Thử lại tối đa vượt quá với URL trong yêu cầu


151

Tôi đang cố gắng để có được nội dung của 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)

Khi tôi thử rangevới (0,2)nó hoạt động, nhưng khi tôi đặt rangetại 100s nó cho thấy lỗi này:

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
Bạn không nên sử dụng ibiến ở đâu đó trong for?
Laurent S.

bạn giống như yêu cầu cùng một ứng dụng 100 lần. cái đó để làm gì
njzk2

Tôi đang sử dụng i trong phần còn lại của mã. Tôi chưa đăng toàn bộ mã
user3446000

Tôi không yêu cầu cho cùng một ứng dụng 100 lần. Tôi đang yêu cầu 100 ứng dụng khác nhau trong cùng một danh mục.
dùng3446000

3
Có vẻ như trình phân giải DNS của bạn không thể giải quyết itunes.apple.com. Bạn có thể chạy dig itunes.apple.comở dòng lệnh của bạn và gửi kết quả ở đây?
Thomas Orozco

Câu trả lời:


139

Điều xảy ra ở đây là máy chủ itunes từ chối kết nối của bạn (bạn đang gửi quá nhiều yêu cầu từ cùng một địa chỉ IP trong khoảng thời gian ngắn)

Thử lại tối đa vượt quá với url: / in / app / adobe-reader / id469337564? Mt = 8

theo dõi lỗi là sai lệch, nó phải là một cái gì đó như "Không thể kết nối được vì máy đích đã chủ động từ chối nó" .

Có một vấn đề về khoảng python.requests lib tại Github, hãy kiểm tra nó ở đây

Để khắc phục vấn đề này (không quá nhiều vấn đề vì đây là dấu vết gỡ lỗi sai), bạn nên nắm bắt các ngoại lệ liên quan đến kết nối như vậy:

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

Một cách khác để khắc phục vấn đề này là nếu bạn sử dụng đủ khoảng cách thời gian để gửi yêu cầu đến máy chủ thì điều này có thể đạt được bằng sleep(timeinsec)chức năng trong python (đừng quên nhập giấc ngủ)

from time import sleep

Tất cả trong tất cả các yêu cầu là lib python tuyệt vời, hy vọng rằng sẽ giải quyết vấn đề của bạn.


2
Vòng lặp ngủ đã khắc phục vấn đề của tôi - một chút hack, nhưng bằng cách lặp lại một vài lần trong khi xử lý phản hồi lỗi, tôi đã có thể bắt bẻ một giải pháp.
elPastor

14
Câu trả lời này thực sự sai. Đây là một vấn đề tra cứu trình giải quyết, như được chỉ ra bởi (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)một phần. "Gai" là viết tắt của getaddrinfo, và lỗi liên quan có thể xảy ra là: EAI_NONAME Nút hoặc dịch vụ không được biết; hoặc cả nút và dịch vụ là NULL; hoặc AI_NUMERICSERV đã được chỉ định trong gợi ý.ai_flags và dịch vụ không phải là chuỗi số cổng số. Nó có thể trông giống như giấc ngủ đã sửa nó, nhưng có lẽ bạn chỉ ngủ qua một vấn đề trình giải quyết DNS thoáng qua.
cá đuối

4
Câu trả lời này dường như không có ý nghĩa vì trong 'r' là đối tượng xuất phát từ request.get () vì vậy ngoại trừ điều này chỉ dẫn đến một lỗi khác.
mikkokotila

Câu trả lời này không có ý nghĩa. Lỗi của OP không nói "Kết nối bị từ chối", nó báo "Tên hoặc dịch vụ không được biết". Câu trả lời này dường như cho rằng tất cả ConnectionError là do "Kết nối bị từ chối".
erjiang

1
Đối với tôi điều này phải hoàn toàn chính xác, giới hạn tốc độ được đặt bởi máy chủ. Tôi có thể thực hiện 80 cuộc gọi và sau đó tin nhắn này sẽ xuất hiện cho tôi. Sau một thời gian ngắn, máy chủ có sẵn cho 80 cuộc gọi khác và chu kỳ lặp lại. nó là quá thường xuyên để là bất cứ điều gì khác.
demongolem

121

Chỉ cần sử dụng requests'các tính năng:

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)

Điều này sẽ GETURL và thử lại 3 lần trong trường hợp requests.exceptions.ConnectionError. backoff_factorsẽ giúp áp dụng sự chậm trễ giữa các lần thử để tránh thất bại một lần nữa trong trường hợp hạn ngạch yêu cầu định kỳ.

Hãy xem requests.packages.urllib3.util.retry.Retry, nó có nhiều tùy chọn để đơn giản hóa thử lại.


Vì lý do nào, điều này không hoạt động trên windows 10. Bắt đầu python manage.py shellsử dụng và đang sử dụng session.get('http://localhost:8000/api/'). Có ai giúp đỡ không? @Zulu
MwamiTovi

vấn đề của tôi được sắp xếp. Đã quên để bắt đầu dev-servervà giữ cho nó chạy đầu tiên.
MwamiTovi

Tại sao nó vẫn không trả lời tốt nhất?
Pavel Druzhinin

Tôi đã thử điều này nhưng nó sẽ không thử lại trong khi tôi nhận được request.exceptions.ConnectionError Đọc đã hết thời gian. nhưng tôi đặt thời gian chờ cho yêu cầu nhận.
Wapfai

34

Chỉ cần làm điều này

Dán đoạn mã sau vào vị trí 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

Không có gì :)


3
nhớ làm import time
Yuan Tao

3
requestscó mã riêng để xử lý lỗi và thử lại
Zulu

5
Nó không bao giờ thoát ra khỏi vòng lặp. @jatin
alper

10
Ngoài ra, không phải là một ý tưởng tốt để chỉ bắt bất kỳ loại ngoại lệ (với except: ...) từ requestssleep()trong phản ứng. Thay vào đó, họ nên bắt requests.exceptions.ConnectionErrorsleep()chỉ khi ngoại lệ đó xảy ra. (Hoặc tốt hơn nữa, chỉ cần sử dụng Retry()lớp dựng sẵn đi kèm requests, như được đề xuất bởi @Zulu).
J. Taylor


15

Tôi gặp vấn đề tương tự nhưng đoạn mã sau làm việc cho tôi.

url = <some REST url>    
page = requests.get(url, verify=False)

"xác minh = sai" vô hiệu hóa xác minh SSL. Hãy thử và bắt có thể được thêm vào như bình thường.


5

Nó luôn luôn tốt để thực hiện xử lý ngoại lệ. Nó không chỉ giúp tránh việc thoát khỏi tập lệnh bất ngờ mà còn có thể giúp ghi nhật ký lỗi và thông báo thông tin. Khi sử dụng các yêu cầu Python, tôi thích bắt các ngoại lệ như thế này:

    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")

Ở đây refreshIPadress () là một hàm xác định người dùng có thể thay đổi địa chỉ IP nếu nó bị chặn. Bạn có thể đi mà không có chức năng này.


Giải pháp của bạn rất hay nhưng làm thế nào để thay đổi ip-adrresscon trăn, bạn có biết gì về nó không, sau đó cho tôi biết
Haritsinh Gohil

1
Tôi đã sử dụng một số dịch vụ VPN IPV Biến và Ẩn My Ass. Chúng được cấu hình bằng open-vpn và open-vpn có hàng lệnh shell làm mới địa chỉ IP. Bạn có thể gọi lệnh shell hoặc bash từ python. Bằng cách này, bạn có thể thực hiện nó.
Tanmoy Datta

5

Việc chỉ định proxy trong môi trường doanh nghiệp đã giải quyết nó cho tôi.

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

Lỗi đầy đủ là:

quiries cố gắng thất bại vì bên được kết nối không phản hồi đúng sau một khoảng thời gian hoặc kết nối được thiết lập không thành công vì máy chủ được kết nối không phản hồi '))


2

Tôi không thể làm cho nó hoạt động trên windows ngay cả sau khi cài đặt pyopenssl và thử các phiên bản python khác nhau (trong khi nó hoạt động tốt trên mac), vì vậy tôi đã chuyển sang urllib và nó hoạt động trên python 3.6 (từ python .org) và 3.7 (anaconda )

import urllib 
from urllib.request import urlopen
html = urlopen("http://pythonscraping.com/pages/page1.html")
contents = html.read()
print(contents)

Tôi khá bực mình vì mọi thứ chỉ hoạt động nếu chạy với dấu nhắc Anaconda.
BingLi224

1

Khi tôi đang viết một kịch bản kiểm tra trình duyệt selen, tôi đã gặp phải lỗi này khi gọi driver.quit()trước khi sử dụng một cuộc gọi api của JS. Hãy nhớ rằng việc thoát khỏi webdo là việc cuối cùng cần làm!


1

Thêm kinh nghiệm của riêng tôi cho những người đang trải nghiệm điều này trong tương lai. Lỗi cụ thể của tôi là

Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'

Hóa ra điều này thực sự là do tôi đã đạt đến số lượng tệp mở tối đa trên hệ thống của mình. Nó không có gì để làm với các kết nối không thành công, hoặc thậm chí là lỗi DNS như được chỉ ra.


0

Thêm kinh nghiệm của riêng tôi:

r = requests.get(download_url)

khi tôi cố tải xuống một tệp được chỉ định trong url.

Lỗi là

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')])")))

Tôi đã sửa nó bằng cách thêm verify = Falsevào hàm như sau:

r = requests.get(download_url + filename)
open(filename, 'wb').write(r.content)

-1

Thêm tiêu đề cho yêu cầu này.

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.