通过使用python发送并发请求进行刮取

通过使用python发送并发请求进行刮取,python,web-scraping,grequests,Python,Web Scraping,Grequests,我已经安装了Python3.4,并且安装了请求和其他一些必要的程序来进行web刮取。我的问题是,我想抓取大约7000页(仅html/文本),不想一次完成所有工作,我希望有一些延迟,这样我就不会在服务器上发出太多请求,并可能被禁止。我听说过grequests,但显然他们没有用于Python3.4的grequests(实际错误是找不到vcvarsall.bat,但在文档中我没有看到对3.4的任何支持)。有人知道可以管理url请求的替代程序吗?换句话说,我并不希望尽可能快地获取所有内容,而是缓慢而稳定

我已经安装了Python3.4,并且安装了请求和其他一些必要的程序来进行web刮取。我的问题是,我想抓取大约7000页(仅html/文本),不想一次完成所有工作,我希望有一些延迟,这样我就不会在服务器上发出太多请求,并可能被禁止。我听说过grequests,但显然他们没有用于Python3.4的grequests(实际错误是找不到vcvarsall.bat,但在文档中我没有看到对3.4的任何支持)。有人知道可以管理url请求的替代程序吗?换句话说,我并不希望尽可能快地获取所有内容,而是缓慢而稳定。

我建议使用您自己的多线程程序来执行请求。我发现
concurrent.futures
是多线程处理这类请求的最简单方法,尤其是使用。文档中甚至有一个简单的多线程url请求示例

至于问题的第二部分,这实际上取决于您希望限制您的请求的程度。对我来说,在我的函数中设置一个足够低的
max_workers
参数,并可能包含一个
time.sleep
wait,即使在抓取成千上万的页面时,也足以避免任何问题,但这显然更多地取决于你试图抓取的站点。实现某种批处理或等待应该不难

下面的代码未经测试,但希望它可以作为一个起点。从这里开始,您可能需要修改
获取url\u数据
(或您正在使用的任何函数)以及您需要执行的任何其他操作(例如解析、保存)


可能重复@remudada谢谢,是的,我看到了,如果我可以安装grequests,我可以解决我的问题,但我无法将其安装在python 3.4上,所以我正在寻找替代解决方案?你的问题离题了,但我可以给你一个答案:非常感谢,这看起来很有希望,我的编程速度非常慢,因为我还是一个初学者,但我会试试这个,明天给你回复!这是否意味着我将使用urllib而不是请求?但是我仍然可以使用BeautifulSoup来进行解析,对吗?不,您几乎可以肯定仍然应该使用
请求
。我会看看我是否能找到一些我用过的旧代码,并将其编辑成答案。谢谢,这似乎是一切!我仍然在试图找出如何提取数据,因为我也是CSS引用的新手。这是否将所有html文件放入“结果”中?对于结果中的每个项目,我是否能够运行For循环并执行类似test=bs4.BeautifulSoup(结果[0].text])的操作?希望如此!或者,根据站点的数量和您希望如何处理它们,您可以将任何解析和保存添加到您版本的
get\u url\u data
函数中,在这种情况下,您可能根本不需要返回
results
dict。谢谢,我可能会这样做。作为最后一个问题,您似乎没有使用
time.sleep
-如果我想,我可以将
sleep(1)
添加到
get\u url\u 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()