リクエストの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)、それは動作しますが、私が置いたときrange100、Sはこのエラーを示しています。

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. 14

同じアプリを100回リクエストするようなものです。それは何のためにあるのです ?
njzk2 14

残りのコードでiを使用しています。コード全体を投稿していません
user3446000 14

同じアプリを100回リクエストしていません。同じカテゴリの100種類のアプリをリクエストしています。
user3446000 14

3
DNSリゾルバが解決できないようitunes.apple.comです。dig itunes.apple.comコマンドラインで実行して、結果をここに投稿できますか?
Thomas Orozco 2014

回答:


139

ここで起こったことは、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)pythonの関数によって実現できます(sleepをインポートすることを忘れないでください)

from time import sleep

すべてのリクエストはすべて素晴らしいpython libです。問題が解決されることを願っています。


2
スリープループは私の問題を修正しました-少しハックですが、エラー応答を処理している間に数回ループすることで、私は解決策を総当たりすることができました。
elPastor 2017年

14
この答えは実際には間違っています。これは、(Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)パーツで示されているように、リゾルバルックアップの問題です。「gai」はの略でgetaddrinfo、関連する可能性のあるエラーは次のとおりです 。EAI_NONAMEノードまたはサービスが不明です。または、ノードとサービスの両方がNULLです。またはAI_NUMERICSERVがhints.ai_flagsで指定され、サービスが数値のポート番号文字列ではありませんでした。おそらく、スリープによって修正されたように見えますが、一時的なDNSリゾルバーの問題が原因で眠っていた可能性があります。
リンフィッシュ2017

4
'r'は、requests.get()からのオブジェクトであるため、この回答は意味をなさないようです。このため、例外として、別のエラーが発生します。
mikkokotila

この答えは意味がありません。OPのエラーは「接続が拒否されました」ではなく、「名前またはサービスが不明です」と表示されます。この回答は、すべてのConnectionErrorが「接続拒否」によるものであると想定しているようです。
erjiang

1
私にとって、これは正確である必要があり、サーバーによって設定されたレート制限です。80件の電話をかけると、このメッセージが表示されます。その後、しばらくすると、サーバーはさらに80回の呼び出しに使用できるようになり、サイクルが繰り返されます。それは他の何かになるには規則的すぎる。
demongolem

121

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/')ます。何か助け?@Zulu
MwamiTovi

問題を整理しました。を起動dev-serverして最初に実行し続けることを忘れていました。
MwamiTovi

なぜそれがまだ最善の答えではないのですか?
Pavel Druzhinin

私はこれを試しましたが、requests.exceptions.ConnectionError読み取りがタイムアウトした間は再試行しませんでした。しかし、私はgetリクエストのタイムアウトを設定しました。
ザグファイ

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エラーを処理して再試行する独自のコードがあります
Zulu

5
ループから抜け出すことはありません。@jatin
alper

10
また、ではない良いアイデアはちょうど(と例外のいずれかのタイプをキャッチするexcept: ...から)requestssleep()応答。その代わり、彼らがキャッチしなければならないrequests.exceptions.ConnectionErrorsleep()、その例外が発生した場合にのみ。(さらに良いことに、@ Zuluで提案されているように、にRetry()付属する組み込みクラスを使用するだけrequestsです)。
J.テイラー


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とHide My Assを使用していました。それらはopen-vpnを使用して設定され、open-vpnは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

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.