0

我有 python 3.4,我安装了请求和一些其他必要的程序来进行网络抓取。我的问题是我想抓取大约 7000 个页面(只是 html/文本),并且不想一次全部完成,我想有一些延迟,所以我不打服务器请求太多,可能会被禁止。我听说过 grequests 但显然它们没有适用于 python 3.4(实际错误说它找不到 vcvarsall.bat 但在文档中我没有看到对 3.4 的任何支持)。有谁知道可以管理 url 请求的替代程序?换句话说,我并不是要尽可能快地抓住一切,而是要缓慢而稳定。

4

1 回答 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 回答