请教一个问题,怎么提高 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
BBrother
V2EX    Python

请教一个问题,怎么提高 python 爬虫的爬取效率?

  •  
  •   BBrother 2016-08-25 09:45:33 +08:00 8088 次点击
    这是一个创建于 3336 天前的主题,其中的信息可能已经有所发展或是发生改变。

    写了个简单的协程爬虫爬取 B 站用户信息,代码如下:

    import requests import re import json import datetime import asyncio def get_info(uid): url_info = "http://space.bilibili.com/ajax/member/GetInfo?mid=" #基本信息 uid = str(uid) return loop.run_in_executor(None, requests.get, url_info+uid) async def user_info(num): for uid in range(num, num+10): info = await get_info(uid) info = json.loads(info.text)["data"] try: # print(datetime.datetime.fromtimestamp(info['regtime'])) print("ok", uid) print(info) except UnicodeEncodeError as e: print("UnicodeEncodeError:", e) except TypeError: print(info) loop = asyncio.get_event_loop() try: loop.run_until_complete(asyncio.wait([user_info(x) for x in range(1, 1000, 10)])) except Exception as e: print("Error:", e) 

    爬取 1000 条需要 50 秒左右,而且带宽占用也只有 220Kbps 左右的样子,有没有什么办法提高爬取的速度? B 站用户有 3800 万左右。

    谢谢指教。

    ps:1. 没机器做分布式 2. 我知道多进程,但我想问问协程能不能更有效率一点。

    30 条回复    2016-08-29 22:35:16 +08:00
    lbp0200
        1
    lbp0200  
       2016-08-25 09:59:49 +08:00
    多个爬虫+队列( redis )
    chy373180
        2
    chy373180  
       2016-08-25 10:05:30 +08:00 via iPhone
    协程与多进程并不冲突
    fatpa
        3
    fatpa  
       2016-08-25 10:19:20 +08:00
    消息队列啊少年
    abxialiang
        4
    abxialiang  
       2016-08-25 10:21:20 +08:00
    使用大量的代理 ip
    yangtukun1412
        5
    yangtukun1412  
       2016-08-25 10:21:55 +08:00
    使用 requests.Session 复用连接应该能稍微快一点.
    kinghui
        6
    kinghui  
       2016-08-25 10:29:07 +08:00
    使用异步非阻塞 I/O, 如 Tornado, Twisted 等框架
    BBrother
        7
    BBrother  
    OP
       2016-08-25 10:35:36 +08:00
    @chy373180 我知道不冲突,但是我想知道协程能不能再快点,很直觉得觉得协程的效率没发挥出来。
    BBrother
        8
    BBrother  
    OP
       2016-08-25 10:37:31 +08:00
    @fatpa 感觉没必要啊, B 站的 uid 是从 1 开始往上加的,直接切片就行了吧?
    BBrother
        9
    BBrother  
    OP
       2016-08-25 10:41:36 +08:00
    @kinghui 我觉得现在的代码已经异步非阻塞了啊?
    razrlele
        10
    razrlele  
       2016-08-25 10:41:58 +08:00 via iPhone
    看一下返回的 response status ,带宽没起来有可能是很多 request 直接被返回 403 了
    BBrother
        11
    BBrother  
    OP
       2016-08-25 10:42:31 +08:00
    @abxialiang 呃,这个,有什么意义吗?
    spider82
        12
    spider82  
       2016-08-25 10:42:41 +08:00
    可以看看 stackless ,我觉得瓶颈应该不在协程那里,单设备不用代理爬早晚被 BAN 。
    knightdf
        13
    knightdf  
       2016-08-25 10:49:33 +08:00
    我每次开 30 台机器爬,想要效率,只有一个途径,花钱
    BBrother
        14
    BBrother  
    OP
       2016-08-25 10:52:28 +08:00
    @knightdf 残酷的现实
    Mark3K
        15
    Mark3K  
       2016-08-25 10:57:54 +08:00
    代码使用了 coroutine ,但仍然是单线程在跑,没有利用到多核的优势,如果不考虑对方的反爬而只考虑效率的提高的话 可以再加上多进程试试
    erevus
        16
    erevus  
       2016-08-25 11:08:38 +08:00
    多进程+协程 能用到多核
    BBrother
        17
    BBrother  
    OP
       2016-08-25 12:34:42 +08:00
    哇啊,大家真热情,谢谢大家!拜谢!
    BBrother
        18
    BBrother  
    OP
       2016-08-25 12:35:18 +08:00
    @razrlele 看了下, status_code 都是 200
    BBrother
        19
    BBrother  
    OP
       2016-08-25 12:45:35 +08:00
    @spider82 嗯,看了下 stackless ,因为我要实现的功能比较简单,我觉得 python3.5.X 的 async/await 是够用的。现在只是试着跑跑啦,感觉差不多了就多进程+代理爬数据啦。
    kinghui
        20
    kinghui  
       2016-08-25 15:11:07 +08:00
    @BBrother https://docs.python.org/3/library/asyncio-eventloop.html#executor

    > Call a function in an Executor (pool of threads or pool of processes). By default, an event loop uses a thread pool executor (ThreadPoolExecutor).
    JhZ7z587cYROBgVQ
        21
    JhZ7z587cYROBgVQ  
       2016-08-25 15:33:16 +08:00
    为啥不用 aiohttp 要用 requests 呢?不会被阻塞住么?
    wmjie
        22
    wmjie  
       2016-08-25 17:48:26 +08:00   1
    requests 会被阻塞,换成 aiohttp 试试;
    https://github.com/aosabook/500lines/tree/master/crawler
    soulmine
        23
    soulmine  
       2016-08-25 18:18:48 +08:00
    不挂代理池+搞分布式然后多线程 你跑到下个月也跑不完
    pncltp
        24
    pncltp  
       2016-08-25 18:27:59 +08:00 via iPhone
    为什么要重新造轮子,用 scrapy 库呗。
    mutalisk
        25
    mutalisk  
       2016-08-26 08:03:22 +08:00 via iPhone   1
    requests+gevent
    hard2reg
        26
    hard2reg  
       2016-08-26 14:44:04 +08:00
    你好,我是 B 站的运维。我打算在后端加入反爬虫代码了!
    BBrother
        27
    BBrother  
    OP
       2016-08-26 15:48:01 +08:00
    @hard2reg 不!住手! 尔康.jpg
    Shliesce
        28
    Shliesce  
       2016-08-26 18:01:53 +08:00
    我是 B 站的研发,我要取消这个接口了。
    hard2reg
        29
    hard2reg  
       2016-08-26 20:32:10 +08:00
    @BBrother 笑尿
    BBrother
        30
    BBrother  
    OP
       2016-08-29 22:35:16 +08:00
    @Shliesce 你不会真是 B 站的吧?接口真没了啊。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     896 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 21:29 PVG 05:29 LAX 14:29 JFK 17:29
    Do have faith in what you're doing.
    ubao 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