V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
phantomer
V2EX  ›  Python

使用 scrapy 爬虫框架,一般是边爬边去重还是爬完一定深度以后再去重?

  •  
  •   phantomer · 2016-06-07 18:23:45 +08:00 · 14951 次点击
    这是一个创建于 3121 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 scrapy 爬虫框架,一般是边爬边去重还是爬完一定深度以后再去重?

    目前刚学爬虫,已经实现爬虫入库,但是遇到一个瓶颈,因为是递归爬虫,所以会一直循环你爬取已经爬过的页面,毕竟很多首页都会有一个首页自己 self 的链接,所以,爬虫一直去请求他。

    所以现在我想了解下,目前大家写的爬虫都是边去重边爬取的?还是入库以后再操作数据库去重?

    如果是数据库去重的话,我感觉会导致数据库里一大堆无用的信息,太损耗效率了。

    如果是边爬取边去重的话,我是从数据库里 select url 来匹配判断是否重复后再入库,还是另外建个列表,每次从内存里取(内存有限的情况下),哪个效率高?

    或者说有更好的实现方法和理论?或者说 scrapy 本身有示例去重的接口或者函数?

    感谢~感谢~

    12 条回复    2016-09-30 09:13:38 +08:00
    JhZ7z587cYROBgVQ
        1
    JhZ7z587cYROBgVQ  
       2016-06-07 18:58:45 +08:00
    我的话之前使用 bloom filter 边爬边去重的,就是会有一定错误率。
    zanpen2000
        2
    zanpen2000  
       2016-06-07 18:59:49 +08:00
    中间件去重,也就是边爬边去
    billion
        3
    billion  
       2016-06-07 19:39:27 +08:00
    使用 Redis 储存网址,自带去重功能。
    zts1993
        4
    zts1993  
       2016-06-07 19:44:18 +08:00
    Redis set 去重
    silverfox
        5
    silverfox  
       2016-06-07 20:36:48 +08:00
    Allianzcortex
        6
    Allianzcortex  
       2016-06-08 08:34:08 +08:00
    所以这就是自己为什么在写完 [scrapy-demos]( https://github.com/Allianzcortex/scrapy-demos) 后就决定再也不用 scrapy 的原因⊙﹏⊙b ……爬虫框架用起来自定义程度总是不高~

    用 requests+Selenium+PhantomJs 多线程爬虫的时候用的是 mp.manager.dict() 来存储已经访问过的网站,如果发现再次访问就直接跳过

    我能想到的就是 Bloom Filter ,按照上面所说用 redis 来去重应该也可以
    phantomer
        7
    phantomer  
    OP
       2016-06-08 13:34:15 +08:00
    brucedone
        8
    brucedone  
       2016-06-08 14:01:31 +08:00   ❤️ 1
    @Allianzcortex scrapy 的自由度还不高?基于插件形式你可以自由定制 proxy ,以及动态 js 解析(scrapy-splash),pipeline 可以自己定义输出形式,你觉得去重是一个难题,那自己定义 queue 的存储然后在重载 start_reqeust 方法就可以轻松的去重了,这些内容都可以自己做,其实已经耦合性不算太高了~
    Allianzcortex
        9
    Allianzcortex  
       2016-06-08 17:28:57 +08:00   ❤️ 1
    @brucedone 可能是我做的还没有到 GB 级这种数据,更喜欢自己写一些内部的东西吧。不过 scrapy 自定义 proxy 这种方式真是特别喜欢,因为我是 Django 党 O(∩_∩)O 哈哈哈~
    BruceWang
        10
    BruceWang  
       2016-09-29 15:56:42 +08:00
    @billion
    @zts1993

    难道你们都不考虑网页内容更新的情况吗?比如爬 V2EX ,爬完就算完成了,再也不考虑新回复?
    billion
        11
    billion  
       2016-09-29 20:35:57 +08:00 via iPad
    @BruceWang 有一些网页会采用增量爬取。
    BruceWang
        12
    BruceWang  
       2016-09-30 09:13:38 +08:00
    @billion 我想,应该是“去重”这两个字定义不清的问题。
    我觉得有这么几个地方需要去重:
    1 、在单一页面解析的时候,可能会提取到重复的链接,需要 url 去重;
    2 、在不同任务、不同页面解析的时候,可能会提取到重复的链接,需要 url 去重;
    3 、在数据提取的时候,可能会遇到重复数据,比如一份重要性比较高的数据被多个不同的站点以各种形式引用(类似论文的引用,不过被引用的论文重复发表在多个期刊),需要 data 去重。
    4 、其它还没想到的

    我在做一个基于 Scrapy 的动态生成的爬虫,也就是提取规则等参数是从数据库取得的(我知道应该已经有了,不过我想自己造个轮子)。所以我对前文( 2 )的情况不是光用集合判断存在还是不存在,我还记录了上次访问时间和任务要求。如果按任务要求比如每周爬一次,判断时间满足那么就再爬一次,否则丢弃。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1033 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:12 · PVG 04:12 · LAX 12:12 · JFK 15:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.