python requests 爬虫和 scrapy 在不同的爬虫应用中,各自有什么优势

Scrapy爬虫轻松抓取网站数据(以bbs为例,提供源码)_数据挖掘入门与实战_传送门
你是真实用户吗(Are you a robot)?
我们怀疑你不是真实用户,已对你的访问做了限制。如果您是真实用户,非常抱歉我们的误判对您造成的影响,您可以通过QQ()或电子邮件()反馈给我们,并在邮件和QQ请求信息里注明您的IP地址:220.177.198.53,我们会尽快恢复您的正常访问权限。另外,如果您不是在访问的当前页面,我们建议您移步
或者 在浏览器中输入以下地址:http://chuansong.me/n/2309495 访问,您所访问的网站是从抓取的数据,请直接访问,会有更好的体验和更及时的更新。We suspect you are a robot.We are really sorry if you are not,and you can email us () with your current IP address: 220.177.198.53 to get full access to .If you are not accessing
for the current page,you'd better visit
for better performance,as the current website you are accessing is just spam.
觉得不错,分享给更多人看到
数据挖掘入门与实战 微信二维码
分享这篇文章
数据挖掘入门与实战 最新头条文章
数据挖掘入门与实战 热门头条文章酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
zhihu_spider
此项目的功能是爬取知乎用户信息以及人际拓扑关系,爬虫框架使用scrapy,数据存储使用mongo,下载这些数据感觉也没什么用,就当为大家学习scrapy提供一个例子吧。代码地址:,欢迎各位大神指出问题,另外知乎也欢迎大家关注哈 ^_^.
请求获取页面中的_xsrf数据,知乎开启了跨站请求伪造功能,所有的POST请求都必须带上此参数。
提交用户名,密码已经第一步解析的_xsrf参数到,登陆获取cookies
访问用户主页,以我的主页为例, 如下图:
解析的用户信息包括昵称,头像链接,个人基本信息还有关注人的数量和粉丝的数量。这个页面还能获取关注人页面和粉丝页面。
由上一步获取的分页列表页面和关注人页面获取用户人际关系,这两个页面类似,唯一麻烦的是得到的静态页面最多只有二十个,获取全部的人员必须通过POST请求,解析到的个人主页再由上一步来解析。
scrapy文档非常详细,在此我就不详细讲解,你所能碰到的任何疑问都可以在文档中找到解答。
爬虫框架从start_requests开始执行,此部分会提交知乎主页的访问请求给引擎,并设置回调函数为post_login.
post_login解析主页获取_xsrf保存为成员变量中,并提交登陆的POST请求,设置回调函数为after_login.
after_login拿到登陆后的cookie,提交一个start_url的GET请求给爬虫引擎,设置回调函数parse_people.
parse_people解析个人主页,一次提交关注人和粉丝列表页面到爬虫引擎,回调函数是parse_follow, 并把解析好的个人数据提交爬虫引擎写入mongo。
parse_follow会解析用户列表,同时把动态的人员列表POST请求发送只引擎,回调函数是parse_post_follow,把解析好的用户主页链接请求也发送到引擎,人员关系写入mongo。
parse_post_follow单纯解析用户列表,提交用户主页请求至引擎。
& 相关主题:Scrapy爬虫的Ajax内容应对方法
在这里我不想讲用太多时间讲如何挖出ajax内容的真实请求地址,这个通过httpfox和fiddler甚至更狠一点上wireshark都是可以搞定的。这里我假定你已经知道了ajax内容对应的查询地址,并且知道如何处理这部分内容,我只讲如何在scrapy使用这些查询地址,并处理数据。
对于一个有ajax内容的页面,如果ajax内容也是我们爬虫要关系的内容,那么毫无疑问的,scrapy爬虫至少需要发起两次http请求,第一次是静态页面本身,第二次是ajax内容,ajax内容的请求源地址一般是要从第一次请求中挖掘出的。
就像Javbus一样,所有内容都是可以直接从静态页面获取的,除了AV的磁力链接。在每个AV页面的源码中,都隐藏了一个gid变量,javascript通过这个变量构建一个查询地址,从服务器查询磁力链接内容,然后更新网页的对应部分。已为例子,查看源码可以找到如下部分:
var gid = ;
var uc = 0;
var img = 'http://pics.dmm.co.jp/digital/video/118sgasga00036pl.jpg';
&script& var gid = ; var uc = 0; var img = 'http://pics.dmm.co.jp/digital/video/118sgasga00036pl.jpg';&/script&
而抓包后可以得到的ajax查询地址如下:
"/ajax/uncledatoolsbyajax.php?gid=&uc=0"
"/ajax/uncledatoolsbyajax.php?gid=&uc=0"
刚开始的时候,我是直接用requests构建一个http请求,然后用正则表达式提取里面的磁力内容。这样会有一个问题,就是requests请求本身的成功与否是没有保障的,我的处理办法是在pipeline中检查磁链获取是否成功,如果成功就保存item并drop掉;如果失败的话,就在下一级pipeline中重新抓取一次磁链。
这对于小批量的抓取来说可能还好,但是当你一次要抓几万个页面的磁链时,失败的个数可能就是几百几千个,即使经过二级pipeline的再次检查,还是可能会有failed,为此我专门改写了一个fix爬虫,来修复那些顽固的失败项,而且,这个fix爬虫依然是有失败的概率的。。。。
你看到了,产生这个麻烦问题的关键就是我用了第三方的request库来抓取内容,scrapy是不会监管这些第三方库的网络动作的,无论是内容重复还是网络失败都不会干涉。如果把ajax的查询也交给scrapy,就没这个问题了。
我们这里需要清楚的理解,scrapy本身的requests并不是一个立刻返回的函数,它只是产生一个请求,这个请求里你可以设定一个callback;然后这些requests交给scrapy统一调度,在scrapy downloader处理完这个请求后执行你设定好的callback,其实你如果已经在用scrapy按层级开始抓取网站的话,应该很好理解这个。一般来说,我们会这么处理这个requests:
headers = {'Referer': '', }
url = "/ajax/uncledatoolsbyajax.php?gid=" + item['av_gid'] + "&uc=0"
request = scrapy.Request(url=url, headers=headers, callback=self.parse_magnet)
yield request,item
&&&&&&&&headers = {'Referer': '', }&&&&&&&&url = "/ajax/uncledatoolsbyajax.php?gid=" + item['av_gid'] + "&uc=0"&&&&&&&&request = scrapy.Request(url=url, headers=headers, callback=self.parse_magnet)&&&&&&&&yield request,item
我们这里定义了一个parse_magnet函数作为callback,来专门处理ajax请求返回的内容,然后yield这个request,和之前从顶层往下一级级抓页面好像一样是不是?但是你一定已经想到了一个问题:你在这里把已经获取的内容item yield给pipeline了,难道我要把ajax内容的返回结果和页面解析的返回结果分成两个item吗?
当然不是,所以这里其实不能直接yield item,而是要把item传递给parse_magnet这个回调函数,等磁链信息抓取完之后,把完整的内容item yield给pipeline。这里scrapy给我们的request提供了一个meta成员,这个成员本质就是一个字典容器,你在requests中传入的内容,可以在callback函数的response中访问到。
所以我们最后的request yield代码是这样的:
headers = {'Referer': '', }
url = "/ajax/uncledatoolsbyajax.php?gid=" + item['av_gid'] + "&uc=0"
request = scrapy.Request(url=url, headers=headers, callback=self.parse_magnet)
request.meta['item'] = item
yield request
&&&&&&&&headers = {'Referer': '', }&&&&&&&&url = "/ajax/uncledatoolsbyajax.php?gid=" + item['av_gid'] + "&uc=0"&&&&&&&&request = scrapy.Request(url=url, headers=headers, callback=self.parse_magnet)&&&&&&&&request.meta['item'] = item&&&&&&&&yield request
在parse_page这个callback中,我们可以很轻松的获取传入的item:
def parse_magnet(self, response):
item = response.meta['item']
#Do Something with the response content here,and update item
yield item
&&&&def parse_magnet(self, response):&&&&&&&&item = response.meta['item']&&&&&&&&#Do Something with the response content here,and update item&&&&&&&&yield item
然后我们对这次response的内容进行解析,提取出磁链信息后更新到item中,然后yield item传递给pipeline。
Share story}

我要回帖

更多关于 python爬虫框架scrapy 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信