2013-04-07 4 views
7

Ho un xml file. per favore scaricalo e salvalo come blog.xml. È l'elenco dei miei file in Google-blogger, scrivo alcuni codici per analizzarlo, c'è qualcosa che strizza con lxml.Come gestire la codifica in lxml per analizzare correttamente html-string?

code1:

from stripogram import html2text 
import feedparser 
d = feedparser.parse('blog.xml') 
for num,entry in enumerate(d.entries): 
    string=entry.content[0]['value'].encode("utf-8") 
    print html2text(string) 

Si ottengono un risultato giusto con code1.

Codice2:

import lxml.html 
import feedparser 
d = feedparser.parse('blog.xml') 
for num,entry in enumerate(d.entries): 
    string=entry.content[0]['value'] 
    myhtml=lxml.html.document_fromstring(string) 
    print myhtml.text_content() 

Si ottengono un'uscita sbagliata con code2.

Traceback (most recent call last): 
    File "<stdin>", line 3, in <module> 
    File "/usr/lib/python2.7/dist-packages/lxml/html/__init__.py", line 532, in document_fromstring 
    value = etree.fromstring(html, parser, **kw) 
    File "lxml.etree.pyx", line 2754, in lxml.etree.fromstring (src/lxml/lxml.etree.c:54631) 
    File "parser.pxi", line 1569, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82659) 
ValueError: Unicode strings with encoding declaration are not supported. 

CODE3:

import lxml.html 
import feedparser 
d = feedparser.parse('blog.xml') 
for num,entry in enumerate(d.entries): 
    string=entry.content[0]['value'].encode("utf-8") 
    myhtml=lxml.html.document_fromstring(string) 
    print myhtml.text_content() 

Si ottiene un'uscita di sbagliato con CODE3.

Traceback (most recent call last): 
    File "<stdin>", line 3, in <module> 
    File "/usr/lib/python2.7/dist-packages/lxml/html/__init__.py", line 532, in document_fromstring 
    value = etree.fromstring(html, parser, **kw) 
    File "lxml.etree.pyx", line 2754, in lxml.etree.fromstring (src/lxml/lxml.etree.c:54631) 
    File "parser.pxi", line 1578, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82748) 
    File "parser.pxi", line 1457, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:81546) 
    File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:78216) 
    File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74472) 
    File "parser.pxi", line 650, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:75363) 
    File "parser.pxi", line 599, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:74827) 
lxml.etree.XMLSyntaxError: line 1395: Tag b:include invalid 

Come gestire la codifica in lxml per analizzare correttamente html-string?

risposta

4

There is a bug in lxml. Controllare l'uscita di questo codice:

import lxml.html 
import feedparser 

def test(): 
    try: 
     lxml.html.document_fromstring('') 
    except Exception as e: 
     print e 

d = feedparser.parse('blog.xml') 
e = d.entries[0].content[0]['value'].encode('utf-8') 

test() # XMLSyntaxError: None 

lxml.html.document_fromstring(e) 
test() # XMLSyntaxError: line 1407: Tag b:include invalid 

Quindi l'errore è confusa, il vero motivo per cui la tua analisi non è che si passa le stringhe vuote per document_fromstring.

Prova di questo codice:

import lxml.html 
import feedparser 
d = feedparser.parse('blog.xml') 
for num,entry in enumerate(d.entries): 
    string=entry.content[0]['value'].encode("utf-8") 
    if not string: 
     continue 
    myhtml=lxml.html.document_fromstring(string) 
    print myhtml.text_content() 
+0

Sospetto che ci * siano * errori di analisi nelle voci ma che l'eccezione venga ignorata da lxml nel punto sbagliato. La gestione delle eccezioni di Python C-API richiede il codice per verificare le eccezioni in determinati punti e, in caso contrario, l'eccezione si verifica * in seguito * quando si verifica un'altra eccezione che * è * gestito correttamente. Cosa succede se ometti la prima chiamata 'test'? Si verifica lo stesso 'XMLSyntaxError'? –

+0

Questo dovrebbe essere sicuramente segnalato al progetto LXML in ogni caso. –

+0

@Martijn Pieters: sì, si verifica lo stesso errore, la prima chiamata 'test' era solo per mostrare che il messaggio' XMLSyntaxError' cambia dopo aver analizzato 'e'. – gatto

4

è possibile creare da soli un parser, invece di utilizzare document_fromstring:

from cStringIO import StringIO 
from lxml import etree 

for num, entry in enumerate(d.entries): 
    text = entry.content[0]['value'].encode('utf8') 
    parser = etree.HTMLParser() 
    tree = etree.parse(StringIO(text), parser) 
    print ''.join(tree.xpath('.//text()')) 

Per Blogger.com Atom esportazioni di feed, questo funziona per stampare il contenuto del testo della voce .content[0].value.

+0

1.Add 'da lxml importazione etree' 2. Forse è' tree.text_content print() '3.But si tratta di un'uscita sbagliata: Traceback (chiamata più recente ultimo): File "", riga 5, in AttributeError: l'oggetto 'lxml.etree._ElementTree' non ha attributo 'text_content' –

+0

@it_is_a_literature: infatti, tutto corretto. –

+0

Traceback (chiamata più recente scorso): file "", la linea 5, in AttributeError: oggetto 'lxml.etree._Element' non ha alcun attributo 'TEXT_CONTENT' c'è un problema ancora. –