estoy totalmente de respetar el uso de sopa Hermosa para obtener contenido representado, pero puede que no sea el paquete ideal para adquirir el contenido representado en una página.
Tuve un problema similar al contenido renderizado o al contenido visible en un navegador típico. En particular, tuve muchos casos quizás atípicos para trabajar con un ejemplo tan simple a continuación. En este caso, la etiqueta no visualizable está anidada en una etiqueta de estilo, y no está visible en muchos navegadores que he verificado. Existen otras variaciones, como definir una pantalla de configuración de etiqueta de clase en none. Luego usando esta clase para el div.
<html>
<title> Title here</title>
<body>
lots of text here <p> <br>
<h1> even headings </h1>
<style type="text/css">
<div > this will not be visible </div>
</style>
</body>
</html>
Una solución publicado anteriormente es:
html = Utilities.ReadFile('simple.html')
soup = BeautifulSoup.BeautifulSoup(html)
texts = soup.findAll(text=True)
visible_texts = filter(visible, texts)
print(visible_texts)
[u'\n', u'\n', u'\n\n lots of text here ', u' ', u'\n', u' even headings ', u'\n', u' this will not be visible ', u'\n', u'\n']
Esta solución, sin duda tiene aplicaciones en muchos casos y hace el trabajo bastante bien en general, pero en el html publicado por encima de ella conserva el texto que no se representa. Después de buscar por lo que un par de soluciones vinieron aquí y aquí BeautifulSoup get_text does not strip all tags and JavaScriptRendered HTML to plain text using Python
Probé estas dos soluciones: html2text y nltk.clean_html y fue sorprendido por los resultados de distribución para pensaron que justifica una respuesta para la posteridad. Por supuesto, las velocidades dependen en gran medida del contenido de los datos ...
Una respuesta aquí de @Helge fue sobre el uso de nltk de todas las cosas.
import nltk
%timeit nltk.clean_html(html)
was returning 153 us per loop
Funcionó muy bien para devolver una cadena con html renderizado. Este módulo nltk fue más rápido que incluso html2text, aunque quizás html2text sea más robusto.
betterHTML = html.decode(errors='ignore')
%timeit html2text.html2text(betterHTML)
%3.09 ms per loop
@jbochi He reemplazado la línea 3 de visible() con re.match ('. * . *', cadena, re.DOTALL). El suyo parece funcionar solo si el contenido * completo * del texto es un comentario, pero si hay un espacio inicial o una línea nueva, se devolverá el html 'invisible'. Mi solución es demasiado agresiva, ya que marcará todo el elemento como invisible, pero para mis propósitos eso está bien. – Trindaz
+1 para 'soup.findAll (text = True)' nunca se supo acerca de esa característica –
Para BS4 reciente (al menos) puede identificar los comentarios con 'isinstance (element, Comment)' en lugar de coincidir con una expresión regular. – tripleee