我制作了一个python程序,它解析子reddits页面并列出它们的列表。但问题是每当我尝试运行这个程序时,reddit 服务器总是给我错误:
429, 'too many requests'
。
如何减少请求数量,从而不受速率限制?
from bs4 import BeautifulSoup as bs
from time import sleep
import requests as req
html = req.get('http://www.reddit.com/')
print html
soup = bs(html.text)
# http://www.reddit.com/subreddits/
link_to_sub_reddits = soup.find('a',id='sr-more-link')['href']
print link_to_sub_reddits
L=[]
for navigate_the_pages in xrange(1):
res = req.get(link_to_sub_reddits)
soup = bs(res.text)
# soup created
print soup.text
div = soup.body.find('div', class_=lambda(class_):class_ and class_=='content')
div = div.find('div', id= lambda(id):id and id=='siteTable')
cnt=0
for iterator in div:
div_thing = div.contents[cnt]
if not div_thing=='' and div_thing.name=='div' and 'thing' in div_thing['class']:
div_entry = div_thing.find('a',class_=lambda(class_):class_ and 'entry' in class_)
# div with class='entry......'
link = div_entry.find('a')['href']
# link of the subreddit
name_of_sub = link.split('/')[-2]
# http://www.reddit.com/subreddits/
# ['http:', '', 'www.reddit.com', 'subreddits', '']
description = div_entry.find('strong').text
# something about the community
p_tagline = div_entry.find('p',class_='tagline')
subscribers = p_tagline.find('span',class_='number').text
L.append((name_of_sub, link, description, subscribers))
elif not div_thing=='' and div_thing.name=='div' and 'nav-buttons' in div_thing['class']:
# case when we find 'nav' button
link_to_sub_reddits = div_thing.find('a')['href']
break
cnt = cnt + 1
sleep(10)
sleep(10)
编辑:所有的人都投了反对票,我不知道我发布这个问题犯了什么严重的错误(感谢反馈)。如果有帮助的话,我是 3 天大的“Pythoner”了。所以基本上我正在尝试学习Python。也许我问的问题对你们来说太明显了,但对我来说却不是。这个问题可以帮助像我这样尝试学习 Python 的其他菜鸟。但由于反对票,它会在某个地方丢失。
这背后的一个可能原因是 reddit 可能一直在检查用户代理标头。由于您没有添加任何用户代理标头,reddit 会将其标记为机器人的请求,这就是您收到错误的原因。 尝试添加用户代理来请求。
这是 reddit 的正常速率限制。您唯一的选择是发出较少数量的请求,或者从具有不同 IP 的多个服务器发出请求(在这种情况下,您的方法会根据服务器数量进行扩展)。
来自维基百科对 HTTP 错误代码 429 的描述:
429 请求过多 (RFC 6585):
用户在给定时间内发送了太多请求。旨在与速率限制方案一起使用。
首先尝试找出允许您发送请求的频率,并将其与发送请求的最大速率进行比较。
当您发现请求过于频繁时,请在每个请求之间添加一些简单的内容,例如
time.sleep(interval)
,以确保您在请求之间等待足够的时间。
如果你想聪明一点,你可以写一些东西来计算距离你上次请求已经过去了多长时间,或者计算你在最近一段时间内做了多少次。然后,您可以使用此信息来决定睡多长时间。
编辑: 事实上查看规则页面:https://github.com/reddit/reddit/wiki/API#rules
Monitor the following response headers to ensure that you're not exceeding the limits:
X-Ratelimit-Used: Approximate number of requests used in this period
X-Ratelimit-Remaining: Approximate number of requests left to use
X-Ratelimit-Reset: Approximate number of seconds to end of period
Clients connecting via OAuth2 may make up to 60 requests per minute.
他们似乎在回复中告诉您可以提出多少个请求,以及需要等待多长时间才能获得更多请求。 当您没有剩余的使用请求时,就睡觉直到一分钟结束。
我认为您可以尝试将带有用户代理的标头添加到您的请求中