Python 爬虫并发极限是多少呢? - 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
Cy86
V2EX    Python

Python 爬虫并发极限是多少呢?

  •  1
     
  •   Cy86 2020-03-14 04:24:44 +08:00 4805 次点击
    这是一个创建于 2111 天前的主题,其中的信息可能已经有所发展或是发生改变。

    模块介绍: 爬取网上很多公开的代理 IP 网址, HTTP HTTPS Sock5 , 去重后, 访问自己域名(返回 Json, 小于 300 字节), 用来测试匿名程度后保存

     不使用代理,仅本地网络测试 设备: 联通光纤宽带(我一个人用) 下行 300M 上行 30 CPU: I7 7700HQ 4 核 8 逻辑处理器 内存: 16G 国内的服务器: 阿里云 1 核 2 内 1M 

     单进程 + 异步: URL 500 个 asyncio.Semaphore(500) aiohttp 设置超时时间为 1 秒 结果: 并发 500 的成功率为 97%左右(偶尔抽风) 每秒并发个数: 485 多进程 + 异步: URL 500 个 5 个进程 (每个进程平均 100 个 URL) asyncio.Semaphore(100) aiohttp 设置超时时间为 1 秒 结果:并发 500 的成功率为 99%左右(偶尔抽风) 每秒并发个数: 495 多进程 + 异步: URL 1600 个 8 个进程 (每个进程平均 200 个 URL) asyncio.Semaphore(200) aiohttp 设置超时时间为 1 秒 结果:并发 1600 的成功率为 4% ~ 75%左右(大概率低于 30%) 每秒并发个数: 64 ~ 1200 

    当前遇到的问题: 超过 500 并发后极其不稳定

     目前猜测之所以 500 是临界点, 可能联通限制连接数 1000 导致 或是 Windows 平台 select 限制 

    当前策略每三秒对所有 代理 IP 访问自己服务器进行测试 测试代理 IP 超时时间为 3 秒 通过超时次数,和响应时间(使用) 对每个 IP 分配权重来筛选,排序, 所以要很大程度上减少自身网络或程序的错误, 才尽可能保证代理 IP 的准确性于可用性, 毕竟能用的 IP 太少, 误封就太可惜了

     电脑性能和上行带宽没跑满, 多加几个服务器太浪费了 

    请问各位, 有什么方式能提高并发量, 或容错(误封可用 IP)的策略呢,

    35 条回复    2024-05-20 10:12:32 +08:00
    chizuo
        1
    chizuo  
       2020-03-14 08:28:17 +08:00
    你这个明显少了。我之前写了个爬虫 b 站排行榜的,多进程+异步 async+代理池,放到学校服务器上( 20c+48G),每秒并发可以轻松上千。不过持续不了多久,因为代理池太弱了,就会被封。
    测试本地网页的话,应该能上万。
    ClericPy
        2
    ClericPy  
       2020-03-14 09:16:40 +08:00
    并发极限没测过, 反正协程自己跑就挺快了, requests + 多线程大概比 httpx 协程慢个 10%, gevent 不测

    Test without uvloop, 12 logical CPUs.
    Windows-10-10.0.18362-SP0
    3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)]
    ================================================================================
    test_aiohttp(3.6.2) : 2000 / 2000 = 100.0%, cost 1.158s, 1727 qps, 100.0% standard.
    test_httpx(0.11.1) : 2000 / 2000 = 100.0%, cost 3.927s, 509 qps, 29.47% standard.

    Test with uvloop, 1 logical CPUs.
    Linux-4.15.0-13-generic-x86_64-with-Ubuntu-18.04-bionic
    3.7.3 (default, Apr 3 2019, 19:16:38)
    [GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]
    ================================================================================
    test_aiohttp(3.6.2) : 2000 / 2000 = 100.0%, ost 0.698s, 2866 qps, 100.0% standard.
    test_httpx(0.11.1) : 2000 / 2000 = 100.0%, cost 2.337s, 856 qps, 29.87% standard.

    以前随手测的, 请求本地 golang 只带 net/http 的 server
    lc7029
        3
    lc7029  
       2020-03-14 11:52:52 +08:00
    具体说是看你配置和网络
    家用宽带可能有运营商的限制连接数或者 QOS
    black11black
        4
    black11black  
       2020-03-14 19:37:29 +08:00
    很明显是你用 select 锁 512fd 的问题吧
    lithbitren
        5
    lithbitren  
       2020-03-14 21:40:56 +08:00 via iPhone
    @black11black 大佬,select 锁怎么解啊?我最近试了试一个挺火的 py 新框架 fastAPI,据说 qps 能上万,结果本地拿并发爬虫一打就死了,win10 上开服务并发量不能超 510,一超就爆 select 错直接垮了,stackoverflow 和 github 都没找到解答。。
    ericbize
        6
    ericbize  
       2020-03-14 21:53:05 +08:00 via iPhone
    之前单位安全大佬写的 py 脚本 , 在 kvm 的 ubuntu 上面打了 12w 条连接,直接把单位的网卡死了。 背景,电信专线,固定 ip,100M
    rockjike
        7
    rockjike  
       2020-03-14 22:04:23 +08:00 via Android
    一般网站,爬虫并发多大会挂掉
    opengps
        8
    opengps  
       2020-03-14 22:29:46 +08:00
    @ericbize 你们单位的网络设备支撑的在线连接数可能用满了,所以没有连接可用,表现成网络卡死。我当初 gps 系统上云是因为 5 万多买的硬件思科防火墙只能支撑 25 万 tcp 长连接
    johnsona
        9
    johnsona  
       2020-03-14 23:23:31 +08:00 via iPhone
    你先把反爬虫绕过去再说
    qsnow6
        10
    qsnow6  
       2020-03-14 23:33:32 +08:00
    提供一个数据,python 爬虫框架的扛把子,scrapy,每秒并发可以达到 1800 request /s
    binux
        11
    binux  
       2020-03-15 03:56:57 +08:00 via Android
    @qsnow6 #10 开 HTTPS 开 gzip 就卡死了
    RicardoY
        12
    RicardoY  
       2020-03-15 10:22:03 +08:00
    @qsnow6 这是怎么测出来的,scrapy bench 只能跑到 2400min/s 左右
    qsnow6
        13
    qsnow6  
       2020-03-15 18:56:26 +08:00
    @RicardoY #12 不好意思,敲错了,单位是 min
    lithbitren
        14
    lithbitren  
       2020-03-15 20:21:30 +08:00
    我用 grequests 单线程最快每秒可以发 500-700 个 request,还没算上多进程,一次性可以同时建立数万的个协程请求,尤其找到一些复杂点的 API,没有保护的话必崩,同事里的个人几乎都被干崩过。
    不过最近遇到一次严重的内存泄漏也是因为 grequests 的 gevent 给搞得,开了 20 万个协程,等了几分钟,直接爆了个 memory error,然后可能是 c 扩展里面的内存没有释放,程序炸了,idle 关了,内存占用率都还在 95%以上,开流氓工具清内存都清不掉,最后只能重启。
    Cy86
        15
    Cy86  
    OP
       2020-03-15 21:13:16 +08:00
    @qsnow6 好吧... 我用协成单进程 9410min/s
    Cy86
        16
    Cy86  
    OP
       2020-03-15 21:28:18 +08:00
    @lithbitren 目前用 grequests 能达到 13377min/s 但 timeout 的几率有点大, 很难控制在百分之 98 以下, 我再研究研究
    Cy86
        17
    Cy86  
    OP
       2020-03-15 21:37:48 +08:00
    目前猜测是运营商的限制, 偶尔能突破 500 限制, 但阿里云和国外 VPS 测试依旧并发不满意, 服务器端可能是网络抖动的原因
    目前:
    国外: VPS 测试代理 IP 端口是否开放,过滤一波虚假的
    家里: 单线程 异步 每秒 400 并发来使用, 3 秒能测试 1200 个代理 IP(GET 国内匿名测试服务器), 准确率达到百分之 98+%
    lithbitren
        18
    lithbitren  
       2020-03-15 21:46:54 +08:00
    @Cy86 外网 grequests 我这边最多也就射出秒均 200-300 这样,任何做过保护的网站都会秒封 IP,只要设了 timeout 怎么都会被短暂阻塞,我测的是自己搭的本地服务框架,算上回收处理时间是 500-700,其实应该算成服务器秒内处理请求数。单纯的看发射的话,本地的秒均单进程应该可以达到 900 多,刚刚测了 1000 个请求,服务器日志的的请求间隔是 1.1 秒这样。其实对于小服务器来说,做好保护的话最多是带宽资源占用导致其他人无法正常使用服务,但也不是这么好崩的。
    black11black
        19
    black11black  
       2020-03-16 19:24:14 +08:00
    @lithbitren 建议补习基础知识....想异步爬虫就好好原生异步,不要猴子补丁....select 机能限制就这么高性能啊,我猜测 select 限制是因为 select 默认 512fd,正好符合了你说的超 500 不稳定,有问题上 epoll 啊,我又不知道你代码怎么写的,纯粹瞎猜。py 原生异步切换携程的时间消耗是微秒级的,合理配置后可以到纳秒级,十万并发不好说,网络状况合适的条件下单线程一万肯定能达到,你这么低性能都出问题明显是网络问题或者代码写的有问题。。
    v2eeeeee
        20
    v2eeeeee  
       2020-03-16 19:48:47 +08:00
    并发的时候会考虑 linux 系统设置的 ulimit (max user processes)吗?
    还是说网络流的并发都是一个进程 (单线程理解为一个进程) 维护的?
    lithbitren
        21
    lithbitren  
       2020-03-16 20:49:34 +08:00 via iPhone
    @black11black 没懂,grequests 用的 gevent 应该和之后的官方协程算另一套体系吧。。
    lithbitren
        22
    lithbitren  
       2020-03-16 20:55:53 +08:00 via iPhone
    @black11black grequests 的问题应该是解析数据占用了线程资源导致的效率瓶颈吧
    black11black
        23
    black11black  
       2020-03-17 00:11:22 +08:00
    @lithbitren 我一直不支持用猴子补丁,我不知道 grequests 的具体实现方式。但是你应该知道多线程是多线程,IO 复用是 IO 复用,你用线程的思考方式考虑 IO 复用是风马牛不相及的两码事。windows 下线程切换的默认时间片是十毫秒还是多少记不住了,linux 应该是几十微秒,基于线程模型理所当然是浪费大部分 IO 性能的,无所谓什么解析数据占用线程资源,就像 select 有监控上限,他不是 py 的并发极限,只是单纯你用了错误的方式而已
    lithbitren
        24
    lithbitren  
       2020-03-17 01:17:10 +08:00
    @black11black 不是,不推荐归不推荐,grequests 就是单纯的 gevent+request 的封装,并发爬虫几行写完了就是图个方便,协程是原理,但用 grequests 根本不需要懂协程,而且印象中是 3.5 之前就有了。单独 request 发送回收数据是需要解析时间解析的,从数据返回到数据解析成 request 对象也是需要时间的,是需要占用 GIL 资源的,切协程这个时间在解析数据这里是可以忽略不计的,但最后接收数据的时候阻塞的,如果任意一个请求的响应变慢或超时,整体的统计时间也会大幅增加。
    我这里 win10 开线程的应该是不到 1ms 左右,协程应该也是几十微妙。
    grequests 的核心代码就是一行 grequests.map(request_list),计时函数只能放在这行代码的前后,实质统计到的是所有请求完整生命周期的时间。
    lithbitren
        25
    lithbitren  
       2020-03-17 01:34:29 +08:00
    @black11black 不过我之前说的确实也不对,grequests 的发送时间统计里包括了所有 request 对象的构建,request 发送接受,对返回内容解析几个过程,并不算是实质从第一个对象发出到最后一个对象发出的时间。
    chengxiao
        26
    chengxiao  
       2024-05-14 18:02:48 +08:00
    爬虫的极限是 代理池和账户号,其他都是浮云
    Cy86
        27
    Cy86  
    OP
       2024-05-14 18:12:02 +08:00
    @chengxiao #26 日常监控 30 万个网站的更新, 每 5 分钟跑一次, 不需要账号和风控, 单站点请求一分钟一次都没有
    chengxiao
        28
    chengxiao  
       2024-05-14 18:21:40 +08:00
    @Cy86 #27 舆情?蜜度?
    macaodoll
        29
    macaodoll  
       2024-05-15 08:42:25 +08:00 via Android
    并发够用就行,别一味想着把你服务器性能全部打满,这样就离进去不远了。
    bug123
        30
    bug123  
       2024-05-15 09:00:19 +08:00
    我对付那种并发高的爬虫也简单,不封禁,只是偶尔返回政治敏感数据
    shanyaoxingtong
        31
    shanyaoxingtong  
       2024-05-15 10:54:57 +08:00
    代理池不够用多高的并发也没用啊,全被风控掉了
    seedai
        32
    seedai  
       2024-05-16 15:24:27 +08:00
    @chizuo 老哥,能利用爬虫做流量吗
    Cy86
        33
    Cy86  
    OP
       2024-05-20 10:08:06 +08:00
    @chengxiao #28 每错是舆情
    Cy86
        34
    Cy86  
    OP
       2024-05-20 10:10:44 +08:00
    @shanyaoxingtong #31 后面接了 5 家的代理池, 每天的总请求 13 亿, qps 能达到 15K, 咱们先讨论技术再讨论代理
    Cy86
        35
    Cy86  
    OP
       2024-05-20 10:12:32 +08:00
    @macaodoll #29 感谢建议, 目前只是突然想到了技术上的问题, 在纠结 Python 为啥并发上不去, 卡点在哪
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2951 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:20 PVG 20:20 LAX 04:20 JFK 07:20
    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