요청시 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: ...에서) requests및 sleep()응답. 대신, 그들은 잡을해야 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.