Maximale Wiederholungsversuche mit URL in Anfragen überschritten


151

Ich versuche, den Inhalt von App Store> Business abzurufen :

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)

Wenn ich das rangemit versuche (0,2), funktioniert es, aber wenn ich das rangein 100s setze , zeigt es diesen Fehler:

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
Sollten Sie nicht iirgendwo in der eine Variable verwenden for?
Laurent S.

Sie möchten dieselbe App 100 Mal anfordern. Wofür ist das ?
njzk2

Ich benutze i im Rest des Codes. Ich habe nicht den gesamten Code gepostet
user3446000

Ich fordere nicht 100 Mal dieselbe App an. Ich fordere 100 verschiedene Apps in derselben Kategorie an.
user3446000

3
Ihr DNS-Resolver kann anscheinend nicht aufgelöst werden itunes.apple.com. Können Sie dig itunes.apple.coman Ihrer Kommandozeile laufen und die Ergebnisse hier veröffentlichen?
Thomas Orozco

Antworten:


139

Was hier passiert ist, ist, dass der iTunes Server Ihre Verbindung ablehnt (Sie senden in kurzer Zeit zu viele Anfragen von derselben IP-Adresse).

Maximale Wiederholungsversuche mit URL überschritten: / in / app / adobe-reader / id469337564? Mt = 8

Die Fehlersuche ist irreführend und sollte etwa "Es konnte keine Verbindung hergestellt werden, da der Zielcomputer sie aktiv abgelehnt hat" lauten .

Es gibt ein Problem bei etwa python.requests lib bei Github. Überprüfen Sie es hier

Um dieses Problem zu beheben (weniger ein Problem als vielmehr eine irreführende Debug-Ablaufverfolgung), sollten Sie verbindungsbezogene Ausnahmen wie die folgenden abfangen:

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

Eine andere Möglichkeit, dieses Problem zu beheben, besteht darin, dass Sie eine ausreichende Zeitlücke zum Senden von Anforderungen an den Server verwenden. Dies kann durch die sleep(timeinsec)Funktion in Python erreicht werden (vergessen Sie nicht, den Ruhezustand zu importieren).

from time import sleep

Alles in allem ist Anfragen fantastisch Python Lib, hoffe, das löst Ihr Problem.


2
Die Schlafschleife hat mein Problem behoben - ein bisschen wie ein Hack, aber durch ein paar Schleifen während der Behandlung der Fehlerantwort konnte ich eine Lösung brutal erzwingen.
elPastor

14
Diese Antwort ist eigentlich falsch. Dies ist ein Resolver-Suchproblem, wie im (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)Teil angegeben. "gai" steht für getaddrinfound der wahrscheinliche Fehler ist: EAI_NONAME Der Knoten oder Dienst ist nicht bekannt; oder sowohl Knoten als auch Dienst sind NULL; oder AI_NUMERICSERV wurde in hints.ai_flags angegeben und service war keine numerische Portnummernzeichenfolge. Es sah wahrscheinlich so aus, als hätte der Schlaf das Problem behoben, aber Sie haben wahrscheinlich nur ein vorübergehendes DNS-Resolver-Problem durchgeschlafen.
Lingfish

4
Diese Antwort scheint nicht sinnvoll zu sein, da 'r' das Objekt ist, das von request.get () stammt. Mit der Ausnahme führt dies nur zu einem weiteren Fehler.
Mikkokotila

Diese Antwort macht keinen Sinn. Der OP-Fehler lautet nicht "Verbindung abgelehnt", sondern "Name oder Dienst nicht bekannt". Diese Antwort scheint davon auszugehen, dass alle ConnectionError auf "Verbindung abgelehnt" zurückzuführen sind.
Erjiang

1
Für mich muss dies genau richtig sein, ein vom Server festgelegtes Ratenlimit. Ich kann 80 Anrufe tätigen und dann erscheint diese Nachricht für mich. Nach kurzer Zeit steht der Server für weitere 80 Anrufe zur Verfügung und der Zyklus wird wiederholt. es ist zu regelmäßig, um etwas anderes zu sein.
Demongolem

121

Verwenden Sie einfach requests'Funktionen:

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)

Dies wird GETdie URL und versuchen 3 Mal im Fall von requests.exceptions.ConnectionError. backoff_factorDies hilft dabei, Verzögerungen zwischen den Versuchen anzuwenden, um zu vermeiden, dass bei einem regelmäßigen Anforderungskontingent erneut ein Fehler auftritt.

Schauen Sie sich an requests.packages.urllib3.util.retry.Retry, es gibt viele Möglichkeiten, um Wiederholungsversuche zu vereinfachen.


Aus irgendeinem Grund funktioniert dies unter Windows 10 nicht. Die Shell wurde mit gestartet python manage.py shellund wird verwendet session.get('http://localhost:8000/api/'). Irgendeine Hilfe? @ Zulu
MwamiTovi

habe mein Problem gelöst. Hatte vergessen, das zu starten dev-serverund es zuerst am Laufen zu halten.
MwamiTovi

Warum ist es immer noch nicht die beste Antwort?
Pavel Druzhinin

Ich habe dies versucht, aber es wurde nicht wiederholt, während ich das Zeitlimit für das Lesen von request.exceptions.ConnectionError Read erhielt. Ich habe jedoch eine Zeitüberschreitung für die Get-Anfrage festgelegt.
Zagfai

34

Tu das einfach,

Fügen Sie anstelle von den folgenden Code ein 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

Bitte :)


3
Denken Sie daran zu tun import time
Yuan Tao

3
requestshat seinen eigenen Code, um seinen Fehler zu behandeln und erneut zu versuchen
Zulu

5
Es verlässt nie die Schleife. @ Jatin
Alper

10
Es ist auch keine gute Idee, einfach irgendeine Art von Ausnahme (mit except: ...) von requestsund sleep()als Antwort abzufangen. Stattdessen sollten sie abfangen requests.exceptions.ConnectionErrorund sleep()nur, wenn diese Ausnahme auftritt. (Oder noch besser, verwenden Sie einfach die mitgelieferte integrierte Retry()Klasse requests, wie von @Zulu vorgeschlagen).
J. Taylor


15

Ich habe ein ähnliches Problem, aber der folgende Code hat bei mir funktioniert.

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

"verify = False" deaktiviert die SSL-Überprüfung. Try and Catch kann wie gewohnt hinzugefügt werden.


5

Es ist immer gut, die Ausnahmebehandlung zu implementieren. Dies hilft nicht nur, ein unerwartetes Beenden des Skripts zu vermeiden, sondern kann auch helfen, Fehler und Info-Benachrichtigungen zu protokollieren. Wenn ich Python-Anfragen verwende, bevorzuge ich Ausnahmen wie diese:

    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")

Hier ist erneuerIPadress () eine benutzerdefinierte Funktion, die die IP-Adresse ändern kann, wenn sie blockiert wird. Sie können auf diese Funktion verzichten.


Ihre Lösung ist schön, aber wie man ip-adrressin Python ändert , wissen Sie etwas darüber, dann lassen Sie es mich wissen
Haritsinh Gohil

1
Ich hatte einen VPN-Dienst IPVanish und Hide My Ass verwendet. Sie werden mit open-vpn konfiguriert und open-vpn verfügt über eine Shell-Befehlszeile, mit der die IP-Adresse erneuert wird. Sie können den Shell- oder Bash-Befehl von Python aus aufrufen. Auf diese Weise können Sie es implementieren.
Tanmoy Datta

5

Die Angabe des Proxys in einer Unternehmensumgebung hat das Problem für mich gelöst.

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

Der vollständige Fehler ist:

request.exceptions.ConnectionError: HTTPSConnectionPool (host = 'www.google.com', port = 80): Maximale Wiederholungsversuche mit URL überschritten: / (verursacht durch NewConnectionError (': Fehler beim Herstellen einer neuen Verbindung: [WinError 10060] Eine Verbindung Versuch fehlgeschlagen, weil die verbundene Partei nach einer bestimmten Zeit nicht richtig geantwortet hat, oder die hergestellte Verbindung fehlgeschlagen ist, weil der verbundene Host nicht geantwortet hat '))


2

Ich war nicht in der Lage, es unter Windows zum Laufen zu bringen, selbst nachdem ich pyopenssl installiert und verschiedene Python-Versionen ausprobiert hatte (während es auf dem Mac gut funktionierte), also wechselte ich zu urllib und es funktionierte unter Python 3.6 (von Python .org) und 3.7 (Anaconda) )

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

Ich bin ziemlich genervt, dass die Dinge nur funktionieren, wenn sie mit der Anaconda-Eingabeaufforderung ausgeführt werden.
BingLi224

1

Beim Schreiben eines Selenium-Browser- driver.quit()Testskripts ist dieser Fehler beim Aufrufen vor der Verwendung eines JS-API-Aufrufs aufgetreten. Denken Sie daran, dass das Beenden des Web-Treibers das letzte ist, was zu tun ist!


1

Hinzufügen meiner eigenen Erfahrung für diejenigen, die dies in Zukunft erleben. Mein spezifischer Fehler war

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

Es stellt sich heraus, dass dies tatsächlich daran lag, dass ich die maximale Anzahl geöffneter Dateien auf meinem System erreicht hatte. Es hatte nichts mit fehlgeschlagenen Verbindungen oder sogar einem DNS-Fehler wie angegeben zu tun.


0

Meine eigene Erfahrung hinzufügen:

r = requests.get(download_url)

als ich versuchte, eine in der URL angegebene Datei herunterzuladen.

Der Fehler war

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')])")))

Ich habe es korrigiert, indem ich verify = Falsedie Funktion wie folgt hinzugefügt habe :

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

-1

Fügen Sie Header für diese Anforderung hinzu.

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.