- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在用 Python 2.7.3 编写一个带有 GRequests 的小脚本和 lxml 可以让我从各种网站收集一些收藏卡价格并进行比较。问题是其中一个网站限制了请求的数量,如果我超过它,就会发回 HTTP 错误 429。
有没有办法限制 GRequestes 中的请求数,这样我就不会超过我指定的每秒请求数?另外 - 如果发生 HTTP 429,我如何让 GRequestes 在一段时间后重试?
附带说明 - 他们的限制低得离谱。每 15 秒有 8 个请求。我多次使用浏览器破坏了它,只是刷新了等待价格变化的页面。
最佳答案
要回答我自己的问题,因为我必须自己解决这个问题,而且关于这个问题的信息似乎很少。
思路如下。与 GRequests 一起使用的每个请求对象在创建时都可以将 session 对象作为参数。另一方面, session 对象可以安装在发出请求时使用的 HTTP 适配器。通过创建我们自己的适配器,我们可以拦截请求并以我们认为最适合我们的应用程序的方式限制它们。就我而言,我最终得到了下面的代码。
用于 throttle 的对象:
DEFAULT_BURST_WINDOW = datetime.timedelta(seconds=5)
DEFAULT_WAIT_WINDOW = datetime.timedelta(seconds=15)
class BurstThrottle(object):
max_hits = None
hits = None
burst_window = None
total_window = None
timestamp = None
def __init__(self, max_hits, burst_window, wait_window):
self.max_hits = max_hits
self.hits = 0
self.burst_window = burst_window
self.total_window = burst_window + wait_window
self.timestamp = datetime.datetime.min
def throttle(self):
now = datetime.datetime.utcnow()
if now < self.timestamp + self.total_window:
if (now < self.timestamp + self.burst_window) and (self.hits < self.max_hits):
self.hits += 1
return datetime.timedelta(0)
else:
return self.timestamp + self.total_window - now
else:
self.timestamp = now
self.hits = 1
return datetime.timedelta(0)
HTTP 适配器:
class MyHttpAdapter(requests.adapters.HTTPAdapter):
throttle = None
def __init__(self, pool_connections=requests.adapters.DEFAULT_POOLSIZE,
pool_maxsize=requests.adapters.DEFAULT_POOLSIZE, max_retries=requests.adapters.DEFAULT_RETRIES,
pool_block=requests.adapters.DEFAULT_POOLBLOCK, burst_window=DEFAULT_BURST_WINDOW,
wait_window=DEFAULT_WAIT_WINDOW):
self.throttle = BurstThrottle(pool_maxsize, burst_window, wait_window)
super(MyHttpAdapter, self).__init__(pool_connections=pool_connections, pool_maxsize=pool_maxsize,
max_retries=max_retries, pool_block=pool_block)
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
request_successful = False
response = None
while not request_successful:
wait_time = self.throttle.throttle()
while wait_time > datetime.timedelta(0):
gevent.sleep(wait_time.total_seconds(), ref=True)
wait_time = self.throttle.throttle()
response = super(MyHttpAdapter, self).send(request, stream=stream, timeout=timeout,
verify=verify, cert=cert, proxies=proxies)
if response.status_code != 429:
request_successful = True
return response
设置:
requests_adapter = adapter.MyHttpAdapter(
pool_connections=__CONCURRENT_LIMIT__,
pool_maxsize=__CONCURRENT_LIMIT__,
max_retries=0,
pool_block=False,
burst_window=datetime.timedelta(seconds=5),
wait_window=datetime.timedelta(seconds=20))
requests_session = requests.session()
requests_session.mount('http://', requests_adapter)
requests_session.mount('https://', requests_adapter)
unsent_requests = (grequests.get(url,
hooks={'response': handle_response},
session=requests_session) for url in urls)
grequests.map(unsent_requests, size=__CONCURRENT_LIMIT__)
关于python - 限制/限制 GRequests 中 HTTP 请求的速率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20247354/
这是我第一次尝试使用文档和示例代码水平不理想的库,所以请多多包涵。我对 Requests 库有一点经验,但我需要每秒向特定地址发送单独的请求: 无需等待第一个请求完成,处理进来时的个人回应 响应的内容
我正在尝试缩短 urlSet 中的许多 URL。以下代码大部分时间都有效。但有时需要很长时间才能完成。例如,我在 urlSet 中有 2950。 stderr 告诉我 2900 已完成,但 getUr
尽管模块按预期工作,但我每次都会收到以下警告: /usr/local/lib/python3.7/site-packages/grequests.py:21: MonkeyPatchWarning:
我正在使用 grequests 从使用相同 url 但不同参数的网站异步下载数据。 例如, unsent_requests = [] for param in params: # assume par
我最近在工作场所发现了一些使用 grequests library 的内部代码发出它的 HTTP 请求。 但是,当我查看代码时,我注意到程序一次只发送一个请求。例如,考虑以下函数: def run(s
我正在尝试执行大约 100k GET 请求并解析每个请求的响应正文。我认为 grequests 将是一个好方法,但我收到与“打开文件太多”相关的错误。代码如下: import grequests wi
我正在编写一个程序。它从文件中读取 url,然后发出请求。但是处理程序不会被调用。 这是我的代码: import grequests def main(): async_list =[]
我正在处理一个基本上如下的过程: 获取一些 url 列表。 获取Response每个人的对象。 从每个 Response 的 text 创建一个 BeautifulSoup 对象。 从 Beautif
我已经使用python requests 库有一段时间了,最近需要异步发出请求,这意味着我想发送 HTTP 请求,让我的主线程继续执行,并有一个回调请求返回时调用。 当然,我被引导到 greque
我正在使用 grequests 来更快地对网站进行 scape。但是,我还需要登录该网站。 之前(只使用请求)我可以做: headers 是我的 User-Agent。 with requests.S
我想制作多个 requests同时。我找到了可以帮助我实现这一目标的 python 模块!但现在我遇到了一个问题,我不知道如何使用这个库处理每个请求中的简单或基本身份验证。 代码如下: import
我有这个代码 #!/usr/bin/python import grequests urls = [ 'http://google.com', 'http://doesnotexists.tld' ]
关于 grequests 的快速问题,因为它的文档相当稀少。从发送的请求中返回 xml 响应的最佳方法是什么?除了状态代码之外,我无法找到一种方法来获得响应。有人能指出我正确的方向吗? greques
我想传递一个参数来忽略一大组 GET 的 SSL 错误。在 requests 包中,您可以传递 verfiy=false 参数。我没有看到任何类似的请求。如果有更好的方案或方向,我很乐意。 urls
我正在使用 grequests 库传递约 250000 个 url 以从 api 获取数据。 API 的调用限制为每秒 100 次。 如何将请求限制为每秒仅传递 100 个 URL?我将大小参数从 5
我的原始任务:使用 Trello API , 通过 HTTP GET 请求获取数据。如果可能,异步运行请求和处理响应。 API 提供程序使用我通过一些 key 和 token 访问的“https://
我正在使用 grequests python 模块来调用一些 API。我想做两个功能。 单个请求(使用请求模块) 一个多请求(使用grequests模块) 当我在两个不同的文件中使用两个模块时,它运行
这是导致内存使用量不断增加的脚本的精简版本,我看到它在 2 分钟后超过了 600MB: import requests import grequests lines = (grequests.get(
当我尝试使用 pip 在 Ubuntu 上安装 grequests 时: sudo pip install grequests 我收到此错误,但我的 gcc 似乎没问题: In file includ
我看到了这个post关于使用 grequests 发送异步请求。 import grequests urls = [ 'http://www.heroku.com', 'http://
我是一名优秀的程序员,十分优秀!