写了个简单的协程爬虫爬取 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. 我知道多进程,但我想问问协程能不能更有效率一点。
|  |      1lbp0200      2016-08-25 09:59:49 +08:00 多个爬虫+队列( redis ) | 
|  |      2chy373180      2016-08-25 10:05:30 +08:00 via iPhone 协程与多进程并不冲突 | 
|  |      3fatpa      2016-08-25 10:19:20 +08:00 消息队列啊少年 | 
|      4abxialiang      2016-08-25 10:21:20 +08:00 使用大量的代理 ip | 
|      5yangtukun1412      2016-08-25 10:21:55 +08:00 使用 requests.Session 复用连接应该能稍微快一点. | 
|  |      6kinghui      2016-08-25 10:29:07 +08:00 使用异步非阻塞 I/O, 如 Tornado, Twisted 等框架 | 
|  |      10razrlele      2016-08-25 10:41:58 +08:00 via iPhone 看一下返回的 response status ,带宽没起来有可能是很多 request 直接被返回 403 了 | 
|  |      11BBrother OP @abxialiang 呃,这个,有什么意义吗? | 
|      12spider82      2016-08-25 10:42:41 +08:00 可以看看 stackless ,我觉得瓶颈应该不在协程那里,单设备不用代理爬早晚被 BAN 。 | 
|  |      13knightdf      2016-08-25 10:49:33 +08:00 我每次开 30 台机器爬,想要效率,只有一个途径,花钱 | 
|      15Mark3K      2016-08-25 10:57:54 +08:00 代码使用了 coroutine ,但仍然是单线程在跑,没有利用到多核的优势,如果不考虑对方的反爬而只考虑效率的提高的话 可以再加上多进程试试 | 
|  |      16erevus      2016-08-25 11:08:38 +08:00 多进程+协程 能用到多核 | 
|  |      17BBrother OP 哇啊,大家真热情,谢谢大家!拜谢! | 
|  |      19BBrother OP @spider82 嗯,看了下 stackless ,因为我要实现的功能比较简单,我觉得 python3.5.X 的 async/await 是够用的。现在只是试着跑跑啦,感觉差不多了就多进程+代理爬数据啦。 | 
|  |      20kinghui      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). | 
|      21JhZ7z587cYROBgVQ      2016-08-25 15:33:16 +08:00 为啥不用 aiohttp 要用 requests 呢?不会被阻塞住么? | 
|      22wmjie      2016-08-25 17:48:26 +08:00  1 requests 会被阻塞,换成 aiohttp 试试; https://github.com/aosabook/500lines/tree/master/crawler | 
|  |      23soulmine      2016-08-25 18:18:48 +08:00 不挂代理池+搞分布式然后多线程 你跑到下个月也跑不完 | 
|  |      24pncltp      2016-08-25 18:27:59 +08:00 via iPhone 为什么要重新造轮子,用 scrapy 库呗。 | 
|      25mutalisk      2016-08-26 08:03:22 +08:00 via iPhone  1 requests+gevent | 
|      26hard2reg      2016-08-26 14:44:04 +08:00 你好,我是 B 站的运维。我打算在后端加入反爬虫代码了! | 
|      28Shliesce      2016-08-26 18:01:53 +08:00 我是 B 站的研发,我要取消这个接口了。 |