关于爬虫的增量更新与性能调优

增量爬取的思路:即保存上一次状态,本次抓取时与上次比对,如果不在上次的状态中,便视为增量,保存下来
增量爬取,一般两类情况:1.一个网站出现了新的页面,2.一个老页面内容变更了。
无论哪一种,增量的前提都是已经存下已经爬取好的信息(至于哪些要存,下面说),当出现新的情况时,重复数据不会抓取,直接抓取新的东西。


第一种,一个网站出现了新页面
1.在分析之前,先看一下scrapy的去重策略:
scrapy通过request_fingerprint函数,对Request对象生成指纹,看注释:

该函数在scrapy/utils/request.py文件中

def request_fingerprint(request, include_headers=None):
if include_headers:
include_headers = tuple(to_bytes(h.lower())
for h in sorted(include_headers))
cache = _fingerprint_cache.setdefault(request, {})
if include_headers not in cache:
fp = hashlib.sha1()
"""计算指纹时,请求方法(如GET、POST)被计算在内"""
fp.update(to_bytes(request.method))

    """下面这句有意思,canonicalize_url()将url规范化,意味着
      http://www.example.com/query?id=111&cat=222
      http://www.example.com/query?cat=222&id=111
    这样参数位置变化,但参数值不变的网址,表示的仍是同一个网址,符合现实逻辑。
     """
    fp.update(to_bytes(canonicalize_url(request.url)))

    """request.body的属性是字符串:
    一般GET方法的body为空字符串,不考虑;
    而POST方法要上传一个字典data(类型是dict),
    要经过urllib.parse.urlencode()函数转换后才能变成request.body
   """
    fp.update(request.body or b'')
    if include_headers:
        for hdr in include_headers:
            if hdr in request.headers:
                fp.update(hdr)
                for v in request.headers.getlist(hdr):
                    fp.update(v)
    cache[include_headers] = fp.hexdigest()
return cache[include_headers]

"""我们甚至可以根据需求将request.meta的内容作为指纹计算的一部分"""

scrapy生成的唯一指纹,存在内存的一个集合里,即set。如果下一次请求产生的指纹在这个set里面,请求被判定为重复,这次请求就被忽略,也就是所谓的去重了。
从上面可以可出,scrapy认为,如果url/POST data/method都一致,这个请求就是重复的,这适合绝大多数情况。
需要提一下:上述的处理方式,意味着想要变更request的指纹就要改变request,即是在downloaderMiddleware的process_request方法中变更。

2.下面就是举例了
一个网站,本来一共有10页,过段时间之后变成了100页。假设,已经爬取了前10页,为了增量爬取,我们现在只想爬取第11-100页。
因此,为了增量爬取,我们需要将前10页请求的指纹保存下来。
以下命令是将内存中的set里指纹保存到本地硬盘的一种方式。
scrapy crawl somespider -s JOBDIR=crawls/somespider-1
但还有更常用的,是将scrapy中的指纹存在一个redis数据库中,这个操作已经有造好轮子了,即scrapy-redis库。
scrapy-redis库将指纹保存在了redis数据库中,是可以持久保存的。(基于此,还可以实现分布式爬虫,那是另外一个用途了)
scrapy-redis库不仅存储了已请求的指纹,还存储了带爬取的请求,这样无论这个爬虫如何重启,每次scrapy从redis中读取要爬取的队列,将爬取后的指纹存在redis中。如果要爬取的页面的指纹在redis中就忽略,不在就爬取。
第二种,一个老页面内容变更了(不适用的情况来了)
1.爬取修改中的博客这种情况。
刚开始爬时,博客写了一段就交了,后来某天,这个博客又续写了,这就是网页url没变,内容变了的情况,一般这种网页不常抓。
根据增量爬取的思路,需要保存老页面的信息,如果再次访问这个页面,内容变化,就更新内容即可。
有个小TIP,比如一个页面是文字,很大,可以将文字哈希,下一次爬取的页面哈希值与上一次相同就说明页面没有更改。
2.ajax页面中,一个页面的内容是不断更新的。
比如豆瓣TOP100 的电影之类的,url/参数/请求方法 可能都一样,但内容是变更的。
ajax请求获得的json文件一般会有一个唯一id,如果没有可以自己造一个,将唯一id记录在redis数据库中,如果这个json返回值已经爬取过,丢弃即可。一般没有办法直接通过fingerprint过滤,总是要加入其它一些人为的考虑在里面。
因为是将东西爬取下来之后才去重,意味着此步骤在pipeline的process_item方法中进行。


此外还有三方插件可以调用:

scrapy-deltafetch scrapy插件,实现request 和item的去重

增量更新与定时爬取提高了爬虫的智能性,

在提高爬虫性能方面有几点需要注意的:

1 dns缓存可以提高爬虫的性能,平均请求dns 服务器的时间大概是在10-60毫秒,当一个域名下有多个页面的时候的,那么耗费的时间综合就非常的大了
2 尽可能用内存高速缓存(例如: redis/memcache )
3 降低存储部分冗余,提高存储效率,比如去除空格之类的,如果是二进制文件可以采用一些算法进行压缩存储

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • 背景 部门(东方IC、图虫)业务驱动,需要搜集大量图片资源,做数据分析,以及正版图片维权。前期主要用node做爬虫...
    字节跳动技术团队阅读 7,663评论 1 67
  • 前言 scrapy是python界出名的一个爬虫框架。Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应...
    以后的以后_hzh阅读 2,267评论 0 14
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化...
    Evtion阅读 5,852评论 12 18
  • 这个项目也是初窥python爬虫的一个项目,也是我的毕业设计,当时选题的时候,发现大多数人选择的都是网站类,实在是...
    梦航韩语阅读 2,998评论 2 37