使用 httplib 进行不完整读取

2024-01-03

我在从特定网站获取 RSS 提要时一直遇到问题。我最终编写了一个相当丑陋的程序来执行此功能,但我很好奇为什么会发生这种情况以及是否有更高级别的接口正确处理此问题。这个问题并不是真正的问题,因为我不需要经常检索提要。

我已经阅读了一个捕获异常并返回部分内容的解决方案,但由于不完整的读取与实际检索的字节数不同,我不确定这样的解决方案是否真正有效。

#!/usr/bin/env python
import os
import sys
import feedparser
from mechanize import Browser
import requests
import urllib2
from httplib import IncompleteRead

url = 'http://hattiesburg.legistar.com/Feed.ashx?M=Calendar&ID=543375&GUID=83d4a09c-6b40-4300-a04b-f88884048d49&Mode=2013&Title=City+of+Hattiesburg%2c+MS+-+Calendar+(2013)'

content = feedparser.parse(url)
if 'bozo_exception' in content:
    print content['bozo_exception']
else:
    print "Success!!"
    sys.exit(0)

print "If you see this, please tell me what happened."

# try using mechanize
b = Browser()
r = b.open(url)
try:
    r.read()
except IncompleteRead, e:
    print "IncompleteRead using mechanize", e

# try using urllib2
r = urllib2.urlopen(url)
try:
    r.read()
except IncompleteRead, e:
    print "IncompleteRead using urllib2", e


# try using requests
try:
    r = requests.request('GET', url)
except IncompleteRead, e:
    print "IncompleteRead using requests", e

# this function is old and I categorized it as ...
# "at least it works darnnit!", but I would really like to 
# learn what's happening.  Please help me put this function into
# eternal rest.
def get_rss_feed(url):
    response = urllib2.urlopen(url)
    read_it = True
    content = ''
    while read_it:
        try:
            content += response.read(1)
        except IncompleteRead:
            read_it = False
    return content, response.info()


content, info = get_rss_feed(url)

feed = feedparser.parse(content)

如前所述,这不是一个关键任务问题,而是一个好奇心,因为尽管我可以预期 urllib2 会出现此问题,但令我惊讶的是,在 mechanize 和 requests 中也遇到了此错误。 feedparser 模块甚至不会抛出错误,因此检查错误取决于“bozo_exception”键是否存在。

编辑:我只是想提一下,wget 和curl 都完美地执行了该功能,每次都能正确检索完整的有效负载。除了我丑陋的 hack 之外,我还没有找到一个纯粹的 python 方法来工作,而且我非常想知道 httplib 后端发生了什么。出于好奇,我决定前几天也用斜纹布尝试一下,并得到相同的 httplib 错误。

附:还有一件事也让我觉得很奇怪。 IncompleteRead 在有效负载中的两个断点之一处一致发生。看起来 feedparser 和 requests 在读取 926 字节后失败,而 mechanize 和 urllib2 在读取 1854 字节后失败。这种行为是一致的,我没有得到解释或理解。


归根结底,所有其他模块(feedparser, mechanize, and urllib2) call httplib这是抛出异常的地方。

现在,首先,我还使用 wget 下载了这个文件,生成的文件有 1854 字节。接下来,我尝试了urllib2:

>>> import urllib2
>>> url = 'http://hattiesburg.legistar.com/Feed.ashx?M=Calendar&ID=543375&GUID=83d4a09c-6b40-4300-a04b-f88884048d49&Mode=2013&Title=City+of+Hattiesburg%2c+MS+-+Calendar+(2013)'
>>> f = urllib2.urlopen(url)
>>> f.headers.headers
['Cache-Control: private\r\n',
 'Content-Type: text/xml; charset=utf-8\r\n',
 'Server: Microsoft-IIS/7.5\r\n',
 'X-AspNet-Version: 4.0.30319\r\n',
 'X-Powered-By: ASP.NET\r\n',
 'Date: Mon, 07 Jan 2013 23:21:51 GMT\r\n',
 'Via: 1.1 BC1-ACLD\r\n',
 'Transfer-Encoding: chunked\r\n',
 'Connection: close\r\n']
>>> f.read()
< Full traceback cut >
IncompleteRead: IncompleteRead(1854 bytes read)

因此它正在读取所有 1854 个字节,但随后认为还有更多字节。如果我们明确告诉它只读取 1854 字节,它就会起作用:

>>> f = urllib2.urlopen(url)
>>> f.read(1854)
'\xef\xbb\xbf<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">...snip...</rss>'

显然,只有当我们总是提前知道确切的长度时,这才有用。我们可以使用部分读取作为异常的属性返回的事实来捕获整个内容:

>>> try:
...     contents = f.read()
... except httplib.IncompleteRead as e:
...     contents = e.partial
...
>>> print contents
'\xef\xbb\xbf<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">...snip...</rss>'

这篇博文 http://bobrochel.blogspot.co.nz/2010/11/bad-servers-chunked-encoding-and.html表明这是服务器的故障,并描述了如何对服务器进行猴子修补httplib.HTTPResponse.read()方法与try..except上面的块来处理幕后的事情:

import httplib

def patch_http_response_read(func):
    def inner(*args):
        try:
            return func(*args)
        except httplib.IncompleteRead, e:
            return e.partial

    return inner

httplib.HTTPResponse.read = patch_http_response_read(httplib.HTTPResponse.read)

我应用了补丁然后feedparser worked:

>>> import feedparser
>>> url = 'http://hattiesburg.legistar.com/Feed.ashx?M=Calendar&ID=543375&GUID=83d4a09c-6b40-4300-a04b-f88884048d49&Mode=2013&Title=City+of+Hattiesburg%2c+MS+-+Calendar+(2013)'
>>> feedparser.parse(url)
{'bozo': 0,
 'encoding': 'utf-8',
 'entries': ...
 'status': 200,
 'version': 'rss20'}

这不是最好的做事方式,但似乎很有效。我在 HTTP 协议方面不够专业,无法确定服务器是否做错了事情,或者是否httplib错误地处理了边缘情况。

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

使用 httplib 进行不完整读取 的相关文章

随机推荐

  • 在 Azure 数据工厂中引用 JSON 有效负载值作为 If 条件

    我有一个像这样的 Json 文件作为从 API 调用返回的有效负载 这是数据工厂中的 http 数据集类型 count 2 name DatasetABC columnNames Column 1 Column 2 rows 1234 56
  • AWS CLI 上传失败:未知编码:idna

    我尝试使用 AWS CLI 将一些文件推送到 s3 但遇到错误 upload failed An HTTP Client raised and unhandled exception unknown encoding idna 我相信这是一
  • Python 包及其对应的 PyPi 项目可以有不同的名称吗?

    例如 我想知道怎么可能scikit learn是 PyPi 包的名称 而实际的 Python 模块的名称是sklearn 我问的原因是我有一个本地Python包packageA我无法上传到 PyPi 因为该名称恰好已被占用 因此我想知道我是
  • 如何在Delphi中实现一套标准的超链接检测规则

    我目前在程序中自动检测文本内的超链接 我把它做得非常简单 只需要寻找http or www 然而 一位用户建议我将其扩展到其他形式 例如 https or com 然后我意识到它可能不止于此 因为还有 ftp mailto 和 file 所
  • 每个应用程序的长路径行为是否可以通过清单启用?

    尽管 MSDN 文档是什么say https msdn microsoft com en us library windows desktop aa365247 aspx maxpath 您还可以通过以下方式启用每个应用程序的新长路径行为
  • R:如何检查可用的核心数/CPU 使用率

    R 是单线程的 使用 R 如何检查 Windows 和 Linux 中运行 R 的核心 线程数 或者正在运行多少卢比 使用R 如何检查Windows和Linux中运行R的每个核心的使用情况 或者每个 R 使用的 CPU 百分比 例如 如果我
  • IIS 7.5 在哪里记录错误?

    IIS 7 5 在哪里记录错误 事件查看器 日志档案 我收到一个非常不具体的内部 500 错误 我想了解更多 我正在运行 PHP 我做了什么最后一条评论 http forums iis net t 1169733 aspx在这个帖子上说 但
  • 检测直角三角形的C程序

    如果给我坐标系中的 100 个点 我必须找出这些顶点中是否存在直角三角形 有没有一种方法可以检测这些顶点中的直角三角形 而不必选择所有 3 个顶点对 然后对它们应用毕达哥拉斯定理 有更好的算法吗 谢谢你的帮助 这是一个O n 2 log n
  • 对绑定到 DataTable 的 GridView 进行排序

    我有一个存储库 其中包含我正在处理的这个项目的所有 LINQ 查询 我能够将 LINQ 结果获取到 DataTable 并将其绑定到 gridview 以显示数据 现在我需要使 gridview 可排序 我已经设定AllowSorting
  • 如何确定 Git 中合并提交的第一个父级

    我正在阅读有关使用的差异 vs git 中的运算符 我遇到了这个问题Git 中的 HEAD 和 HEAD 有什么区别 https stackoverflow com q 2221658 2498327 在谷歌搜索后 我在网上找不到一个很好的
  • 当我有触摸事件处理程序时,为什么我的鼠标事件处理程序不工作?

    我的一些最终用户拥有触摸屏 其他用户则拥有 PC 在触摸屏上 PreviewMouseUp Down与触摸事件处理程序一起触发 导致重复行为 在 PreviewMousUp Down 中编写的函数被执行两次 所以我的示例按钮 XAML
  • 当涉及两个输入时,jQuery 模糊不断触发

    我在 Google 和 Stack Overflow 上搜索了一段时间 但找不到与此相关的任何内容 我有多个输入文本字段 当模糊时 它们会向服务器调用 jQuery AJAX 函数 它几乎可以完美地工作 问题是 如果我专注于一个文本输入 然
  • 为什么 Set 与 Proxy 不兼容?

    JavaScriptSet https developer mozilla org en docs Web JavaScript Reference Global Objects Set似乎与 JavaScript 完全不兼容proxies
  • Pymongo 连接远程机器超时

    我有一个在 AWS EC2 上运行的 Bitnami MEAN 堆栈 我正在尝试使用 PyMongo 从远程计算机进行连接 from pymongo import MongoClient conn MongoClient mongodb u
  • Automapper:忽略条件

    是否可以根据源属性的值忽略映射成员 例如 如果我们有 public class Car public int Id get set public string Code get set public class CarViewModel p
  • 可以要求我的事件处理程序立即返回吗?

    我正在编写一个 NET 库 其中一个类包含库用户需要订阅的事件 是否可以要求这些事件的处理程序的实现快速返回 或者这是一个有共同解决方案的常见问题吗 如果处理程序花费很长时间 这不会是致命的 但如果处理程序花费的时间超过大约半秒 事情就会开
  • Angular 5 - 添加动态路由但不路由

    我创建了一个新项目 并向路由模块添加了一些代码以进行动态路由 路由模块代码如下 import NgModule from angular core import Routes RouterModule Router from angular
  • SSRS 和 PowerShell:获取 Excel 格式的报告

    我正在尝试让 PowerShell 向我们的 SSRS 服务器发送 Web 请求并捕获结果 我已经使用了撞墙rs FORMAT EXCELSSRS url 字符串中的参数 我有以下内容 首先 初始化凭据 User MYDOMAIN MyUs
  • jquery 插件在其他公共函数中调用公共函数

    我定义了我的插件基于http docs jquery com Plugins Authoring http docs jquery com Plugins Authoring function var methods init functi
  • 使用 httplib 进行不完整读取

    我在从特定网站获取 RSS 提要时一直遇到问题 我最终编写了一个相当丑陋的程序来执行此功能 但我很好奇为什么会发生这种情况以及是否有更高级别的接口正确处理此问题 这个问题并不是真正的问题 因为我不需要经常检索提要 我已经阅读了一个捕获异常并