2010-11-06 2 views
15

Я пытаюсь разобрать некоторый html в Python. Были некоторые методы, которые на самом деле работали до этого ... но в настоящее время я ничего не могу использовать без обходных решений.Python html синтаксический анализ, который на самом деле работает

  • BeautifulSoup имеет проблемы после того, как SGMLParser ушел
  • html5lib не может разобрать половину того, что это «там»
  • LXML пытается быть «слишком правильными» для обычного HTML (атрибуты и теги, не могут содержать неизвестные пространства имен, или исключение исключается, что означает, что почти без страницы с подключением Facebook можно разобрать)

Какие еще варианты существуют в эти дни? (если они поддерживают xpath, это было бы замечательно)

+0

Вам нужно привести примеры страниц, с которыми не справляются текущие подходы. В противном случае, как мы узнаем, помогут ли наши предлагаемые решения решить ваши проблемы? Кроме того, не забудьте сообщить об ошибках html5lib на странице http://code.google.com/p/html5lib/issues/entry –

ответ

20

Убедитесь, что вы используете html модуль, когда вы разбираете HTML с lxml:

>>> from lxml import html 
>>> doc = """<html> 
... <head> 
... <title> Meh 
... </head> 
... <body> 
... Look at this interesting use of <p> 
... rather than using <br /> tags as line breaks <p> 
... </body>""" 
>>> html.document_fromstring(doc) 
<Element html at ...> 

Все ошибки & исключения растают, вы останетесь с удивительно быстрым синтаксическим анализатором, который часто имеет дело с HTML суп лучше, чем BeautifulSoup.

+0

Это интересно. Я всегда использовал lxml через treebuilder. Я был уверен, что HTMLParser использовал этот способ принудительного html-режима. Очевидно нет. lxml.html анализирует материал, подобный ' 'правильно. (где lxml выбрасывает исключение) – viraptor

+0

Рад слышать, что думает, что работает хорошо для вас! Спасибо, что приняли ответ. –

+1

s/thinks/things –

1

Я думаю, проблема в том, что большинство HTML плохо сформировано. XHTML попытался это исправить, но он никогда не попадал на достаточное количество - особенно, поскольку большинство браузеров делают «интеллектуальные обходные пути» для плохо сформированного кода.

Еще несколько лет назад я попытался проанализировать HTML-код для примитивного приложения-паука и нашел проблемы слишком сложными. Я подозреваю, что на ваших карточках можно писать свои собственные, хотя мы не можем быть единственными людьми с этой проблемой!

10

Я использовал pyparsing для нескольких проектов соскабливания HTML-страниц. Это своего рода промежуточная точка между BeautifulSoup и полными HTML-парсерами на одном конце, а также слишком низкий уровень регулярных выражений (таким образом, это безумие).

С помощью pyparsing вы можете часто получать хорошие результаты HTML-поиска, идентифицируя конкретное подмножество страницы или данных, которые вы пытаетесь извлечь. Этот подход позволяет избежать вопросов, связанных с попыткой разобрать все на странице, так как какой-то проблематичный HTML за пределами интересующего вас региона может отбросить всеобъемлющий парсер HTML.

Хотя это похоже только на прославленный подход с регулярным выражением, pyparsing предлагает встроенные функции для работы с текстом HTML или XML. Pyparsing позволяет избежать многих ошибок, которые расстроить регулярные выражения на основе решения:

  • принимает пропуска без захламления «\ с *» все над выражением
  • обрабатывает неожиданные атрибуты в тегах
  • обрабатывает атрибуты в любом порядке
  • обрабатывает верхний/нижний регистр в тегах
  • ручки имен атрибутов с пространствами имен
  • ручки значений атрибутов в двойные кавычки, одинарные кавычки, или нет котировки
  • обрабатывает пустые тег (эти формы <blah />)
  • возвращает разобранные данные тегов с доступом объекта-атрибутом для атрибутов тега

Вот простой пример из Pyparsing вики, которая получает <a href=xxx> тегов из веб-страница:

from pyparsing import makeHTMLTags, SkipTo 

# read HTML from a web page 
page = urllib.urlopen("http://www.yahoo.com") 
htmlText = page.read() 
page.close() 

# define pyparsing expression to search for within HTML  
anchorStart,anchorEnd = makeHTMLTags("a") 
anchor = anchorStart + SkipTo(anchorEnd).setResultsName("body") + anchorEnd 

for tokens,start,end in anchor.scanString(htmlText): 
    print tokens.body,'->',tokens.href 

Это будет вытаскивать <a> тегов, даже если есть и другие части страницы, содержащей проблемный HTML.Есть и другие примеры HTML на Pyparsing вики:

Pyparsing не полное решение несложный этой проблемы, но, подвергнув процесс синтаксического анализа вам, вы можете лучше контролировать, какие фрагменты HTML, которые вы специально интересуете, обрабатываете их и пропускаете отдых.

4

Если вы соскабливаете контент, отличный способ обойти раздражающие детали - это пакет sitescraper. Он использует машинное обучение для определения того, какой контент нужно получить для вас.

На главной странице:

>>> from sitescraper import sitescraper 
>>> ss = sitescraper() 
>>> url = 'http://www.amazon.com/s/ref=nb_ss_gw?url=search-alias%3Daps&field-keywords=python&x=0&y=0' 
>>> data = ["Amazon.com: python", 
      ["Learning Python, 3rd Edition", 
      "Programming in Python 3: A Complete Introduction to the Python Language (Developer's Library)", 
      "Python in a Nutshell, Second Edition (In a Nutshell (O'Reilly))"]] 
>>> ss.add(url, data) 
>>> # we can add multiple example cases, but this is a simple example so 1 will do (I generally use 3) 
>>> # ss.add(url2, data2) 
>>> ss.scrape('http://www.amazon.com/s/ref=nb_ss_gw?url=search-alias%3Daps&field- keywords=linux&x=0&y=0') 
["Amazon.com: linux", ["A Practical Guide to Linux(R) Commands, Editors, and Shell Programming", 
"Linux Pocket Guide", 
"Linux in a Nutshell (In a Nutshell (O'Reilly))", 
'Practical Guide to Ubuntu Linux (Versions 8.10 and 8.04), A (2nd Edition)', 
'Linux Bible, 2008 Edition: Boot up to Ubuntu, Fedora, KNOPPIX, Debian, openSUSE, and 11 Other Distributions']] 
5

html5lib не может разобрать половину того, что это "там"

Это звучит крайне неправдоподобно. html5lib использует точно такой же алгоритм, который также реализован в последних версиях Firefox, Safari и Chrome. Если бы этот алгоритм сломал половину сети, я думаю, мы бы услышали. Если у вас есть определенные проблемы с этим, делайте ошибки в файлах.

+0

ОК - может быть, не половина, но она сломалась на некоторых тегах скриптов (не помню сайт), пропускает большой кусок youtube (иногда) и другие сайты, с которыми я пытался его использовать. Я расскажу о материалах, которые я могу воспроизвести. – viraptor

+1

Скриптовые теги - это ужасный беспорядок, но их обработка совсем недавно изменилась. Надеюсь, вы обнаружите, что теперь это работает лучше. – Ms2ger

Смежные вопросы