2010-04-20 10 views
34

Hay tantas html and xml libraries built into python, que es difícil de creer que no haya soporte para el análisis de HTML en el mundo real.Cómo analizar HTML malformado en python, usando librerías estándar

He encontrado muchas excelentes bibliotecas de terceros para esta tarea, pero esta pregunta es sobre la biblioteca estándar de python.

Requisitos:

  • Utilice únicamente componentes de la biblioteca Python estándar (cualquier versión 2.x)
  • soporte de DOM
  • entidades manija HTML ( )
  • manejar documentos parciales (como: Hello, <i>World</i>!)

Puntos de bonificación:

  • Soporte XPATH
  • Manejar las etiquetas no cerradas/malformadas. (<big>does anyone here know <html ???

Aquí está mi solución al 90%, conforme a lo solicitado. Esto funciona para el conjunto limitado de HTML que he intentado, pero como todo el mundo puede ver claramente, esto no es exactamente robusta. Desde que hice esto mirando a los documentos durante 15 minutos y una línea de código, pensé que iba a ser capaz de consultar a la comunidad stackOverflow para una solución similar, pero mejor ...

from xml.etree.ElementTree import fromstring 
DOM = fromstring("<html>%s</html>" % html.replace('&nbsp;', '&#160;')) 
+0

No estoy seguro, pero creo que http://docs.python.org/library/markup.html es una lista exhaustiva de todas las funciones de la biblioteca * ML estándar. –

+2

No lo entiendo ¿Estás esperando que hagamos qué? Usted sabe que no hay tal módulo en stdlib. ¿Cuál es tu pregunta? – SilentGhost

+0

¿Podría alguien explicar por qué me están rebajando? Esta es una pregunta legítima que no se aborda actualmente. Todos podemos beneficiarnos al poder hacer esta tarea sin requerir una biblioteca de terceros. – bukzor

Respuesta

43

El análisis de código de forma confiable es un desarrollo relativamente moderno (aunque parezca extraño). Como resultado, definitivamente no hay nada en la biblioteca estándar. HTMLParser puede aparecer como una forma de manejar HTML, pero no lo es - falla en muchos HTML comunes, y aunque puede solucionar esos fallos, siempre habrá otro caso en el que no haya pensado (si de hecho, logrará manejar cada falla que básicamente habrá recreado BeautifulSoup).

En realidad, hay solo 3 maneras razonables de analizar HTML (como se encuentra en la web): lxml.html, BeautifulSoup y html5lib. lxml es el más rápido con diferencia, pero puede ser un poco complicado de instalar (e imposible en un entorno como App Engine). html5lib se basa en cómo HTML 5 especifica el análisis sintáctico; aunque similar en la práctica a los otros dos, es quizás más "correcto" en la forma en que analiza el HTML roto (todos analizan el HTML bastante bueno de la misma manera). Todos hacen un trabajo respetable en el análisis de HTML roto. BeautifulSoup puede ser conveniente, aunque creo que su API es innecesariamente peculiar.

+0

Gran respuesta. ¡Gracias! No tengo suficientes representantes para animarte. QQ Desearía que la gente no fuera tan sensible con las preguntas difíciles. El buen científico también busca experimentos negativos ... – bukzor

+0

@Ian Bicking: finalmente tengo suficientes representantes como para toparte. Solo para confirmar, no hay forma conocida de obtener ElementTree (como existe en el archivo stdlib) para analizar HTML en el mundo real. – bukzor

+0

Puede hacer que BeautifulSoup (con ElementSoup) o html5lib analicen el HTML y generen una estructura ElementTree, pero ElementTree definitivamente no puede analizar HTML. –

1

no se ajusta a sus necesidades de la std solamente, pero beautifulsoup es bueno

+0

Esa es una de las bibliotecas a las que hice referencia con esto: "He encontrado muchas excelentes bibliotecas de terceros para esta tarea, pero esta pregunta es sobre la biblioteca estándar de Python". – bukzor

5

Tome el código fuente de BeautifulSoup y cópielo en su secuencia de comandos ;-) Estoy como una broma ... cualquier cosa que pueda escribir que haga el trabajo sería más o menos duplicar la funcionalidad que ya existe en bibliotecas como ese.

Si eso es realmente no va a funcionar, tengo que preguntar, ¿por qué es tan importante que solo use componentes de biblioteca estándar?

+0

No es tan importante. Es simplemente mi pregunta. Como dije, hay toneladas de soporte html y xml en la biblioteca de python. Parece que algo debería apoyar esto. Si no, esa es una respuesta también, pero aún no estoy convencido. – bukzor

+0

Tenga en cuenta que BeautifulSoup ya no se mantiene. Yo prefiero lxml.html. En general, esta es una gran respuesta. –

+0

¿Dónde escuchaste eso? El sitio web de BeautifulSoup no muestra evidencia de que ya no se mantenga. De hecho, la versión más reciente fue hace 11 días. (Por supuesto, cualquier otro analizador de HTML de terceros funciona igual de bien para el argumento que estaba haciendo en la respuesta) –

1

No puedo pensar en ningún idioma popular con una buena, robusta, heurística biblioteca de análisis de HTML en su stdlib. Python ciertamente no tiene uno, que es algo que creo que sabes.

¿Por qué el requisito de un módulo stdlib? La mayoría de las veces, cuando escucho personas que hacen ese requerimiento, están siendo tontas. Para la mayoría de las tareas principales, necesitará un módulo de terceros o gastar en un lote completo del trabajo reimplementando uno. Introducir una dependencia es una buena cosa , ya que es un trabajo que no tenía que hacer.

Así que lo que quiere es lxml.html. Envíe lxml con su código si eso es un problema, en cuyo punto se vuelve funcionalmente equivalente a escribirlo usted mismo excepto en dificultad, bugginess y capacidad de mantenimiento.

+1

De mi investigación, estaba viendo eso como la respuesta más común, pero no sé, y todavía no estoy convencido de que no exista tal capacidad en el stdlib. Tendrá que admitir que es mucho más probable que una secuencia de comandos que no utiliza una biblioteca externa funcione correctamente para los usuarios noveles. – bukzor

+0

@bukzor, bien convencido, ya que es el caso. = p Y no tengo que admitirlo en absoluto. ;) –

+5

Analizar HTML es algo que las personas solo han entendido ampliamente desde hace unos años; está tomado sorprendentemente largo. Por lo tanto, se puede decir de manera muy definitiva que no hay nada en la biblioteca estándar: BeautifulSoup, html5lib y lxml.html hacen una lista completa. –

4

Sus opciones son cambiar sus requisitos o duplicar todo el trabajo realizado por los desarrolladores de módulos de terceros.

La sopa hermosa consiste en un solo archivo python con aproximadamente 2000 líneas de código, si es una dependencia demasiado grande, luego sigue y escribe la tuya, no funcionará tan bien y probablemente no sea una mucho más pequeño.

+1

Si realmente es tan compacto (nunca se molestó en mirar: P) y está empeñado en tener un script que funcione sin ninguna otra dependencia, copiar y pegar suena como un gran plan. –

+4

Literal copiar y pegar es una forma ridícula de agregar una dependencia. –

0

Como ya se indicó, actualmente no hay una solución satisfactoria solo con standardlib. Me enfrenté al mismo problema que usted, cuando traté de ejecutar uno de mis programas en un entorno de hospedaje obsoleto sin la posibilidad de instalar extensiones propias y solo python2.6. Solución:

Grab this file y la última versión estable BeautifulSoup de la serie 3er (3.2.1 a partir de ahora). Desde el archivo tar allí, solo seleccione BeautifulSoup.py, es el único que realmente necesita enviar con su código. Por lo que tiene estos dos archivos en su camino, lo único que tiene que hacer a continuación, para obtener una etree objeto ocasional de alguna cadena HTML, como puede conseguir desde lxml, es la siguiente:

from StringIO import StringIO 
import ElementSoup 

tree = ElementSoup.parse(StringIO(input_str)) 

lxml sí mismo y html5lib ambos requieren que usted compile un código C para que se ejecute. Es considerablemente más esfuerzo lograr que funcionen, y si su entorno está restringido o su público objetivo no está dispuesto a hacerlo, evítelos.

+2

html5lib no tiene extensiones (por ejemplo, código C) de las que dependa. Puede * opcionalmente * usar varios (como 'datrie') para mejorar el rendimiento, pero funcionará bien sin. – gsnedders

Cuestiones relacionadas