LXML в Python, парсинг от URL - PullRequest
6 голосов
/ 20 марта 2012

Я новичок в lxml.Я хочу загрузить веб-страницу и получить интересующие данные, мой код:

import urllib2
from lxml import etree

url = "http://www.example.com/"

html = urllib2.urlopen(url)

root = etree.parse(html) # the problem is here

Может кто-нибудь объяснить мне, почему это не так?

Ошибка:

Traceback (most recent call last):
  File "yatego.py", line 10, in <module>
    root = etree.parse(html)
  File "lxml.etree.pyx", line 2942, in lxml.etree.parse (src/lxml/lxml.etree.c:54187)
  File "parser.pxi", line 1550, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:79703)
  File "parser.pxi", line 1580, in lxml.etree._parseFilelikeDocument (src/lxml/lxml.etree.c:80012)
  File "parser.pxi", line 1463, in lxml.etree._parseDocFromFilelike (src/lxml/lxml.etree.c:78908)
  File "parser.pxi", line 1019, in lxml.etree._BaseParser._parseDocFromFilelike (src/lxml/lxml.etree.c:75905)
  File "parser.pxi", line 564, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:71739)
  File "parser.pxi", line 645, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:72614)
  File "parser.pxi", line 585, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:71955)
lxml.etree.XMLSyntaxError: Entity 'mdash' not defined, line 4, column 21

Этот код:

url = "http://www.example.com/"

res = requests.get(url)
doc = lxml.html.parse(res.content)

выдает эту ошибку:

File "yatego.py", line 11, in <module>
    doc = lxml.html.parse(res.content)
  File "/usr/lib/python2.7/dist-packages/lxml/html/__init__.py", line 692, in parse
    return etree.parse(filename_or_url, parser, base_url=base_url, **kw)
  File "lxml.etree.pyx", line 2942, in lxml.etree.parse (src/lxml/lxml.etree.c:54187)
  File "parser.pxi", line 1528, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:79485)
  File "parser.pxi", line 1557, in lxml.etree._parseDocumentFromURL (src/lxml/lxml.etree.c:79768)
  File "parser.pxi", line 1457, in lxml.etree._parseDocFromFile (src/lxml/lxml.etree.c:78843)
  File "parser.pxi", line 997, in lxml.etree._BaseParser._parseDocFromFile (src/lxml/lxml.etree.c:75698)
  File "parser.pxi", line 564, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:71739)
  File "parser.pxi", line 645, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:72614)
  File "parser.pxi", line 583, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:71927)
IOError: Error reading file '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>IANA &mdash; Example domains</title>

Этот код:

doc = lxml.html.parse(url)

отлично работает

Так гдеэто проблема?

Ответы [ 3 ]

10 голосов
/ 20 марта 2012

Ключевым моментом здесь является исключение:

IOError: Error reading file '<!DOCTYPE html PUBLIC  ...

Вы передаете содержимое файла функции, которая ожидает путь к файлу.По той же причине doc = lxml.html.parse(url) работает, URL "является" filepath.

Работает ли следующее лучше?

doc = lxml.html.fromstring(res.content)
5 голосов
/ 20 марта 2012

Вы должны использовать lxml.html для анализа HTML вместо lxml.etree.

Вы также можете открыть URL-адрес напрямую с помощью lxml:

doc = lxml.html.parse(url)

Иногда lxml будетвозникают проблемы с причудами HTTP, и в этом случае вам нужно будет использовать более надежное решение для извлечения страниц, например requests:

res = requests.get(url)
doc = lxml.html.parse(res.content)
0 голосов
/ 20 марта 2012

Вы должны использовать html.read() для начала: HTML не является строковым типом.Кроме того, вы должны действительно проверить, правильно ли загружен URL-адрес, поскольку это ни в коем случае не является гарантией.

UPD.Используйте html.parse(filename_or_url)

...