程序猿日记孔Sir收藏程序设计

使用Scrapy爬取大规模数据

2016-05-23  本文已影响7363人  向右奔跑

系统学习了解Python爬虫有20天时间了,做了一些爬虫小实验,如:

但是以上爬取的数据量都不大,最多的有一千多数条数据。于是想做一次大数据量的爬取。选择的数据源是简书用户,使用的是Scrapy框架。同时也想对简书的用户做一个数据分析。

要爬取大量数据,使用Scrapy要考虑的是新的url在哪里产生,解析的方法如何循环调用,也就是爬取的深度和广度。在Scrapy官方文档上的案例过于简单,实现的过程遇到不少问题,如scrapy中的方法如何调度,如何返回,循环中如何去抓取需要的另一个字段,再如何返回等等, 有些可能是我思维的局限,问题先记下,一步步解决。

一、考虑爬虫从哪里入口?

简书的用户id不是一个自增的序列数,无法使用一个循环就可以跑下所有用户。一开始我是想从一篇热门文章的阅读数或者喜欢数开始抓取用户,热门文章的阅读数能达到6W+,喜欢数在6~7K。但下一步数据再怎么爬,没有想好,阅读和喜欢的用户都是最普通用户,他们的关注和粉丝很少,而且阅读用户是Ajax数据。还有一个问题,数据如何去重。

后来,我再看上次爬取的简书签约作者时,发现有8个签约作者粉丝都超过1W,彭小六粉丝近3W。于是就觉得从这里作为入口,会是一个比较好的方案,简单易行,使用几个不多的url作为待爬取的入口,便可以抓取到大量的数据。最后我选择几个入口用户是,简书、彭小六、剽悍一只猫、入江之鲸、陶瓷兔子5个用户url,爬取他们的粉丝用户信息。

没有把所有签约作者url一起列为入口,是因为我现在数据存为csv格式,考虑可能超过65535行。后来我看了一下,特征用户还可以包括简叔,简书首席拒稿官。

要爬取的用户信息:

class JsuserItem(Item):
   
    nickname = Field()  #用户昵称
    subscriptions = Field() # 用户关注数
    fans = Field() #粉丝数
    url = Field()  #用户首页url
    articles = Field()  #写的文章数
    words = Field() #写作的字数
    likes = Field()   #收到的喜欢数
    comments = Field()  # 发表的评论数,这个数据跳到另外url,还要做分页处理,这次没有做。
    regtime = Field()  # 与评论数一样,下次再爬取
    collected = Field()  #文集数量

二、如何使用Scrapy循环爬取数据

在上一篇文章爬虫框架Scrapy快速入门中数据提交,获取新的url,url规则没有变,抓取的页面结构没有变,所以都是在parse()中实现。这次不一样。

1、列出start_urls, parse()方法会自动从这个待爬取的url列表依次执行。
2、每一个用户的粉丝是分页加载的。所以需要一个方法获取粉丝分页url,分页页面每一行数据显示了一个用户文章数、字数、喜欢数、粉丝数,不需要进入到用户首页。

要获得用户注册时间,第一篇文章发表时间,发表过多少评论,是需要进到用户首页的,这也是下一步抓取要解决的。

用户信息

在parse()方法中,我的目标就是拿到所有分页url,parse_item()中解析出用户信息并提交。在parse()方法中循环调用parse_item()。把所有特征用户的粉丝数据都抓取出来。

注意:
1)在构造分页url时,查看到一个参数“_=”后面是一串数字,在浏览器中验证去掉又不行,猜测是时间戳。就用time构造出一个,测试正确。

分页url

2)在scrapy中方法调用,采用回调的方式。

       for i in range(1, pages + 1):
            nurl = response.url + '?_' + str(t) + '&page=' + str(i)  #构造出分页的url
            yield Request(nurl, callback=self.parse_item) 

看一下爬取到的数据:

到了65535行!

把数据导入数说立方,去重后的条数为64714条,重复率为1.2%,可见用户在粉以上几个签约作者时重合度并不高。

数据统计 90.8%用户写了7篇文章,68.9%用户没有发表过文章

你坚持写7篇就超过90%的用户。更多数据分析,另外写一篇来解读。下一步的学习放在mongodb,redis上,练习10W+级别的数据爬取,以及Scrapy处理复杂的流程和性能优化。

上一篇下一篇

猜你喜欢

热点阅读