使用 urllib2 或任何其他 http 库读取超时

2024-04-04

我有用于读取这样的网址的代码:

from urllib2 import Request, urlopen
req = Request(url)
for key, val in headers.items():
    req.add_header(key, val)
res = urlopen(req, timeout = timeout)
# This line blocks
content = res.read()

超时适用于 urlopen() 调用。但随后代码进入 res.read() 调用,我想在其中读取响应数据,并且此处未应用超时。因此,读取调用可能几乎永远挂起,等待来自服务器的数据。我发现的唯一解决方案是使用信号来中断 read() ,这不适合我,因为我正在使用线程。

还有什么其他选择? Python 是否有处理读取超时的 HTTP 库?我查看了 httplib2 和 requests,它们似乎遇到了与上面相同的问题。我不想使用套接字模块编写自己的非阻塞网络代码,因为我认为应该已经有一个用于此目的的库。

Update:以下解决方案都不适合我。您可以亲自看到,在下载大文件时,设置套接字或 urlopen 超时没有任何效果:

from urllib2 import urlopen
url = 'http://iso.linuxquestions.org/download/388/7163/http/se.releases.ubuntu.com/ubuntu-12.04.3-desktop-i386.iso'
c = urlopen(url)
c.read()

至少在使用 Python 2.7.3 的 Windows 上,超时被完全忽略。


如果不通过线程或其他方式使用某种异步计时器,任何库都不可能做到这一点。原因是,timeout参数使用于httplib, urllib2和其他库设置timeout在底层的socket。这实际上做了什么解释在文档 http://pubs.opengroup.org/onlinepubs/009695399/functions/setsockopt.html.

SO_RCVTIMEO

设置超时值,该值指定输入函数完成之前等待的最长时间。它接受一个 timeval 结构,其中包含秒数和微秒数,指定等待输入操作完成的时间限制。如果接收操作已阻塞这么长时间不接收额外数据,如果没有收到数据,它应返回部分计数或设置为 [EAGAIN] 或 [EWOULDBLOCK] 的 errno。

加粗部分是关键。 Asocket.timeout仅当在持续时间内未收到单个字节时才会引发timeout窗户。换句话说,这是一个timeout接收到的字节之间。

一个简单的函数使用threading.Timer可以如下。

import httplib
import socket
import threading

def download(host, path, timeout = 10):
    content = None
    
    http = httplib.HTTPConnection(host)
    http.request('GET', path)
    response = http.getresponse()
    
    timer = threading.Timer(timeout, http.sock.shutdown, [socket.SHUT_RD])
    timer.start()
    
    try:
        content = response.read()
    except httplib.IncompleteRead:
        pass
        
    timer.cancel() # cancel on triggered Timer is safe
    http.close()
    
    return content

>>> host = 'releases.ubuntu.com'
>>> content = download(host, '/15.04/ubuntu-15.04-desktop-amd64.iso', 1)
>>> print content is None
True
>>> content = download(host, '/15.04/MD5SUMS', 1)
>>> print content is None
False

除了检查之外None,也可以捕获httplib.IncompleteRead异常不在函数内部,而是在函数外部。如果 HTTP 请求没有Content-Length header.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 urllib2 或任何其他 http 库读取超时 的相关文章

随机推荐

  • 切换 elseif 来切换 case

    我们如何将下面的 if else 语句切换为 switch case 语句 任何人都可以帮忙解决这个问题 if Webcc1 Contains licensePartID dtExpiryDate dtActivatedDate AddYe
  • 在 Android APK 中嵌入版本详细信息

    我的代码存储在SVN版本控制中 我使用 Eclipse 来构建我的 Android 应用程序 在我的应用程序中 我有一个关于框 我想在其中显示正确的源代码控制修订版 标签 任何内容 有没有一种方法可以自动执行此操作 以便我在 关于 框中的版
  • 如何在 Ruby 中拆分字符串并获取除第一个之外的所有项目?

    字符串是ex test1 test2 test3 test4 test5 当我使用 ex split first 它返回 test1 现在我想获取剩余的项目 即 test2 test3 test4 test5 如果我使用 ex split
  • 默认情况下,鼠标单击是否会将键盘焦点带到可聚焦控件上?

    这个问题看起来很奇怪 但根据我的经验 我已经习惯了只需用鼠标单击即可将键盘焦点设置到可聚焦元素 但是 UserControl 具有以下属性Focusable true and IsTabStop true让我感到惊讶的是 它通过 Tab 获
  • 如何监控 TensorFlow 估计器训练中的验证损失?

    我想问一个关于如何在 TensorFlow 估计器的训练过程中监控验证损失的问题 我查过类似的问题 估计器训练期间的验证 https stackoverflow com questions 45417502 validation durin
  • 如何在 MATLAB 中执行此累积和?

    我想计算第 2 列中的值的累积和dat txt下面是第 1 列中的每个字符串 所需的输出显示为dat2 txt dat txt dat2 txt 1 20 1 20 20 20 0 1 22 1 22 42 20 22 1 20 1 20
  • 解析树和抽象语法树(AST)有什么区别?

    它们是由编译过程的不同阶段生成的吗 或者它们只是同一事物的不同名称 这是基于表达评估器 http www antlr3 org works help tutorial calculator html泰伦斯 帕尔的语法 本例的语法 gramm
  • 修复了左侧的侧边栏菜单和顶部的固定标题

    所以我想做的是一个固定的侧边栏 顶部有一个固定的菜单 中间的内容可以滚动 body html height 100 margin 0 aside background 90EE90 height 100 left 0 position fi
  • validateRequest="false" 不起作用,即使 requestValidationMode="2.0"

    我有一个在 Visual Studio dev fabric azure 项目 中运行的 ASP NET 网站 并且正在使用 ACS 和 WIF 我的身份验证过程无法正常工作 因为登录后我收到以下信息 A potentially dange
  • Node.js 中的客户端-服务器通信

    我最近开始使用 Node js 来制作一个在线游戏 用于教育 通过阅读各种教程 我想出了如下所示的简单代码 使用我拥有的代码 我能够进行客户端 服务器通信 这基本上是我制作游戏所需的全部内容 只有一个问题 只有客户端可以发起会话 而服务器只
  • 在 gridview 中显示数据库中的数据

    有谁知道如何将数据库条目放入android中的gridview中 或者是否有一个教程解释了如何做到这一点 请通过提供完整的示例来帮助我 您将需要使用游标适配器 http developer android com reference and
  • 当片段更改时如何更新视图?

    我有一个活动 其中有 2 个 sherlockfragment 前两个页面显示带有自定义列表视图的片段 这些视图是使用 AsyncTask 从服务器的 xml 构建的 但是 当应用程序运行时 仅显示一个列表视图 另一页只是空白 public
  • new URL() - WHATWG URL API

    我正在摆弄节点 并试图获取 URL 类的实例 因为这些方便的属性 喜欢 const URL require url http createServer request response gt let uri new URL request
  • 如何生成具有给定限制和平均值的随机数? [复制]

    这个问题在这里已经有答案了 我想生成一系列 30 个随机数 其中上限为 40 下限为 12 平均值为 23 总结 n 30 最小值 12 最大值 40 平均值 23 提前致谢 如果您想要连续分布 您可以获得最小值和最大值之间的任何浮点值 一
  • 如何在 UML 中指定“一次一个”?

    我正在制作一个类图Classroom and a Course class 我怎样才能表明Classroom只能有一个Course一次在其中吗 我知道我可以使用多重性来指定教室可以只开设一门课程 但这并不能完全指定在不同时间可以有除该一门课
  • 列表中情侣的乘积之和

    我想找出列表中情侣的乘积之和 例如给出一个列表 1 2 3 4 我想要得到的是答案 1 2 1 3 1 4 2 3 2 4 3 4 我使用暴力来完成此操作 它会给我带来非常大的列表的超时错误 我想要一种有效的方法来做到这一点 请告诉我 我该
  • setFont(Times-Roman) 不能缺少 T1 文件吗?

    我有错误 Can t find pfb for face Times Roman Error reportlab graphics renderPM RenderPMError Can t setFont Times Roman missi
  • 使用 StreamReader 异步解码 utf-8

    我正在习惯 asyncio 并发现任务处理非常好 但将异步库与传统 io 库混合起来可能很困难 我当前面临的问题是如何正确解码异步 StreamReader 最简单的解决方案是read 字节字符串块 然后解码每个块 请参阅下面的代码 在我的
  • React Native 嵌套 ScrollView 锁定

    我正在尝试将 ScrollViews 嵌套在 React Native 中 带有嵌套垂直滚动条的水平滚动条 这是一个例子 var Test React createClass render function return
  • 使用 urllib2 或任何其他 http 库读取超时

    我有用于读取这样的网址的代码 from urllib2 import Request urlopen req Request url for key val in headers items req add header key val r