请求中的URL超过了最大重试次数


151

我正在尝试获取App Store> Business的内容:

import requests
from lxml import html

page = requests.get("https://itunes.apple.com/in/genre/ios-business/id6000?mt=8")
tree = html.fromstring(page.text)

flist = []
plist = []
for i in range(0, 100):
    app = tree.xpath("//div[@class='column first']/ul/li/a/@href")
    ap = app[0]
    page1 = requests.get(ap)

当我尝试range使用(0,2)它时,但是当我使用rangein 时,100它显示此错误:

Traceback (most recent call last):
  File "/home/preetham/Desktop/eg.py", line 17, in <module>
    page1 = requests.get(ap)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 55, in get
    return request('get', url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 383, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 486, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 378, in send
    raise ConnectionError(e)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='itunes.apple.com', port=443): Max retries exceeded with url: /in/app/adobe-reader/id469337564?mt=8 (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)

1
您不应该i在中的某处使用变量for吗?
Laurent S.

您就像要求一个应用100次一样。那是做什么用的 ?
njzk2 2014年

我在其余的代码中使用i。我尚未发布整个代码
user3446000

我没有要求同一个应用100次。我要求在同一类别下提供100个不同的应用程序。
user3446000 2014年

3
看来您的DNS解析器无法解析itunes.apple.com。您可以dig itunes.apple.com在命令行中运行并将结果发布到此处吗?
Thomas Orozco 2014年

Answers:


141

这里发生的是itunes服务器拒绝您的连接(您在短时间内从同一ip地址发送了太多请求)

网址超出了最大重试次数:/ in / app / adobe-reader / id469337564?mt = 8

错误跟踪会误导您,应该是“由于目标计算机主动拒绝连接而无法建立连接”

Github上有关python.requests lib的问题,请在此处查看

要克服此问题(与其说是错误的调试跟踪,不如说是一个问题),您应该捕获与连接有关的异常,如下所示:

try:
    page1 = requests.get(ap)
except requests.exceptions.ConnectionError:
    r.status_code = "Connection refused"

解决此问题的另一种方法是,如果您使用足够的时间间隔将请求发送到服务器,则可以通过sleep(timeinsec)python中的函数来实现(不要忘记导入睡眠)

from time import sleep

总而言之,请求都是很棒的python lib,希望能解决您的问题。


2
睡眠循环解决了我的问题-有点破解,但是通过在处理错误响应时循环几次,我得以强行解决。
elPastor

14
这个答案实际上是错误的。如(Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)零件所示,这是一个解析器查找问题。“ gai”代表getaddrinfo,并且可能的相关错误是: EAI_NONAME节点或服务未知;或节点和服务均为NULL;或 或在hints.ai_flags中指定了AI_NUMERICSERV,并且服务不是端口号数字字符串。看起来好像睡眠可以解决问题,但是您可能只是通过暂时的DNS解析器问题进行了睡眠。
lingfish

4
这个答案似乎没有任何意义,因为在“ r”中是来自requests.get()的对象,因此,这会导致另一个错误。
mikkokotila

这个答案没有道理。OP的错误未显示“拒绝连接”,而是显示“名称或服务未知”。该答案似乎假定所有ConnectionError均归因于“拒绝连接”。
erjiang

1
对我来说,这是完全正确的,服务器设置了速率限制。我可以拨打80个电话,然后此消息会为我显示。然后,过一会儿,服务器可再接80个电话,然后重复该循环。太常规了,别无其他。
demongolem

122

只需使用以下requests'功能:

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry


session = requests.Session()
retry = Retry(connect=3, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

session.get(url)

这将GET是URL,如果是,将重试3次requests.exceptions.ConnectionErrorbackoff_factor将有助于在两次尝试之间施加延迟,以避免在定期请求配额的情况下再次失败。

看一下requests.packages.urllib3.util.retry.Retry,它有许多选项可以简化重试。


无论出于何种原因,这并不在Windows 10开始与外壳的工作python manage.py shell和正在使用session.get('http://localhost:8000/api/')。有什么帮助吗?@祖鲁
MwamiTovi '19

解决了我的问题。忘记了启动dev-server并使其首先运行。
MwamiTovi

为什么它仍然不是最佳答案?
帕维尔·德鲁欣宁

我尝试了此操作,但在收到request.exceptions.ConnectionError读取超时时不会重试。但我为获取请求设置了超时时间。
Zagfai

34

就是这样

粘贴以下代码代替page = requests.get(url)

import time

page = ''
while page == '':
    try:
        page = requests.get(url)
        break
    except:
        print("Connection refused by the server..")
        print("Let me sleep for 5 seconds")
        print("ZZzzzz...")
        time.sleep(5)
        print("Was a nice sleep, now let me continue...")
        continue

别客气 :)


3
记得要做 import time
袁涛

3
requests有自己的代码来处理错误
Zulu

5
它永远不会退出循环。@jatin
alper

10
此外,并非一个好主意,只是捕捉任何类型的异常(有except: ...从)requestssleep()响应。相反,他们应该抓住requests.exceptions.ConnectionError并且sleep()只有在发生该异常。(或者更好的方法是,使用@Zulu建议的随带的内置Retry()requests)。
泰勒


15

我遇到了类似的问题,但是以下代码对我有用。

url = <some REST url>    
page = requests.get(url, verify=False)

“ verify = False”禁用SSL验证。尝试捕获可以像往常一样添加。


5

实施异常处理总是好的。它不仅有助于避免脚本意外退出,还可以帮助记录错误和信息通知。当使用Python请求时,我更喜欢捕获这样的异常:

    try:
        res = requests.get(adress,timeout=30)
    except requests.ConnectionError as e:
        print("OOPS!! Connection Error. Make sure you are connected to Internet. Technical Details given below.\n")
        print(str(e))            
        renewIPadress()
        continue
    except requests.Timeout as e:
        print("OOPS!! Timeout Error")
        print(str(e))
        renewIPadress()
        continue
    except requests.RequestException as e:
        print("OOPS!! General Error")
        print(str(e))
        renewIPadress()
        continue
    except KeyboardInterrupt:
        print("Someone closed the program")

这里的renewIPadress()是一个用户定义函数,如果被阻止,它可以更改IP地址。您可以不使用此功能。


您的解决方案很好,但是如何ip-adrress在python中进行更改,您是否了解它,然后让我知道
Haritsinh Gohil

1
我曾经使用过一些VPN服务IPVanish和“隐藏我的屁股”。使用open-vpn和open-vpn配置它们,并在shell命令行中更新IP地址。您可以从python调用shell或bash命令。这样,您可以实现它。
Tanmoy Datta

5

在公司环境中指定代理可以为我解决问题。

page = requests.get("http://www.google.com:80", proxies={"http": "http://111.233.225.166:1234"})

完整的错误是:

requests.exceptions.ConnectionError:HTTPSConnectionPool(host ='www.google.com',port = 80):URL超过了最大重试次数:/(由NewConnectionError(':导致:无法建立新连接:[WinError 10060]连接尝试失败,因为连接的一方在一段时间后未正确响应,或者建立的连接失败,因为连接的主机未能响应'))


2

即使安装了pyopenssl并尝试了各种python版本(尽管在Mac上运行良好)后,我仍无法使其在Windows上运行,所以我切换到urllib,并且在python 3.6(来自python .org)和3.7(anaconda)上工作)

import urllib 
from urllib.request import urlopen
html = urlopen("http://pythonscraping.com/pages/page1.html")
contents = html.read()
print(contents)

我很生气,只有在Anaconda提示符下运行,事情才能起作用。
BingLi224 '19

1

在编写硒浏览器测试脚本时,driver.quit()在使用JS api 调用之前进行调用时会遇到此错误。请记住退出网络驱动程序是最后要做的事情!


1

为以后遇到这种情况的人增加我自己的经验。我的具体错误是

Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'

事实证明,这实际上是因为我已达到系统上打开文件的最大数量。它与失败的连接或指示的DNS错误无关。


0

添加我自己的经验:

r = requests.get(download_url)

当我尝试下载url中指定的文件时。

错误是

HTTPSConnectionPool(host, port=443): Max retries exceeded with url (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))

我通过添加verify = False如下函数来更正了它:

r = requests.get(download_url + filename)
open(filename, 'wb').write(r.content)

-1

添加此请求的标头。

headers={
'Referer': 'https://itunes.apple.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}

requests.get(ap, headers=headers)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.