懒,求个异步爬虫,必要需求是方便处理异常 - 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
imn1

懒,求个异步爬虫,必要需求是方便处理异常

  •  
  •   imn1 May 11, 2020 3082 views
    This topic created in 2192 days ago, the information mentioned may be changed or developed.
    速度、并发量不是最大需求,当然能做到更好

    必要的是出现爬取失败的 url,能扔进队列重试若干次
    持续失败( 403/404/50x,超时……等等)的能记录下来

    其次是可以自定义 header,包括 cookies 、UA 等等,当然包括可重用(session)

    搜了好几个简述都没这方面说明,估计不是逐个看文档,就是看代码……
    谁知道有这样的,省我一点时间,谢了
    16 replies    2020-05-12 11:58:06 +08:00
    NaVient
        1
    NaVient  
       May 11, 2020
    开源不是伸手,别人没实现的你可以实现了提 PR 方便下一个朋友
    also24
        2
    also24  
       May 11, 2020 via Android
    第一行和第三行需求,直接 aiohttp 不就好了。

    第二行需求,自己用 redis 实现一下估计也就一百行以内?
    dayeye2006199
        3
    dayeye2006199  
       May 11, 2020   3
    这是传说中的伸手党?
    imn1
        4
    imn1  
    OP
       May 11, 2020
    @also24
    redis 我只认识这五个字母,

    @NaVient
    伸手是伸手,但也不完全是拿来就用,肯定要自己改的
    只是年纪大了,又不是用来吃饭的东西,总不能我现在对某个软件不满意就重写一个,能尽量少改动最好

    爬虫十多年前就写过,单线程,但我较强能力在 parse (韩文以前我都爬过百多个站点),aio 或多线程方面很弱
    我以前玩的是 aria2 抓取,然后脚本 parse 出 link,导出 aria2 list,再重复几次到最后完成
    以前这样玩好处是主动操作,满足感强,现在只想扔到后台爬完整理就算了
    ruby0906
        5
    ruby0906  
       May 11, 2020
    要不是轮子太多,看楼主的描述我都想自己写一个。
    imn1
        6
    imn1  
    OP
       May 11, 2020
    @ruby0906 #5
    就是这个意思,如果自认为能力足够,已经动手了,我就从来没用过别人的 html parser 轮子
    问题是自己写出来的,自己用着都觉得糟心,还不如用人家高水平的轮子
    ClericPy
        7
    ClericPy  
       May 11, 2020
    以前还真写过类似的... https://github.com/ClericPy/torequests

    支持协程, 线程, 同步, 异步, 反正就是当年想在同步环境里享受到协程的高性能用的

    和原生 aiohttp 比, 损失 10% 性能, 带上 uvloop 损失 15% ~ 20%... 损失这么多现在我都有点不想用它了...

    https://paste.ubuntu.com/p/fFWsNmvVX2/ 简单的小例子
    tlemar
        8
    tlemar  
       May 11, 2020
    scrapy 可以满足需求
    imn1
        9
    imn1  
    OP
       May 11, 2020
    @ClericPy #7
    哎呀,失敬失敬,刚刚在看 torequests,没想到下一秒作者就出现了

    既然大驾光临,顺便问两个问题:
    1.我写个 class 继承 FailureException,就可以自行处理了吧,error 是 http error code 么?
    超时的 error 是什么,文档好像没写这个
    2.自定义 header 好像只见到 torequests.utils.curlparse(string, encoding='utf-8') ?
    ClericPy
        10
    ClericPy  
       May 11, 2020
    @imn1 #9

    1. FailureException 其实就是在 catch exception 的时候不抛错, 让它 Return 回来方便自省和排查, FailureException.error 实际就是原始抛出的错误

    另一方面 FailureException 主要作用就是存放了 request 的 kwargs, 方便回调的时候用上

    超时根据不同的依赖不一定是什么 error, 需要根据依赖来判断, aiohttp 或者 requests 里面都有很多细分, 超时也是区分了读超时和连接超时的, 所以得自己去他们源码里看看, 比如 requests.exceptions 里的 Timeout ConnectTimeout ReadTimeout, aiohttp 里面更复杂

    因此, 这里面的重试的涵盖范围默认是 aiohttp 和 requests 里面的请求错误的基类, 避免 handle 一些非请求类错误 (早年间因为 handle 了 KeyboardInterrupt 导致我一个十万请求的脚本差点停不下来...

    2. 没看懂自定义 Headers 是什么需求, 有个例子么. 可重用 Session 是默认的, tPool Requests 类都是只用一个 Client Session

    3. 代码一开始是刚上班时候自己边学边折腾的, 实际没什么有价值的地方, 不如自己现写一个 wrapper...
    imn1
        11
    imn1  
    OP
       May 11, 2020
    @ClericPy #10
    自定义 header,例如 UA 用 firefox/chrome...,cookies 增加一些条文,如页面访问点击“同意”,cookies 会多了 agree=1 这样,程序首次访问 cookies 没有这条或者 agree=0,后面用代码添加上去才能访问后面的页面

    我本来是想 requests 写个单函数,然后多进程执行,感觉放后台跑有点重,所以才找找有什么异步协程的,这样静默运行不影响我干其他事,所以能记录下载失败反而是最关键的
    crella
        12
    crella  
       May 11, 2020
    楼主自己的 html parser 的其中比较好的几个可以给个链接吗?想看看是怎么解析 html 的。谢谢
    ClericPy
        13
    ClericPy  
       May 11, 2020
    @imn1 #11 这些自然是带的, torequests 要做的就是兼容 Requests 的参数...

    req = tPool()
    task = req.get('http://httpbin.org', headers={"Cookie": "agree=0;"})
    resp = task.x

    这些都是 Requests 库原生的参数

    记录下载失败, 拿到结果以后如果是错误, FailureException 对象的 bool 都是 false 的, 而且也有 self.ok 来兼容 Requests 的响应, 所以只要判断 self.ok 就能知道请求是否成功了. Requests 的 Response.ok 判断的好像是状态码在 range(200, 300) 之间

    记录下载失败, 写个 Callback 函数做变量塞上应该就够了, lambda r: r.ok or open('file.txt', 'a').write('xxx')
    imn1
        14
    imn1  
    OP
       May 11, 2020
    @crella #12
    没公布,而且有些年头,这次也要重写
    没什么特别,就是正则用得好而已(我不需要 bs4/lxml )
    加两三个函数,可以根据捕获"last page"生成一个组合 list,也就是 itertools.product()之类
    有个函数是处理,分散在几个页面的信息,要各自取出合成一个 record,外面的框架很少见有做这个,但这个只是业务逻辑理顺,跟代码能力无关
    可以导出 aria2/wget 可用的 list,wget 不能指定输出文件名,加个下载后对照改名的脚本
    ……

    总的一句,就是做了一个 py,然后不同站点写个 ini/cfg/yaml 什么的,把一堆正则、referrer 按顺序扔进去,就能跑,仅此而已,没什么特别,比别人强的地方可能就是我熟悉中日韩 unicode 字符,文字处理比人家写的要简洁顺手些
    neoblackcap
        15
    neoblackcap  
       May 11, 2020
    @crella 解析 html ?你去看看 nginx 的不就结了。基本上都是拿 nginx 的代码改一下。要不然你去看 pichttpparser 也可以,不过那个到底有多标准,我不好说了。nginx 解析 html 的代码好像也就一个文件,非常短小精悍
    triangle111
        16
    triangle111  
       May 12, 2020
    有个开源的 Ruia,也是异步爬虫,就是插件没人开发。LZ 说的这些功能刚好都有
    About     Help     Advertise     Blog     API     FAQ     Solana     1440 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 50ms UTC 17:01 PVG 01:01 LAX 10:01 JFK 13:01
    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