【问题标题】:Python requests timeout not suitable when sites stream当网站流式传输时,Python 请求超时不合适
【发布时间】:2017-09-05 19:09:00
【问题描述】:

以下内容适用于 99.999% 的网站,但随机找到一个不适用的网站:

import requests
requests.get('http://arboleascity.com',timeout=(5,5),verify=False)

我已就该项目提出问题。

https://github.com/requests/requests/issues/4276

有什么建议或想法吗?

我在concurrent.futures.ThreadPoolExecutor 中运行它,所以我真的不想添加一些外部的东西,比如小事件或信号。但对任何运作良好的东西都持开放态度。

【问题讨论】:

  • 页面是否非常/无限长?
  • 去吧,我看不出这个网站有什么问题。加载速度超快、内容相当小的内容。
  • 卷曲它,我永远看不到它结束。看起来页面以 8 kBps 无休止地传输
  • 如果您是“随机查找”网站,如果您根本不知道要下载什么样的数据,您可能需要更多的遏制措施。

标签: python python-3.x python-requests


【解决方案1】:

它流式传输 SHOUTcast 流(内容类型:audio/aacp),因此没有超时,它永远不会停止流式传输。

如果您想要主页而不是流,请将 User-Agent 标头设置为类似于浏览器的内容。如果您想要音频流,请使用 stream=True 并迭代内容 - 如果需要,您也可以在此处退出。

如果您正在编写爬虫,您可能希望在尝试获取分块的响应之前检查 HEAD 请求中的内容类型。

【讨论】:

  • 你好,谢谢!虽然可能需要实现一些更强大的东西。
【解决方案2】:

他们都在工作exactly as documented

连接超时是请求将等待您的客户端与套接字上的远程机器(对应于 connect())调用建立连接的秒数。最好将连接超时设置为略大于 3 的倍数,这是默认的 TCP 数据包重传窗口。

一旦您的客户端连接到服务器并发送 HTTP 请求,读取超时就是客户端等待服务器发送响应的秒数。 (具体来说,它是客户端在从服务器发送的字节之间等待的秒数。在 99.9% 的情况下,这是服务器发送第一个字节之前的时间)。

【讨论】:

  • 谢谢,很高兴知道。所以我的问题标题错误地与我的问题相关联,但并没有真正帮助我,仍然投票赞成,因为你说的是​​真的。
【解决方案3】:

问题不在于requests,而在于您访问该特定网站的方式。

也就是说,http://arboleascity.com 似乎使用 User-Agent 标头字段来区分浏览器和音乐播放器。

如果您使用有效的浏览器签名,它只会返回页面 HTML (text/html) 并关闭连接:

$ curl -vvv -A 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0' http://arboleascity.com >/dev/null
...
< Content-Type: text/html;charset=utf-8
...
100   118    0   118    0     0    297      0 --:--:-- --:--:-- --:--:--   297
* Connection #0 to host arboleascity.com left intact

但是,如果您未定义 User-Agent(默认值),则该站点以 ~8kbps 的速度传输二进制内容 (audio/aacp):

$ curl -vvv http://arboleascity.com >/dev/null
...
< Content-Type: audio/aacp
...
< icy-notice1: <BR>This stream requires <a href="http://www.winamp.com">Winamp</a><BR>
< icy-notice2: SHOUTcast DNAS/posix(linux x64) v2.5.1.724<BR>
...
100  345k    0  345k    0     0  26975      0 --:--:--  0:00:13 --:--:--  7118^C

或者,with requests

>>> headers = {'user-agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0'}
>>> r = requests.get('http://arboleascity.com', headers=headers)

【讨论】:

  • 谢谢,你是对的,虽然类似于antii,但这并没有真正帮助我。尽管如此赞成,但仍然受到赞赏。
  • 关于如何防止使用请求流式传输的任何建议?
  • 如果您想处理流式传输的情况(限制接收的内容大小),请参阅链接的possible duplicate
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 2019-07-02
  • 2021-11-22
相关资源
最近更新 更多