我有 python 3.4,我安装了请求和一些其他必要的程序来进行网络抓取。我的问题是我想抓取大约 7000 个页面(只是 html/文本),并且不想一次全部完成,我想有一些延迟,所以我不打服务器请求太多,可能会被禁止。我听说过 grequests 但显然它们没有适用于 python 3.4(实际错误说它找不到 vcvarsall.bat 但在文档中我没有看到对 3.4 的任何支持)。有谁知道可以管理 url 请求的替代程序?换句话说,我并不是要尽可能快地抓住一切,而是要缓慢而稳定。
问问题
1921 次
1 回答
1
我建议滚动您自己的多线程程序来执行请求。我发现concurrent.futures
这是对这类请求进行多线程处理的最简单方法,尤其是使用ThreadPoolExecutor
. 他们甚至在文档中有一个简单的多线程 url 请求示例。
至于问题的第二部分,这实际上取决于您想限制多少/如何限制您的请求。对我来说,设置一个足够低的max_workers
参数并可能time.sleep
在我的函数中包含一个等待就足以避免任何问题,即使在抓取数万页时也是如此,但这显然更多地取决于你试图抓取的网站。不过,实现某种批处理或等待应该不难。
以下代码未经测试,但希望它可以作为一个起点。从这里开始,您可能想用您需要做的任何其他事情(例如解析、保存)来修改get_url_data
(或您正在使用的任何功能)。
import concurrent.futures as futures
import requests
from requests.exceptions import HTTPError
urllist = ...
def get_url_data(url, session):
try:
r = session.get(url, timeout=10)
r.raise_for_status()
except HTTPError:
return None
return r.text
s = requests.Session()
try:
with futures.ThreadPoolExecutor(max_workers=5) as ex:
future_to_url = {ex.submit(get_url_data, url, s): url
for url in urlist}
results = {future_to_url[future]: future.result()
for future in futures.as_completed(future_to_url)}
finally:
s.close()
于 2014-08-14T06:11:58.943 回答