目录
解决pyspider页面改变问题
pyspider对懒人很友好,这里要感谢一下作者[binux]尤其像我这种外行,使用起来很方便,但由于不了解程序的背后逻辑,很多时候会被“坑”,下面记录了使用过程中遇到的页面问题:
1.当同一个页面的数据发生改变时
例如,同一个页面的数据随时发生变动,而我们又想要变动数据的时候。可以参考usdebt网站,数据即时变动,如果我们想要每天采集一次,这时按照pyspider的逻辑,对于taskid不变的页面,默认不抓取。
此时,我们需要在抓取页面修改taskid的生成逻辑:
def get_taskid(self, task):
time_instanttime = time.localtime()
return md5string(task['url']+str(time_instanttime))
如上代码所示,我们将原来的taskid(基于url的md5值),修改为url+抓取时间
的md5值,这样在每次系统启动时,系统会默认为页面不一样,从而增加数据,taskid即为新的数值,从而实现同一个页面的周期抓取,能够得到数据的变化趋势。
2.当同一个页面里的链接发生改变时
默认情况下,pyspider只对同一个页面抓取一次,即从on_start()
函数开始,所有的页面默认只抓取一次,即便我们设置了@every()
装饰器,也只是重新启动,如果没有设置页面的过期时间,就会直接停止。
此时我们不能使用上面的方法,毕竟对于同一个页面里的链接有两种情况:①发生变化的链接;②没有发生变化的链接。最典型的例子就是排行榜,例如豆瓣的电影排行榜——定期的增减排行榜的电影,也存在有些电影长期霸榜的情况,此时我们想要抓取所有电影,并且补充发生改变的部门,就需要两个步骤:
1. 设置抓取周期,通过@every(minutes=60*24)
装饰器实现。
2. 设置页面过期时间(该页面中有链接发生改变),通过@config(age=24*60*60)
装饰器设置,单位是s。
3.默认情况
默认情况下,pyspider任务对每个页面中的链接和内容都是不变的,即从on_start()
函数开始,抓到的页面不会过期,再次抓到的页面以及链接都默认为不会过期,这样在页面中增加链接时也不会重新抓取(即不会重新比对是否已经抓取过),所以我们在编写爬虫脚本时需要明确爬取的网页是否需要重新监测(即设定过期时间,以便在重新抓取和节省资源之间抉择)
总结
1.对于一次性任务,即不需要周期抓取的任务,例如档案类资料。可以不需要设置@every()
或者age()
,即按照规则只抓取一次,且不会周期抓取。
2.对于周期性任务,分为两种情况:
– 对于同一个页面的数据不存在更新的情况:增加@every()
和age()。
age()`不兼容,存在重复爬取同一个页面多次,及时页面的数据没有任何改变,建议在使用taskid时只抓取动态页面本身的数据。
- 对于同一个页面的数据存在更新的情况:对于更新页面单独使用taskid函数,增加时间变量,这样可以保证每次爬取的时候md5都不一样。需要注意的是,重写taskid函数时如果增加了时间,会与