2013-04-07 15 views
7

Mam xml file. pobierz ją i zapisz jako blog.xml. To jest lista moich plików w bloggerze Google, piszę kilka kodów do parsowania, jest coś, co wykręca się przy pomocy lxml.Jak obsługiwać kodowanie w lxml, aby poprawnie analizować ciąg html?

kod1:

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) 

on uzyskać prawo wynik z Kod1.

code2:

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() 

To się źle wyjście z 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() 

To się źle wyjście z 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 

Jak obsługiwać kodowanie w lxml w celu prawidłowego odczytywania html-string?

Odpowiedz

4

There is a bug w lxml. Sprawdź wyjściowa tego kodu:

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 

więc błąd jest mylące, prawdziwy powód dlaczego parsowanie nie jest to, że przechodzą pustych strun do document_fromstring.

Spróbuj kod:

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

Podejrzewam, że * występują * błędy analizy w wpisach, ale wyjątek jest ignorowany przez lxml w niewłaściwym punkcie. Obsługa wyjątków C-API w języku Python wymaga sprawdzenia przez kod wyjątków w określonych punktach, a jeśli to nie jest zrobione, wyjątek zostanie wyświetlony * w późniejszym czasie *, gdy wystąpi inny wyjątek, który * jest * traktowany poprawnie. Co się dzieje, jeśli pominięto pierwsze wywołanie "test"? Czy występuje ten sam "XMLSyntaxError"? –

+0

To powinno być zgłoszone do projektu LXML w każdym przypadku. –

+0

@Martijn Pieters: tak, ten sam błąd występuje, pierwsze wywołanie 'test' miało jedynie pokazać, że komunikat' XMLSyntaxError' zmienia się po parsowaniu 'e'. – gatto

4

Można by stworzyć sobie parser, zamiast korzystania 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()')) 

Dla eksportu paszowych Blogger.com Atom, to działa, aby wydrukować zawartość tekstową wpisu .content[0].value.

+0

1.Add 'z importu lxml etree' 2. Może to' tree.text_content print() '3.but to źle wyjściowa: Traceback (najnowsza wezwanie last): Plik "", wiersz 5, w AttributeError: obiekt "lxml.etree._ElementTree" nie ma atrybutu "text_content" –

+0

@it_is_a_literature: rzeczywiście, wszystkie poprawione. –

+0

Traceback (najnowsza wezwanie ostatni): Plik "", linia 5, w AttributeError: obiekt 'lxml.etree._Element' nie ma atrybutu 'TEXT_CONTENT' istnieje problem nadal. –

Powiązane problemy