特定の Web サイトから 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 の両方が機能を完璧に実行し、毎回完全なペイロードを正しく取得することに言及したかっただけです。私の醜いハックを除いて、動作する純粋な python メソッドをまだ見つけていません。httplib のバックエンドで何が起こっているのか知りたいと思っています。ヒバリで、先日ツイルでもこれを試してみることにしましたが、同じ httplib エラーが発生しました。
PS 非常に奇妙に感じることが 1 つあります。IncompleteRead は、ペイロードの 2 つのブレークポイントのいずれかで一貫して発生します。feedparser と requests は 926 バイトの読み取り後に失敗するようですが、mechanize と urllib2 は 1854 バイトの読み取り後に失敗します。この行動は一貫しており、説明も理解もできません。