Python 请求挂起/冻结

新手上路,请多包涵

我正在使用请求库从某处获取大量网页。他是相关代码:

 response = requests.Session()
retries = Retry(total=5, backoff_factor=.1)
response.mount('http://', HTTPAdapter(max_retries=retries))
response = response.get(url)

一段时间后,它在获取页面时只是挂起/冻结(从不在同一网页上)。这是我中断它时的回溯:

 File "/Users/Student/Hockey/Scrape/html_pbp.py", line 21, in get_pbp
  response = r.read().decode('utf-8')
File "/anaconda/lib/python3.6/http/client.py", line 456, in read
  return self._readall_chunked()
File "/anaconda/lib/python3.6/http/client.py", line 566, in _readall_chunked
  value.append(self._safe_read(chunk_left))
File "/anaconda/lib/python3.6/http/client.py", line 612, in _safe_read
  chunk = self.fp.read(min(amt, MAXAMOUNT))
File "/anaconda/lib/python3.6/socket.py", line 586, in readinto
  return self._sock.recv_into(b)
KeyboardInterrupt

有人知道是什么原因造成的吗?或者(更重要的是)如果需要超过一定时间,有人知道阻止它的方法以便我可以重试吗?

原文由 Hobbit36 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 437
2 个回答

似乎设置(读取) 超时 可能对您有所帮助。

类似的东西:

 response = response.get(url, timeout=5)

(这会将连接和读取超时设置为 5 秒。)

requests 中,不幸的是,默认情况下既没有设置 连接 超时也没有设置 读取 超时,即使 文档 说设置它很好:

大多数对外部服务器 的请求都应该附加超时,以防服务器没有及时响应。默认情况下,除非明确设置超时值,否则请求不会超时。如果没有超时,您的代码可能会挂起几分钟或更长时间。

只是为了完整起见, 连接超时 是秒数 requests 将等待您的客户端与远程计算机建立连接, 读取超时 是客户端从发送的字节之间等待的秒数服务器。

原文由 randomir 发布,翻译遵循 CC BY-SA 3.0 许可协议

修补记录的“发送”功能将为所有请求修复此问题 - 即使在许多依赖库和 sdk 中也是如此。修补库时,一定要修补支持/记录的功能,否则你可能会默默地失去补丁的效果。

 import requests

DEFAULT_TIMEOUT = 180

old_send = requests.Session.send

def new_send(*args, **kwargs):
     if kwargs.get("timeout", None) is None:
         kwargs["timeout"] = DEFAULT_TIMEOUT
     return old_send(*args, **kwargs)

requests.Session.send = new_send

没有任何超时的影响非常严重,使用默认超时几乎不会破坏任何东西——因为 TCP 本身也有超时。

在 Windows 上,默认 TCP 超时为 240 秒,TCP RFC 建议 RTO* 重试至少为 100 秒。该范围内的某处是安全的默认值。

原文由 Erik Aronesty 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题