学习爬虫框架scrapy时的一些收获

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习爬虫框架scrapy时的一些收获相关的知识,希望对你有一定的参考价值。

        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的赋值应在同一个函数内完成。

以上是关于学习爬虫框架scrapy时的一些收获的主要内容,如果未能解决你的问题,请参考以下文章

scrapy按顺序启动多个爬虫代码片段(python3)

scrapy主动退出爬虫的代码片段(python3)

Scrapy走进成熟的爬虫框架

Python爬虫框架Scrapy学习笔记

scrapy爬虫框架

爬虫系列---Scrapy框架学习