Urllib в сочетании с elementtree - PullRequest
       23

Urllib в сочетании с elementtree

1 голос
/ 12 марта 2012

У меня есть несколько проблем с анализом простого HTML с использованием модуля ElementTree из стандартных библиотек Python.Это мой исходный код:

from urllib.request import urlopen
from xml.etree.ElementTree import ElementTree

import sys

def main():
    site = urlopen("http://1gabba.in/genre/hardstyle")
    try:
        html = site.read().decode('utf-8')
        xml = ElementTree(html)
        print(xml)
        print(xml.findall("a"))        
    except:
        print(sys.exc_info())

if __name__ == '__main__':
    main()

Если это не удастся, я получу следующий вывод на моей консоли:

<xml.etree.ElementTree.ElementTree object at 0x00000000027D14E0>
(<class 'AttributeError'>, AttributeError("'str' object has no attribute 'findall'",), <traceback object at 0x0000000002910B88>)

Так что xml действительно является объектом ElementTree, когда мы смотрим на документация мы увидим, что класс ElementTree имеет функцию findall.Дополнительная вещь: xml.find ("a") работает нормально, но возвращает экземпляр вместо экземпляра Element.

Так кто-нибудь может мне помочь?Что я недопонимаю?

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

Замените ElementTree(html) на ElementTree.fromstring(html) и измените свой оператор импорта на from xml.etree import ElementTree.

Проблема здесь в том, что конструктор ElementTree не ожидает строку в качестве входных данных - он ожидает объект Element. Функция xml.etree.ElementTree.fromstring () - это самый простой способ построить ElementTree из строки.

Я предполагаю, что синтаксический анализатор XML - это не то, что вам действительно нужно для этой задачи, учитывая, что вы анализируете HTML (который не обязательно является допустимым XML). Возможно, вы захотите взглянуть на:

0 голосов
/ 12 марта 2012

Строка должна быть:

xml = ElementTree(file=html)

P.S .: Вышеуказанное будет работать только тогда, когда XML хорошо структурирован. Если есть ошибка в структуре XML или плохой HTML, то это вызовет ParseError.

Возможно, вы захотите использовать BeautifulSoup для разбора HTML. Если вы хотите использовать XPATH и lxml, вам также может понравиться html5lib.

Это так же просто, как:

tree = html5lib.parse(html.content, treebuilder='lxml', namespaceHTMLElements=False)
# the tree is a lxml object (parsed from any/bad html) supporting findall and find with xpaths
...