2010-01-29 11 views
6

Estoy tratando de ver un archivo html y eliminar todas las etiquetas para que solo quede el texto pero tengo un problema con mi expresión regular. Esto es lo que tengo hasta ahora.Eliminando etiquetas html de un texto utilizando Expresión regular en python

import urllib.request, re 
def test(url): 
html = str(urllib.request.urlopen(url).read()) 
print(re.findall('<[\w\/\.\w]*>',html)) 

El HTML es una página sencilla con unos pocos enlaces y el texto pero mi expresión regular no va a recoger DOCTYPE HTML PUBLIC "- // W3C // DTD HTML 4.01 Transitional // EN" y 'a href = "...." etiquetas. ¿Alguien puede explicar lo que necesito cambiar en mi expresión regular?

+5

Problemas al analizar HTML con expresiones regulares, ¿dices? ¡Por qué, apenas puedo creerlo! ¡Quien lo hubiera pensado! ¡Qué novedades para los libros! PD. BeautifulSoup. – bobince

+0

Mantenga la calma, bobince. Respira lentamente en la bolsa de papel. En, fuera, dentro, ... http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – hughdbrown

+0

Me encanta la regularidad con la que estas preguntas aparecen Es como si la parte "Buscar preguntas similares" del nuevo formulario de preguntas no funciona: D –

Respuesta

14

Utilice BeautifulSoup. Use lxml. No use regular expressions para analizar HTML.


Editar 2010-01-29: Esto sería un punto de partida razonable para lxml:

from lxml.html import fromstring 
from lxml.html.clean import Cleaner 
import requests 

url = "https://stackoverflow.com/questions/2165943/removing-html-tags-from-a-text-using-regular-expression-in-python" 
html = requests.get(url).text 

doc = fromstring(html) 

tags = ['h1','h2','h3','h4','h5','h6', 
     'div', 'span', 
     'img', 'area', 'map'] 
args = {'meta':False, 'safe_attrs_only':False, 'page_structure':False, 
     'scripts':True, 'style':True, 'links':True, 'remove_tags':tags} 
cleaner = Cleaner(**args) 

path = '/html/body' 
body = doc.xpath(path)[0] 

print cleaner.clean_html(body).text_content().encode('ascii', 'ignore') 

desea que el contenido, por lo que presumiblemente usted no quiere ningún JavaScript o CSS. Además, presumiblemente solo desea el contenido del cuerpo y no el HTML de la cabeza. Lea en lxml.html.clean para ver lo que puede quitar fácilmente. Más inteligente que las expresiones regulares, ¿no?

Además, tenga cuidado con los problemas de codificación Unicode. Puede terminar fácilmente con HTML que no puede imprimir.


2012-11-08: se ha cambiado el uso de urllib2 a requests. Solo usa solicitudes!

+0

¡Esta es la respuesta final! – jathanism

+2

-1. El requisito de OP es simple, elimina todas las etiquetas. No hay necesidad de BeautifulSoup. – ghostdog74

+1

Aquí hay un par de cosas que el OP podría considerar obvias pero omitidas de la pregunta: sección del documento (¿cabeza y cuerpo? ¿Cuerpo solamente?) Y javascript (¿el OP considera parte del contenido de JavaScript?). Esos serán fácilmente controlables con BeautifulSoup y lxml. Las expresiones regulares no se ocuparán de eso en absoluto. – hughdbrown

-1
import re 
patjunk = re.compile("<.*?>|&nbsp;|&amp;",re.DOTALL|re.M) 
url="http://www.yahoo.com" 
def test(url,pat): 
    html = urllib2.urlopen(url).read() 
    return pat.sub("",html) 

print test(url,patjunk) 
+0

Creo que esto manejará todas las entidades HTML: '& (([a-z] {1,5}) | (# \ d {1,4}));' – mlissner

Cuestiones relacionadas