2009-10-23 20 views
5

Estoy intentando extraer texto de páginas html arbitrarias. Algunas de las páginas (que no tengo control) tienen html malformados o scripts que dificultan esto. También estoy en un entorno de alojamiento compartido, así que puedo instalar cualquier lib de Python, pero no puedo instalar todo lo que quiero en el servidor.Estrategia de Python para extraer texto de páginas html con formato incorrecto

pyparsing y html2text.py tampoco parecían funcionar para páginas html malformadas.

Ejemplo URL es http://apnews.myway.com/article/20091015/D9BB7CGG1.html

Mi implementación actual es aproximadamente la siguiente:

# Try using BeautifulSoup 3.0.7a 
soup = BeautifulSoup.BeautifulSoup(s) 
comments = soup.findAll(text=lambda text:isinstance(text,Comment)) 
[comment.extract() for comment in comments] 
c=soup.findAll('script') 
for i in c: 
    i.extract()  
body = bsoup.body(text=True) 
text = ''.join(body) 
# if BeautifulSoup can't handle it, 
# alter html by trying to find 1st instance of "<body" and replace everything prior to that, with "<html><head></head>" 
# try beautifulsoup again with new html 

si BeautifulSoup aún así no funciona, entonces recurrir al uso de una heurística de mirar la primera char, última Char (para ver si parece que es una línea de código # <, y tomar una muestra de la línea y luego verificar si los tokens son palabras o números en inglés. Si a pocos tokens son palabras o números, entonces supongo que el línea es código.

Podría utilizar el aprendizaje automático para inspeccionar cada línea, pero parece un poco caro y probablemente tendría que entrenarlo (ya que no sé mucho sobre máquinas de aprendizaje no supervisadas), y por supuesto escribirlo también.

Cualquier consejo, herramienta, estrategia sería bienvenido. También me doy cuenta de que la última parte de eso es bastante desordenada ya que si obtengo una línea que determine que contiene código, actualmente descarto toda la línea, incluso si hay una pequeña cantidad de texto en inglés real en la línea.

+0

Bueno, no obstante, la noticia con la que se vinculó fue de gran lectura. Algunas personas, ¿eh? :) –

+1

@Lesse, creo que también hay personas mal formadas. – Johnny4000

Respuesta

5

Trate de no reírse, pero:

class TextFormatter: 
    def __init__(self,lynx='/usr/bin/lynx'): 
     self.lynx = lynx 

    def html2text(self, unicode_html_source): 
     "Expects unicode; returns unicode" 
     return Popen([self.lynx, 
         '-assume-charset=UTF-8', 
         '-display-charset=UTF-8', 
         '-dump', 
         '-stdin'], 
         stdin=PIPE, 
         stdout=PIPE).communicate(input=unicode_html_source.encode('utf-8'))[0].decode('utf-8') 

espero que tenga lince!

+0

No tengo lynx = (y no lo instalarán. Tienen el ELinks instalado, que me dijeron que se supone que es similar. Mirando la documentación de ELinks para ver si funciona. Es bueno saber sobre lynx none the menos. – Johnny4000

+0

ELinks y Lynx patean el trasero. Gracias por informarme sobre ellos. – Johnny4000

+0

Nació de la desesperación de mi parte, te lo puedo decir. ¡Me alegro de que sea útil para ti! –

0

Bueno, depende de lo buena que sea la solución. Tuve un problema similar, importando cientos de páginas html antiguas en un nuevo sitio web. Básicamente hice

# remove all that crap around the body and let BS fix the tags 
newhtml = "<html><body>%s</body></html>" % (
    u''.join(unicode(tag) for tag in BeautifulSoup(oldhtml).body.contents)) 
# use html2text to turn it into text 
text = html2text(newhtml) 

y funcionó, pero por supuesto los documentos podrían ser tan malos que incluso BS no puede salvar mucho.

0

BeautifulSoup funcionará mal con HTML mal formado. ¿Qué hay de algunos regex-fu?

>>> import re 
>>> 
>>> html = """<p>This is paragraph with a bunch of lines 
... from a news story.</p>""" 
>>> 
>>> pattern = re.compile('(?<=p>).+(?=</p)', re.DOTALL) 
>>> pattern.search(html).group() 
'This is paragraph with a bunch of lines\nfrom a news story.' 

A continuación, puede ensamblar una lista de etiquetas válidas de las que desea extraer información.

Cuestiones relacionadas