Превышено максимальное количество попыток с 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)

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, надеюсь, она решит вашу проблему.


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

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


3
не забудьте сделать import time
Юань Тао

3
requestsимеет свой собственный код для обработки своей ошибки и повторите попытку
Zulu

5
Он никогда не выходит из цикла. @jatin
Alper

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


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)


-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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.