【发布时间】:2018-02-02 20:06:24
【问题描述】:
我正在尝试使用requests-futures 库发送一批异步HTTP 请求,并识别每个页面内容中是否存在特定字节串。
这里是同步版本。请注意,我正在抓取的实际站点不是 Stack Overflow,实际上 URL 的长度约为 20,000。在下面的示例中,我平均每个循环大约 1 秒的挂墙时间,这意味着整个批次将需要半天的时间。
import timeit
import requests
KEY = b'<meta name="referrer"'
def filter_url(url):
"""Presence or absence of `KEY` in page's content."""
resp = requests.get(url, stream=True)
return resp.content.find(KEY) > -1
urls = [
'https://stackoverflow.com/q/952914/7954504',
'https://stackoverflow.com/q/48512098/7954504',
'https://stackoverflow.com/q/48511048/7954504',
'https://stackoverflow.com/q/48509674/7954504',
'https://stackoverflow.com/q/15666943/7954504',
'https://stackoverflow.com/q/48501822/7954504',
'https://stackoverflow.com/q/48452449/7954504',
'https://stackoverflow.com/q/48452267/7954504',
'https://stackoverflow.com/q/48405592/7954504',
'https://stackoverflow.com/q/48393431/7954504'
]
start = timeit.default_timer()
res = [filter_url(url) for url in urls]
print(timeit.default_timer() - start)
# 11.748123944002145
现在,当我要异步执行此操作时:
from requests_futures.sessions import FuturesSession
session = FuturesSession()
def find_multi_reviews(urls):
resp = [session.get(url).result() for url in urls]
print(resp)
return [i.content.find(KEY) > -1 for i in resp]
start = timeit.default_timer()
res2 = find_multi_reviews(urls)
print(timeit.default_timer() - start)
# 1.1806047540012514
我可以获得 10 倍的加速。这没关系——但我能做得更好吗?截至目前,我仍在查看不到 2 小时的运行时间。是否有技巧,例如增加工人的数量或在单独的进程中执行, 会导致这里的速度提高吗?
【问题讨论】:
-
多处理模块可能会有所帮助。如果你有多台机器,你应该看看任务队列(比如 celery)
标签: python asynchronous python-requests requests-futures