2010-04-10 5 views
8

Al tratar de extraer el título de una página HTML que siempre he utilizado la siguiente expresión regular:Python mirada detrás de expresiones regulares requiere patrón fijo de ancho

(?<=<title.*>)([\s\S]*)(?=</title>) 

que extraerá todo entre las etiquetas en un documento y ignorar las etiquetas ellos mismos. Sin embargo, cuando se trata de usar esta expresión regular en Python se plantea la siguiente excepción:

Traceback (most recent call last): 
File "test.py", line 21, in <module> 
    pattern = re.compile('(?<=<title.*>)([\s\S]*)(?=</title>)') 
File "C:\Python31\lib\re.py", line 205, in compile 
    return _compile(pattern, flags) 
File "C:\Python31\lib\re.py", line 273, in _compile 
    p = sre_compile.compile(pattern, flags) File 
"C:\Python31\lib\sre_compile.py", line 495, in compile 
    code = _code(p, flags) File "C:\Python31\lib\sre_compile.py", line 480, in _code 
_compile(code, p.data, flags) File "C:\Python31\lib\sre_compile.py", line 115, in _compile 
    raise error("look-behind requires fixed-width pattern") 
sre_constants.error: look-behind requires fixed-width pattern 

El código que estoy utilizando es:

pattern = re.compile('(?<=<title.*>)([\s\S]*)(?=</title>)') 
m = pattern.search(f) 

si hago algunos ajustes mínimos funciona:

pattern = re.compile('(?<=<title>)([\s\S]*)(?=</title>)') 
m = pattern.search(f) 

Esto, sin embargo, no tendrá en cuenta los posibles títulos html que por alguna razón tienen atributos o similar.

¿Alguien sabe una buena solución para este problema? Cualquier consejo es apreciado.

+0

¿Hay alguna razón por la cual tiene que ser una aserción de ancho cero? ¿Podrías usar un grupo que no captura? –

+3

Aunque no debería usar expresiones regulares para procesar HTML. ¿Por qué usas look-arounds para nada y no algo así como ' ([\ s \ S] *)' y seleccionas el partido del primer grupo? – Gumbo

Respuesta

1

Si lo que desea es obtener la etiqueta del título,

html=urllib2.urlopen("http://somewhere").read() 
for item in html.split("</title>"): 
    if "<title>" in item: 
     print item[ item.find("<title>")+7: ] 
10

Inicie la idea de analizar HTML con expresiones regulares y utilice una biblioteca de análisis de HTML real en su lugar. Después de una búsqueda rápida encontré this one. Es una forma mucho más segura de extraer información de un archivo HTML.

Recuerde, el HTML no es un lenguaje normal, por lo que las expresiones regulares son fundamentalmente la herramienta incorrecta para extraer información de él.

+6

BeautifulSoup (http://www.crummy.com/software/BeautifulSoup/) también es una buena opción. –

5

Here's a famous answer en el análisis de html con expresiones regulares que hace un gran trabajo al decir "no use regex para analizar html".

+4

Sí y no. No debe usar expresiones regulares para analizar un DOM entero o anidamientos complicados de etiquetas. Sin embargo, el análisis de una sola etiqueta no anidada, como lo intenta el OP, es un uso perfectamente legítimo de regex. – Cerin

2

¿Qué pasa algo como:

r = re.compile("(<title.*>)([\s\S]*)(</title>)") 
title = r.search(page).group(2) 
3

La expresión regular para extraer el contenido de HTML no anidada/etiquetas XML es realmente muy simple:

r = re.compile('<title[^>]*>(.*?)</title>') 

Sin embargo, para algo más complejo, realmente debería usar un analizador DOM apropiado como urlli b o BeautifulSoup.

Cuestiones relacionadas