2010-11-06 27 views
15

Estoy tratando de analizar algunos html en Python. Hubo algunos métodos que realmente funcionaron antes ... pero hoy en día no hay nada que pueda usar realmente sin soluciones provisionales.Análisis html de Python que realmente funciona

  • BeautifulSoup tiene problemas después de SGMLParser se fue
  • html5lib no puede analizar la mitad de lo que está "ahí fuera"
  • lxml está tratando de ser "demasiado correcto" para HTML típica (atributos y etiquetas no pueden contener espacios de nombres desconocidos, o se lanza una excepción, lo que significa que casi no se puede analizar ninguna página con Facebook connect)

¿Qué otras opciones hay en estos días? (si son compatibles con xpath, sería genial)

+0

Tiene que darnos ejemplos de páginas en las que falla su enfoque actual. De lo contrario, ¿cómo sabremos si nuestras soluciones propuestas resolverán sus problemas? Además, no olvide informar los errores html5lib en http://code.google.com/p/html5lib/issues/entry –

Respuesta

20

Asegúrese de que se utiliza el módulo de html al analizar HTML con 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 ...> 

Todos los errores & excepciones se derretirán, se le dejó con un analizador increíblemente rápido que a menudo se ocupa de HTML sopa mejor que BeautifulSoup.

+0

Eso es interesante. Siempre utilicé lxml a través de un treebuilder. Estaba bastante seguro de que HTMLParser usaba de esta forma el modo html forzado. Aparentemente no. lxml.html analiza el material como ' 'correctamente. (donde lxml arrojó una excepción) – viraptor

+0

¡Me alegra saber que los pensamientos están funcionando bien para usted! Gracias por aceptar la respuesta. –

+1

s/piensa/cosas –

1

Creo que el problema es que la mayoría de HTML está mal formado. XHTML trató de solucionarlo, pero nunca alcanzó lo suficiente, especialmente porque la mayoría de los navegadores hacen "soluciones inteligentes" para códigos mal formados.

Incluso hace algunos años traté de analizar HTML para una aplicación tipo araña primitiva, y encontré los problemas demasiado difíciles. ¡Sospecho que escribir el tuyo podría estar en juego, aunque no podemos ser las únicas personas con este problema!

10

He utilizado pyparsing para varios proyectos de raspado de páginas HTML. Es una especie de término medio entre BeautifulSoup y los analizadores de HTML completos en un extremo, y el enfoque de bajo nivel de las expresiones regulares (de ese modo yace la locura).

Con pyparsing, a menudo puede obtener buenos resultados de análisis HTML identificando el subconjunto específico de la página o los datos que está tratando de extraer. Este enfoque evita los problemas de intentar analizar todo en la página, ya que algunos HTML problemáticos fuera de su región de interés podrían arrojar un analizador HTML exhaustivo.

Si bien esto suena como un enfoque regex glorificado, pyparsing ofrece instrucciones integradas para trabajar con texto etiquetado HTML o XML. Pyparsing evita muchos de los problemas que frustran las soluciones basadas en expresiones regulares:

  • acepta espacios en blanco sin tirar basura '\ S *' por toda su expresión
  • maneja atributos inesperados dentro de las etiquetas
  • manijas atributos en cualquier orden
  • maneja mayúsculas/minúsculas en las etiquetas
  • asas atribuyen nombres con espacios de nombres
  • mangos los valores de atributos entre comillas dobles, comillas simples o sin cotizaciones
  • maneja etiquetas vacías (las de la forma <blah />)
  • vuelve analizados datos de la etiqueta con el acceso a objetos-atributo para atributos de etiqueta

Aquí está un ejemplo sencillo de la pyparsing wiki que se <a href=xxx> etiquetas de una página web:

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 

Esto sacar los <a> etiquetas, incluso si hay otras partes de la página que contiene HTML problemática.Hay otros ejemplos HTML en el pyparsing wiki:

Pyparsing no es una solución total a toda prueba de este problema, pero por la exposición de la proceso de análisis sintáctico para usted, puede controlar mejor las partes del HTML que le interesan específicamente, procesarlas y omitir el descanso.

4

Si está raspando contenido, una excelente manera de evitar los detalles irritantes es el paquete sitescraper. Utiliza aprendizaje automático para determinar qué contenido recuperar para usted.

Desde la página principal:

>>> 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 no puede analizar la mitad de lo que está "ahí fuera"

Eso suena muy plausible. html5lib utiliza exactamente el mismo algoritmo que también se implementó en las versiones recientes de Firefox, Safari y Chrome. Si ese algoritmo rompió la mitad de la web, creo que hubiéramos escuchado. Si tiene problemas particulares con él, búsquelo.

+0

Ok - tal vez no la mitad, pero rompió algunas etiquetas de script (no recuerdo el sitio), echa de menos una gran parte de youtube (a veces) y otros sitios con los que traté de usarlo. Informaré cosas que puedo reproducir. – viraptor

+1

Las etiquetas de scripts son un desastre horrible, de hecho, pero su manejo ha cambiado bastante recientemente. Espero que encuentres que funciona mejor ahora. – Ms2ger