Numero massimo di tentativi superato con URL nelle richieste


151

Sto cercando di ottenere il contenuto di 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)

Quando provo il rangecon (0,2)funziona, ma quando inserisco rangein 100s mostra questo errore:

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
Non dovresti usare la ivariabile da qualche parte nel for?
Laurent S.

stai chiedendo la stessa app 100 volte. a cosa serve ?
njzk2,

Sto usando i nel resto del codice. Non ho pubblicato l'intero codice
user3446000

Non sto richiedendo la stessa app 100 volte. Sto richiedendo 100 app diverse nella stessa categoria.
user3446000,

3
Sembra che il risolutore DNS non sia in grado di risolvere itunes.apple.com. Puoi correre dig itunes.apple.comdalla tua riga di comando e pubblicare i risultati qui?
Thomas Orozco,

Risposte:


141

Quello che è successo qui è che il server itunes rifiuta la tua connessione (stai inviando troppe richieste dallo stesso indirizzo IP in breve tempo)

Numero massimo di tentativi superato con url: / in / app / adobe-reader / id469337564? Mt = 8

la traccia dell'errore è fuorviante dovrebbe essere qualcosa del tipo "Non è stato possibile stabilire alcuna connessione perché la macchina di destinazione l'ha rifiutata attivamente" .

C'è un problema su lib python.requests su Github, controlla qui

Per ovviare a questo problema (non tanto quanto è fuorviante la traccia di debug), dovresti rilevare eccezioni relative alla connessione in questo modo:

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

Un altro modo per ovviare a questo problema è se si utilizza un intervallo di tempo sufficiente per inviare richieste al server, ciò può essere ottenuto mediante la sleep(timeinsec)funzione in Python (non dimenticare di importare sleep)

from time import sleep

Tutto sommato le richieste sono fantastiche lib python, spero che risolva il tuo problema.


2
Il ciclo del sonno ha risolto il mio problema - un po 'di un trucco, ma eseguendo il ciclo un paio di volte mentre gestivo la risposta all'errore, sono stato in grado di forzare una soluzione.
elPastor

14
Questa risposta è in realtà sbagliata. Questo è un problema di ricerca del resolver, come indicato dalla (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)parte. "gai" significa getaddrinfo, e il probabile errore correlato è: EAI_NONAME Il nodo o il servizio non è noto; oppure sia il nodo che il servizio sono NULL; oppure AI_NUMERICSERV è stato specificato in hints.ai_flags e il servizio non era una stringa numerica di porta. Probabilmente sembrava che il sonno lo avesse risolto, ma probabilmente hai dormito solo attraverso un problema temporaneo del risolutore DNS.
lingfish,

4
Questa risposta non sembra avere senso in quanto in 'r' è l'oggetto che proviene da request.get () quindi con l'eccezione questo porta solo ad un altro errore.
mikkokotila,

Questa risposta non ha senso. L'errore di OP non dice "Connessione rifiutata", dice "Nome o servizio non conosciuti". Questa risposta sembra presupporre che tutti ConnectionError siano dovuti a "Connessione rifiutata".
erjiang,

1
Per me questo deve essere esattamente giusto, un limite di velocità posto dal server. Posso effettuare 80 chiamate e quindi questo messaggio verrà visualizzato per me. Quindi, dopo breve tempo, il server è disponibile per altre 80 chiamate e il ciclo si ripete. è troppo regolare per essere qualcos'altro.
demongolem,

122

Usa solo le requests'funzionalità:

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)

Questo sarà GETl'URL e riprovare 3 volte in caso di requests.exceptions.ConnectionError.backoff_factorcontribuirà ad applicare ritardi tra i tentativi di evitare di fallire nuovamente in caso di quota di richiesta periodica.

Dai un'occhiata requests.packages.urllib3.util.retry.Retry, ha molte opzioni per semplificare i tentativi.


Per qualsiasi motivo, questo non funziona su Windows 10. Ho avviato la shell python manage.py shelle sto usando session.get('http://localhost:8000/api/'). Qualsiasi aiuto? @Zulu
MwamiTovi il

ho risolto il problema. Avevo dimenticato di avviare il dev-servere mantenerlo attivo per primo.
MwamiTovi il

Perché non è ancora la risposta migliore?
Pavel Druzhinin,

Ho provato questo ma non ci avrei riprovato mentre sono scaduto il file request.exceptions.ConnectionError. ma ho impostato un timeout per la richiesta get.
Zagfai,

34

Fallo e basta

Incolla il seguente codice al posto di 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

Prego :)


3
ricordati di fare import time
Yuan Tao,

3
requestsha il suo codice per gestire il suo errore e riprovare
Zulu

5
Non esce mai dal loop. @jatin
Alper

11
Inoltre, non è una buona idea catturare qualsiasi tipo di eccezione (con except: ...) da requestse sleep()in risposta. Invece, dovrebbero catturare requests.exceptions.ConnectionErrore sleep()solo se si verifica quell'eccezione. (O meglio ancora, basta usare la Retry()classe requestsintegrata che viene fornita , come suggerito da @Zulu).
J. Taylor,


15

Ho avuto un problema simile ma il seguente codice ha funzionato per me.

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

"verifica = Falso" disabilita la verifica SSL. Try and catch può essere aggiunto come al solito.


5

È sempre bene implementare la gestione delle eccezioni. Non solo aiuta a evitare l'uscita imprevista dello script, ma può anche aiutare a registrare errori e notifiche di informazioni. Quando utilizzo le richieste Python, preferisco rilevare eccezioni come questa:

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

Qui rinnovIPadress () è una funzione definita dall'utente che può modificare l'indirizzo IP se viene bloccato. Puoi andare senza questa funzione.


la tua soluzione è carina ma come cambiare ip-adrressin Python, ne sai qualcosa, poi fammi sapere
Haritsinh Gohil

1
Avevo usato un servizio VPN IPVanish e Hide My Ass. Sono configurati usando open-vpn e open-vpn hanno una riga di comando della shell che rinnova l'indirizzo IP. Puoi chiamare il comando shell o bash da Python. In questo modo, puoi implementarlo.
Tanmoy Datta,

5

La specifica del proxy in un ambiente aziendale l'ha risolto per me.

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

L'errore completo è:

request.exceptions.ConnectionError: HTTPSConnectionPool (host = "www.google.com", porta = 80): numero massimo di tentativi superato con url: / (causato da NewConnectionError (': impossibile stabilire una nuova connessione: [WinError 10060] una connessione tentativo fallito perché la parte connessa non ha risposto correttamente dopo un certo periodo di tempo o la connessione stabilita non è riuscita perché l'host connesso non ha risposto '))


2

non sono riuscito a farlo funzionare su Windows anche dopo aver installato pyopenssl e aver provato varie versioni di Python (mentre funzionava bene su Mac), quindi sono passato a urllib e funziona su Python 3.6 (da Python .org) e 3.7 (Anaconda )

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

sono abbastanza seccato che le cose funzionino solo se eseguite con il prompt di Anaconda.
BingLi224,

1

Quando stavo scrivendo uno script di test del browser selenio, ho riscontrato questo errore durante la chiamata driver.quit()prima dell'uso di una chiamata API JS. Ricorda che chiudere Webdriver è l'ultima cosa da fare!


1

Aggiungendo la mia esperienza per coloro che stanno vivendo questo in futuro. Il mio errore specifico è stato

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

Si scopre che questo era in realtà perché avevo raggiunto il numero massimo di file aperti sul mio sistema. Non aveva nulla a che fare con le connessioni fallite o persino con un errore DNS come indicato.


0

Aggiungendo la mia esperienza:

r = requests.get(download_url)

quando ho provato a scaricare un file specificato nell'URL.

L'errore è stato

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

L'ho corretto aggiungendo verify = Falsela funzione come segue:

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

0

Controlla la tua connessione di rete. Ho avuto questo e la VM non aveva una connessione di rete corretta.


-1

Aggiungi intestazioni per questa richiesta.

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.