요청시 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

나머지 코드에서 i를 사용하고 있습니다. 전체 코드를 게시하지 않았습니다
user3446000 April

같은 앱을 100 번 요청하지 않습니다. 같은 카테고리에서 100 개의 서로 다른 앱을 요청하고 있습니다.
user3446000

3
DNS 확인자가 확인할 수없는 것 같습니다 itunes.apple.com. dig itunes.apple.com명령 행에서 실행 하여 결과를 여기에 게시 할 수 있습니까?
Thomas Orozco

답변:


141

여기서 일어난 일은 itunes 서버가 연결을 거부 한다는 것입니다 (짧은 시간에 동일한 IP 주소에서 너무 많은 요청을 보내고 있습니다)

URL에서 최대 재시도 횟수를 초과했습니다 : / 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)파이썬 기능 으로 달성 할 수 있습니다 (수면을 가져 오는 것을 잊지 마십시오)

from time import sleep

모든 요청에서 모두 훌륭한 파이썬 라이브러리입니다. 문제가 해결되기를 바랍니다.


2
수면 루프는 약간의 해킹으로 문제를 해결했지만 오류 응답을 처리하는 동안 몇 번 반복하여 솔루션을 무력화시킬 수있었습니다.
elPastor

14
이 답변은 실제로 잘못되었습니다. (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)부품에 표시된대로 리졸버 조회 문제 입니다. "gai"는의 약자이며 getaddrinfo가능한 관련 오류는 다음과 같습니다. EAI_NONAME 노드 또는 서비스를 알 수 없습니다. 또는 노드와 서비스가 모두 NULL입니다. 또는 AI_NUMERICSERV가 hints.ai_flags에 지정되었으며 service는 숫자 포트 번호 문자열이 아닙니다. 수면이 문제를 해결 한 것처럼 보이지만 일시적인 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.ConnectionError됩니다. backoff_factor정기적 인 요청 할당량의 경우 다시 실패하지 않도록 시도 사이에 지연을 적용하는 데 도움이됩니다.

한 번 봐 requests.packages.urllib3.util.retry.Retry, 그것은 단순화 시도 할 수있는 여러 가지 옵션이 있습니다.


어떤 이유로 든 이것은 Windows 10에서 작동하지 않습니다 .을 python manage.py shell사용하여 셸을 시작하고 사용 중 session.get('http://localhost:8000/api/')입니다. 어떤 도움? @Zulu
MwamiTovi

내 문제가 정렬되었습니다. 시작하고 잊어 버린 것을 잊어 버렸습니다 dev-server.
MwamiTovi

여전히 최선의 대답이 아닌 이유는 무엇입니까?
Pavel Druzhinin

나는 이것을 시도했지만 requests.exceptions.ConnectionError 읽기 시간이 초과되는 동안 다시 시도하지 않습니다. 그러나 get 요청에 대한 시간 초과를 설정했습니다.
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
Yuan Tao

3
requests그 오류 및 재시도 처리 할 수있는 자신의 코드가
줄루어

5
루프에서 나가지 않습니다. @jatin
alper

10
또한, 좋은 생각은 (와 예외의 모든 유형을 잡으려고 except: ...에서) requestssleep()응답. 대신, 그들은 잡을해야 requests.exceptions.ConnectionError하고 sleep()그 예외가 발생했을 경우에만 가능합니다. 또는 @Zulu가 제안한대로 내장 Retry()클래스를 사용하십시오 requests.
J. Taylor


15

비슷한 문제가 있지만 다음 코드가 저에게 효과적이었습니다.

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

"verify = False"는 SSL 확인을 비활성화합니다. 평소처럼 try and catch를 추가 할 수 있습니다.


5

항상 예외 처리를 구현하는 것이 좋습니다. 예기치 않은 스크립트 종료를 피할뿐만 아니라 오류 및 정보 알림을 기록하는 데 도움이됩니다. 파이썬 요청을 사용할 때 다음과 같은 예외를 잡는 것을 선호합니다.

    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파이썬에서 변경하는 방법에 대해 알고 있습니까?
Haritsinh Gohil

1
나는 VPN 서비스 IPVanish와 Hide My Ass를 사용했다. open-vpn을 사용하여 구성되며 open-vpn에는 IP 주소를 갱신하는 쉘 명령 행이 있습니다. 파이썬에서 쉘 또는 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을 설치하고 다양한 파이썬 버전을 시도한 후에도 Windows에서 작동하지 못했습니다 (Mac에서는 정상적으로 작동했지만) 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

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.