Максимальна кількість спроб перевищена в 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)нею працює, але коли я поставив rangeв 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?
Лоран С.

ви ніби запитуєте одну і ту ж програму 100 разів. для чого це?
njzk2

Я використовую i в решті коду. Я не опублікував весь код
користувач3446000

Я не надсилаю запит на те саме додаток 100 разів. Я запитую 100 різних додатків під тією ж категорією.
користувач3446000

3
Схоже, ваш DNS-розв’язник не вдається вирішити itunes.apple.com. Чи можете ви запустити dig itunes.apple.comу своєму командному рядку та опублікувати результати тут?
Томас Орозько

Відповіді:


141

Тут сталося те, що сервер itunes відмовляється від вашого з'єднання (ви надсилаєте занадто багато запитів з однієї ip адреси за короткий проміжок часу)

Максимальна кількість спроб перевищена за URL: / in / 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 (не забудьте імпортувати сон)

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, і служба не була числовим рядком номера порту. Напевно, це виглядало так, що сон це виправив, але ви, ймовірно, просто проспали через перехідну проблему DNS для вирішення.
lingfish

4
Ця відповідь, мабуть, не має сенсу, оскільки "r" - це об'єкт, що надходить з request.get (), тому, за винятком, це призводить до чергової помилки.
mikkokotila

Ця відповідь не має сенсу. Помилка OP не говорить "З'єднання відмовлено", а "Ім'я або послуга невідомі". Здається, ця відповідь передбачає, що всі ConnectionError пов'язані з "Відмовою у відключенні".
erjiang

1
Для мене це має бути абсолютно правильним, обмеження швидкості, встановлене сервером. Я можу здійснити 80 дзвінків, і тоді це повідомлення з’явиться для мене. Потім через короткий час сервер стає доступним ще 80 дзвінків і цикл повторюється. це занадто регулярно, щоб бути чим-небудь іншим.
демонголем

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)

Це буде 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 Read. але я встановив тайм-аут для запиту на отримання.
Загфай

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()лише якщо це виняток трапляється. (Або ще краще, просто використовуйте вбудований Retry()клас, який поставляється разом requestsіз пропозицією @Zulu).
Дж. Тейлор


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-adrresspython, чи знаєте ви щось про це, тоді дайте мені знати
Харіцин Гохіль

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()перед використанням виклику 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.