Ho avuto un problema persistente ottenere un feed RSS da un sito Web particolare. Ho finito per scrivere una procedura piuttosto brutta per eseguire questa funzione, ma sono curioso di sapere perché questo accade e se le interfacce di livello superiore gestiscono correttamente questo problema. Questo problema non è in realtà uno stopper, dal momento che non ho bisogno di recuperare il feed molto spesso.IncompleteRead using httplib
Ho letto una soluzione che intercetta l'eccezione e restituisce il contenuto parziale, eppure poiché le letture incomplete differiscono nella quantità di byte che vengono effettivamente recuperati, non ho la certezza che tale soluzione funzioni effettivamente.
#!/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)
Come già detto, questo non è un problema mission critical, ma una curiosità, come anche se posso aspettarmi urllib2 ad avere questo problema, sono sorpreso che si incontra questo errore in mechanize e le richieste pure . Il modulo feedparser non lancia nemmeno un errore, quindi il controllo degli errori dipende dalla presenza di una chiave "bozo_exception".
Modifica: volevo solo dire che sia wget che curl eseguono perfettamente la funzione, recuperando il payload completo correttamente ogni volta. Devo ancora trovare un metodo Python puro per funzionare, tranne il mio brutto trucco, e sono molto curioso di sapere cosa sta succedendo sul backend di httplib. Su un'allodola, ho deciso di provare anche questo con twill l'altro giorno e ho ottenuto lo stesso errore httplib.
P.S. C'è anche una cosa che mi sembra molto strana. IncompleteRead si verifica in modo coerente in uno dei due punti di interruzione nel payload. Sembra che feedparser e le richieste non riescano dopo aver letto 926 byte, eppure meccanize e urllib2 falliscono dopo aver letto 1854 byte. Questo comportamento è coerente, e sono rimasto senza spiegazione o comprensione.
Mentre sono d'accordo che non è un bel modo di fare le cose, è certamente molto meglio del metodo che stavo usando. (Ho davvero bisogno di esercitarmi con i decoratori più spesso). Non sono nemmeno un esperto dei protocolli HTTP, né se httplib lo tratti correttamente o meno, motivo per cui ho ritenuto che questa potesse essere una buona domanda da porre. FWIW, ogni altra pagina di questo sito funziona bene, ed è solo quando si accede all'url di rss che questo problema si verifica sul proprio server http. – umeboshi
@umeboshi - forse è qualcosa a che fare con il tipo di contenuto della risposta, cioè il modo in cui il server è configurato per le risposte 'text/html' funzionano bene ma' text/xml' no? Se non vengono visualizzate risposte più complete, puoi sempre provare a postare questa domanda alla mailing list di Python e vedere se qualcuno può dare una diagnosi. – Blair