scrapy作为python中的一个爬虫框架,功能十分强大,内部实现了twisted的异步调用,在一定程度上提升了运行效率,并且由于scrapy爬虫有着相对固定的结构,内部封装了众多功能,因此只要逻辑清晰,初步掌握scrapy还是比较容易的。作为一个小白,刚刚接触scrapy,计划用scrapy爬取知乎上感兴趣的话题以及其热门问答,现记录一下自己在学习中的一些感悟,如果有不对的地方欢迎指正。
1. 爬取知乎第一步是模拟登录,关于模拟登陆知乎的技术文章有很多,大体思路都是先获取_xsrf以及验证码,然后以post的方式提交登录信息。在此不进行详细阐述,具体步骤可以参考这两篇文章:http://www.jianshu.com/p/3debfb110ad9,http://blog.csdn.net/hudeyu777/article/details/76706007,对于模拟登录时的的一些细节讲解的很清楚;在scrapy中模拟登录时也可以采用这种方式,scrapy中有一个FormRequest.from_response函数,可用于提交表单信息,模拟用户登录,在登陆之后,必须传递cookies,以保持登录状态,此时必须在setting中设置cookies中间件,并开启cookies功能,然后使用cookiejar对cookie进行传递。如下:
for i, url in enumerate(urls): yield scrapy.Request("http://www.example.com", meta={‘cookiejar‘: i}, callback=self.parse_page)在后续访问中传递cookie:
def parse_page(self, response): # do some processing return scrapy.Request("http://www.example.com/otherpage", meta={‘cookiejar‘: response.meta[‘cookiejar‘]}, callback=self.parse_other_page) 除此之外,还有一个野路子,可以先在其他程序中模拟登陆之后,将cookies以文件的形式保存下来,然后在scrapy中导入cookie文件,直接在scrapy.Request方法中添加cookies字段即可,cookies只添加一次即可,scrapy会自动传递,前提是在设置中开启了cookie及其中间件。需要注意的是cookie应该为字典形式。 2.在爬取时有时会遇到网页爬取失败的现象,但是有次我多次爬取某个网页,返回的均是同样的结果,排除登录状态和IP被封禁等因素后,我想起来我在setting中,设置了HTTPCACHE_ENABLED=True,也就是说当爬取相同网页时会直接加载之前的缓存,以加速爬取,这样就会导致之前的失败信息再次返回。 3.在具体的spider编写时,有时需要在两个函数间传递参数,例如item信息等,当我在meta中直接传递item时,发现最后输出的item信息错乱。仔细思索后意识到由于scrapy采用了异步调用的机制,也就是说当发出一个请求之后,并不会一直等待response的返回,而是马上发出其他请求,当收到之前请求的response之后,再将其传递给回调函数。这就会导致当response返回给回调函数时,其item信息已经被其他request修改(item相当于全局变量),因此传到回调函数的item中很可能含有不属于该request的信息。最保险的方法是在meta中传递item的具体值,避免直接传递item,并且item的赋值应在同一个函数内完成。
时间: 2024-09-29 08:19:12