requests.get ()이 반환되지 않는 이유는 무엇입니까? requests.get ()이 사용하는 기본 시간 제한은 무엇입니까?
내 스크립트에서 requests.get
절대 반환하지 않습니다.
import requests
print ("requesting..")
# This call never returns!
r = requests.get(
"http://www.justdial.com",
proxies = {'http': '222.255.169.74:8080'},
)
print(r.ok)
가능한 이유는 무엇입니까? 치료법이 있습니까? get
사용 하는 기본 제한 시간은 무엇입니까 ?
사용되는 기본 시간 제한은 무엇입니까?
기본 제한 시간은 None
연결이 닫힐 때까지 대기 (중단)됨을 의미합니다.
시간 초과 값을 전달하면 어떻게됩니까?
r = requests.get(
'http://www.justdial.com',
proxies={'http': '222.255.169.74:8080'},
timeout=5
)
에서 요청 문서 :
timeout 매개 변수를 사용하여 지정된 시간 (초) 후에 응답 대기를 중지하도록 Requests에 지시 할 수 있습니다.
>>> requests.get('http://github.com', timeout=0.001) Traceback (most recent call last): File "<stdin>", line 1, in <module> requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
노트 :
시간 제한은 전체 응답 다운로드에 대한 시간 제한이 아닙니다. 오히려 서버가 timeout 초 동안 응답을 발행하지 않은 경우 (더 정확하게는 timeout 초 동안 기본 소켓에 수신 된 바이트가없는 경우) 예외가 발생합니다.
requests.get () timeout
이 1 초라도 반환하는 데 시간이 너무 오래 걸리는 일이 많이 발생합니다 . 이 문제를 극복하는 몇 가지 방법이 있습니다.
1. TimeoutSauce
내부 클래스 사용
출처 : https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
import requests from requests.adapters import TimeoutSauce class MyTimeout(TimeoutSauce): def __init__(self, *args, **kwargs): if kwargs['connect'] is None: kwargs['connect'] = 5 if kwargs['read'] is None: kwargs['read'] = 5 super(MyTimeout, self).__init__(*args, **kwargs) requests.adapters.TimeoutSauce = MyTimeout
이 코드는 우리가 Session.get () 호출에 전달하는 타임 아웃 값인 연결 타임 아웃과 동일하게 읽기 타임 아웃을 설정하게합니다. (실제로이 코드를 테스트하지 않았으므로 빠른 디버깅이 필요할 수 있습니다. 방금 GitHub 창에 직접 작성했습니다.)
2. kevinburke의 요청 포크 사용 : https://github.com/kevinburke/requests/tree/connect-timeout
설명서에서 : https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
다음과 같이 제한 시간에 단일 값을 지정하는 경우 :
r = requests.get('https://github.com', timeout=5)
제한 시간 값은 연결 및 읽기 제한 시간 모두에 적용됩니다. 값을 개별적으로 설정하려면 튜플을 지정하십시오.
r = requests.get('https://github.com', timeout=(3.05, 27))
참고 : 이후 변경 사항이 기본 요청 프로젝트에 병합되었습니다 .
3. 유사한 질문에서 이미 언급했듯이 evenlet
또는 사용 signal
: python requests.get 전체 응답에 대한 시간 초과
모든 답변을 검토하고 문제가 여전히 존재한다는 결론에 도달했습니다. 일부 사이트에서는 요청이 무한히 멈출 수 있으며 다중 처리를 사용하는 것은 과도한 것 같습니다. 내 접근 방식 (Python 3.5 이상)은 다음과 같습니다.
import asyncio
import aiohttp
async def get_http(url):
async with aiohttp.ClientSession(conn_timeout=1, read_timeout=3) as client:
try:
async with client.get(url) as response:
content = await response.text()
return content, response.status
except Exception:
pass
loop = asyncio.get_event_loop()
task = loop.create_task(get_http('http://example.com'))
loop.run_until_complete(task)
result = task.result()
if result is not None:
content, status = task.result()
if status == 200:
print(content)
기본 제한 시간을 코드 묶음에 쉽게 추가하고 싶었습니다 (시간 제한이 문제를 해결한다고 가정)
이것이 요청 저장소에 제출 된 티켓에서 선택한 솔루션입니다.
크레딧 : https://github.com/kennethreitz/requests/issues/2011#issuecomment-477784399
해결책은 여기 마지막 두 줄이지 만 더 나은 컨텍스트를 위해 더 많은 코드를 보여줍니다. 재시도 동작을 위해 세션을 사용하고 싶습니다.
import requests
import functools
from requests.adapters import HTTPAdapter,Retry
def requests_retry_session(
retries=10,
backoff_factor=2,
status_forcelist=(500, 502, 503, 504),
session=None,
) -> requests.Session:
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
# set default timeout
for method in ('get', 'options', 'head', 'post', 'put', 'patch', 'delete'):
setattr(session, method, functools.partial(getattr(session, method), timeout=30))
return session
그러면 다음과 같이 할 수 있습니다.
requests_session = requests_retry_session()
r = requests_session.get(url=url,...
'code' 카테고리의 다른 글
WAMPServer의 Windows 명령 줄에서 PHP를 실행하는 방법 (0) | 2020.10.12 |
---|---|
Angularjs 단순 파일 다운로드로 인해 라우터가 리디렉션 됨 (0) | 2020.10.12 |
유 방향 그래프가 비순환인지 어떻게 확인합니까? (0) | 2020.10.12 |
구문 분석을 사용하여 문자열을 모든 유형으로 변환하는 일반 Parse () 함수가 있습니까? (0) | 2020.10.12 |
PHP로 작성된 괜찮은 PHP 파서가 있습니까? (0) | 2020.10.12 |