Превышено максимальное количество попыток с URL в запросах

153

Я пытаюсь получить контент из App Store> Бизнес :

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)этим работает, но когда я помещаю rangeв 100s, он показывает эту ошибку:

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)
user3446000
источник
1
Разве вы не должны использовать iпеременную где-то в for?
Лоран С.
вы как бы запрашиваете одно и то же приложение 100 раз. для чего это ?
njzk2
Я использую я в остальной части кода. Я не выложил весь код
user3446000
Я не запрашиваю одно и то же приложение 100 раз. Я запрашиваю 100 разных приложений в одной категории.
user3446000
3
Похоже, ваш DNS-распознаватель не может разрешить itunes.apple.com. Можете ли вы запустить dig itunes.apple.comв командной строке и опубликовать результаты здесь?
Томас Орозко

Ответы:

141

Здесь произошло то, что сервер itunes отклонил ваше соединение (вы отправляете слишком много запросов с одного и того же IP-адреса за короткий промежуток времени)

Максимальное количество повторных попыток превышено с помощью URL: / в / app / adobe-reader / id469337564? Mt = 8

след ошибка в заблуждение это должно быть что - то вроде «Нет соединения может быть сделано , потому что целевая машина активно отказалась от него» .

Существует проблема примерно в python.requests lib на Github, посмотрите здесь

Чтобы преодолеть эту проблему (не столько проблему, сколько вводящую в заблуждение трассировку отладки), вы должны перехватывать исключения, связанные с подключением, например:

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

Другой способ преодоления этой проблемы - если вы используете достаточный промежуток времени для отправки запросов на сервер, это может быть достигнуто с помощью sleep(timeinsec)функции в python (не забудьте импортировать sleep)

from time import sleep

В общем, все запросы - это потрясающая библиотека Python, надеюсь, она решит вашу проблему.

djra
источник
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, и служба не была числовой строкой номера порта. Вероятно, это выглядело так, как будто это исправило сон, но вы, вероятно, только что спали из-за временной проблемы с преобразователем DNS.
lingfish
4
Этот ответ, по-видимому, не имеет смысла, так как в 'r' это объект, который приходит из request.get (), поэтому, за исключением, это просто приводит к другой ошибке.
Миккокотила
Этот ответ не имеет смысла. Ошибка OP не говорит «Соединение отказано», она говорит «Имя или служба не известны». Этот ответ, по-видимому, предполагает, что все ошибки ConnectionError вызваны «Отказ в соединении».
erjiang
1
Для меня это должно быть точно, ограничение скорости, установленное сервером. Я могу сделать 80 звонков, и тогда это сообщение появится для меня. Затем через короткое время серверу доступно еще 80 звонков и цикл повторяется. это слишком регулярно, чтобы быть чем-то еще.
демонголем
123

Просто используйте 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)

Это будет GETURL и повторите 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
Почему это все еще не лучший ответ?
Павел Дружинин
Я пробовал это, но он не будет повторяться, пока я получаю request.exceptions.ConnectionError Тайм-аут чтения. но я установил таймаут для запроса на получение.
Загфай
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

Пожалуйста :)

Jatin
источник
3
не забудьте сделать import time
Юань Тао
3
requestsимеет свой собственный код для обработки своей ошибки и повторите попытку
Zulu
5
Он никогда не выходит из цикла. @jatin
Alper
11
Кроме того, не очень хорошая идея просто перехватывать любые типы исключений (с except: ...) от requestsи sleep()в ответ. Вместо этого они должны ловить requests.exceptions.ConnectionErrorи sleep()только если это исключение происходит. (Или, что еще лучше, просто используйте встроенный Retry()класс, который поставляется вместе requestsс @Zulu).
Дж. Тейлор
32

pip install pyopenssl казалось, решил это для меня.

https://github.com/requests/requests/issues/4246

Akshar
источник
1
Помог мне выяснить, SSL - это моя проблема
MilaDroid
То же самое здесь =) Спасибо!
Родриго Э. Принсипи
16

Я получил похожую проблему, но следующий код работал для меня.

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, знаете ли вы что-нибудь об этом, а затем дайте мне знать
Харицин Гохил
1
Я использовал VPN-сервис IPVanish и Hide My Ass. Они настроены с использованием open-vpn и open-vpn, в командной строке оболочки обновляется IP-адрес. Вы можете вызвать команду shell или bash из python. Таким образом, вы можете реализовать это.
Танмой Датта
5

Определение прокси в корпоративной среде решило это за меня.

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

Полная ошибка:

request.exceptions.ConnectionError: HTTPSConnectionPool (host = 'www.google.com', port = 80): превышено максимальное количество попыток с URL: / (вызвано NewConnectionError (': не удалось установить новое соединение: [WinError 10060] Соединение попытка не удалась, потому что подключенная сторона не ответила должным образом через некоторое время, или не удалось установить соединение, потому что подключенный хост не смог ответить '))

Джереми Томпсон
источник
2

я не смог заставить его работать на windows даже после установки pyopenssl и пробовать разные версии python (хотя он нормально работал на 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()перед использованием вызова API JS. Помните, что выход из веб-драйвера - это последнее, что нужно сделать!

Салех
источник
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)
Сурадж Субраманян
источник
0

Проверьте подключение к сети. У меня было это, и у VM не было надлежащего сетевого подключения.

Тимоти К. Куинн
источник
-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)
Майкл Ян
источник