爬虫抽取连接和抽取内容的部分是不是应该分开? - V2EX
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
yakczh
V2EX    Python

爬虫抽取连接和抽取内容的部分是不是应该分开?

  •  
  •   yakczh 2014-02-26 11:50:02 +08:00 5202 次点击
    这是一个创建于 4274 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一般抽取链接的逻辑都比较简单,有些定向爬取的的可以象 chilcat用正则匹配AddAvoidOutboundLinkPattern("xxx") 那样设置成参数 ,但是内容抽取跟实际需求相关,而且网站改版以后这部分怎么需要重写,而且一个种子站点,可能抽取的数据是多个部分,相当于一个链接抽取的处理器,和一个内容抽取的处理器,内容处理器可能是1-n个,这样设计的话比较清晰,但是一个抓取一html内容,相对于一个函数里同时获取链接和内容,这样每次分开处理应该会对性能有一定影响
    11 条回复    1970-01-01 08:00:00 +08:00
    lecher
        1
    lecher  
       2014-02-26 12:20:05 +08:00
    取决于规模,当你的规模上去之后,分开是必然的,为了保证不受网络请求延时的影响,消息通信的时候可能还要上请求队列。
    规模不大,请求不高的时候,怎么方便怎么来。只要模块接口条理清晰python重构还挺快的。
    diaoleona
        2
    diaoleona  
       2014-02-26 12:22:16 +08:00
    看你怎么设计了,我之前是爬到的response.url和 web content压缩一下放在一个数据库里,然后根据需求再做不同的抽取
    pubby
        3
    pubby  
       2014-02-26 21:18:44 +08:00
    我们用的比较多的架构是这样的:
    Job Server: gearman
    fetch_worker: 用node.js写的一个抓取脚本,连上gearman获取并处理抓取任务,支持socks5代理,worker数量动态自动调整,可分布到多台机器
    队列服务: RabbitMQ
    KV存储: 我们用redis-storage,一个redis接口+leveldb存储后端的东西,本身支持snappy压缩


    处理流程是这样的:
    1. 一个抓取调度进程
    1.1 从rabbitmq读取抓取url
    1.2 预处理后交给gearman,预处理包括抓取频率的控制,代理服务器的决策等
    1.3 抓取结果存储,写入redis-storage服务器
    1.4 写入rabbitmq队列通知分析进程处理
    1.5 对于需要跳转或者需要重试的抓取,把url再次插入rabbitmq抓取队列即可。
    1.6 遇到404等错误,直接丢弃结果

    2. 一个数据分析进程
    1.1 从rabbitmq队列获抓取成功的消息
    1.2 从redis-storage服务器提取页面数据
    1.3 如果是过渡页,分析下一步的url插入抓取队列
    1.4 如果是目标页,分析信息,保存结果


    我们主要用php
    pubby
        4
    pubby  
       2014-02-26 21:45:09 +08:00
    看具体需求而定的。
    抓取规模,抓取周期,处理流程


    如果是一次性的,怎么简单怎么来,想这么多.....
    yakczh
        5
    yakczh  
    OP
       2014-02-26 21:45:51 +08:00
    你说的这种是链接专门在一个页面,数据在另一个页面, 假如一个页面同时有数据和链接呢?

    另外数据页面可能有多个区域
    yakczh
        6
    yakczh  
    OP
       2014-02-26 21:58:14 +08:00
    @pubby 简单的都很好说,就不说了
    我在看scrapy, 貌似一个种子站点,一个详情页面一个数据块这种的很好处理,但是比较种子站点多个页面,多个页面都可能有数据,每个页面有多个数据区域的话,还不知道怎么写,http://stackoverflow.com/questions/21323123/scrapy-storing-items-across-multiple-formrequest-pages-meta-python 其他人也有类似的问题

    我觉得合理的配置是按urlpatten来配置, 一个patten对应一个页面,和一个parse函数,如果数据在详情页,就写一个parse函数,如果多个页面,分别写多个parser,每个parse中处理的xpath都不同
    另外多个parse函数中的items可以平行地收集,(相当于parse是支流,items汇总) 也可以在items里加个一个urlpatten的key,这样各收集各的,两种都支持更灵活一些
    pubby
        7
    pubby  
       2014-02-26 23:47:55 +08:00
    @yakczh

    这个..... 上面只是一个基本框架

    实际上确实碰到你说的情况,所以数据分析也分步骤的,并且队列也有多个分别对应每个步骤
    或者在单个队列里面对的数据进行标记,表示它是那个站,哪个步骤的待处理信息

    比如第一步,得到某个列表页,得到的url进入第二步的待抓取队列
    第二步分析目标页,如果内容全了就ok,不全就增加步骤

    所有步骤走完了才得到完整信息,中间某个步骤失败了,数据就是不完整的。


    但是不管多少步骤,抽象出来每一步就是简单的 抓取->分析

    “抓取”比较简单,就是准备任务扔给gearman,除非某些抓取需要带上特殊条件而需要一个特别点的实现
    “分析”就是要针对不同站,实现每一个步骤的分析过程了

    增加新的抓取目标站,就是做3件事情:
    1. 定义新的站点,和步骤标记
    2. 实现新的“抓取”,如果没有特殊性,可以用通用的
    3. 实现新的“分析”

    至于parser的实现,那就五花八门了,正则、DOM、json、甚至node.js解jsonp回掉数据,取决于目标站变态程度

    目前我们实际用的就是这么个架构和流程,
    rabbitmq中差不多有7G的消息队列,没办法抓取速度永远赶不上分析速度。
    有时候内存吃紧,只能“忍痛”从队列中砍掉一大片

    另外一点就是:如果存在多个步骤,那么后面步骤的抓取url要放入优先级高的队列,优先处理,要不然排到猴年马月也轮不上它
    yakczh
        8
    yakczh  
    OP
       2014-02-27 09:14:47 +08:00
    @pubby 这种是通用的,我不知道7g的url里面,是不是每一条都有用

    定向抓取只抓取需要的链接,根据正则来匹配url连接,一个patten对应一个parser,
    貌似scrapy的rule就是这样思路

    rules = [Rule(SgmlLinkExtractor(allow=['/xxx/\d+']),'parse_xxx'),
    Rule(SgmlLinkExtractor(allow=['/tor/\d+']), 'parse_torrent')]

    如果再进一步配置化,可以把parse函数写成数据库字段,启动时读出来动态执行, 这样只需要把parse函数当成一个功能单元测试好,更新到数据库就完了
    diaoleona
        9
    diaoleona  
       2014-02-27 15:22:48 +08:00
    @yakczh
    '多个页面都可能有数据,每个页面有多个数据区域的话,还不知道怎么写'
    没看明白你具体问题是什么?
    如果担心多个页面多个数据 区域有相同的的数据的话,把你需要的数据区域都爬下来hash一下或者放在一个专门判重redis也可以在scrapy 里的中间件加一道判重过程.
    最好你发个子页面的例子给看一下
    yakczh
        10
    yakczh  
    OP
       2014-02-27 16:09:41 +08:00
    @diaoleona 比如京东的详情页 http://item.jd.com/1020784.html
    有商品信息, 有象册,有评论 这种的是写到一个parse函数里吗,评论还可能有翻页
    diaoleona
        11
    diaoleona  
       2014-02-27 16:32:02 +08:00
    @yakczh
    类似这种页的话一个parser专门把ur,商品信息等可以xpath的信息保存下来,
    另外一个parser来抽取相关评论,翻页什么的不是问题,储存时候 评论 和这个商品的ID联系起来.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2588 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 07:36 PVG 15:36 LAX 23:36 JFK 02:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86