2010-02-21 8 views
9

Tengo una página que tiene este aspecto:¿Cómo utilizar BeautifulSoup para analizar líneas separadas por <br>?

Company A<br /> 
123 Main St.<br /> 
Suite 101<br /> 
Someplace, NY 1234<br /> 
<br /> 
<br /> 
<br /> 
Company B<br /> 
456 Main St.<br /> 
Someplace, NY 1234<br /> 
<br /> 
<br /> 
<br /> 

A veces hay dos en lugar de tres etiquetas "BR" que separan las entradas. ¿Cómo usaría BeautifulSoup para analizar a través de este documento y extraer los campos? Estoy perplejo porque los bits de texto que necesito no están contenidos en las etiquetas de párrafos (o similares) que simplemente puedo repetir.

Respuesta

2

Una vez que tenga este fragmento de HTML, simplemente use una expresión regular para reemplazar <br /> seguido de una nueva línea opcional por una sola nueva línea, luego divídalo en varias líneas nuevas. Esto debería generar múltiples párrafos individuales que puede procesar manualmente.

+0

Gracias por la respuesta, pero por desgracia, no es tan simple como usar una expresión regular. He simplificado el documento anterior para ilustrar mejor mi pregunta. El documento real tiene una mezcla de etiquetas de formato HTML y similares. – jamieb

+1

Pero no le importa * el documento, solo la parte separada por las etiquetas '
'. Utilice BeatifulSoup para extraer esa parte primero. –

+0

No estoy seguro de por qué alguien rechazó su respuesta; Aprecio la ayuda. Voy a intentar un par de ideas basadas en tu sugerencia. Solo esperaba que BeautifulSoup hubiera eliminado la necesidad de un análisis manual. Gracias. – jamieb

0

primero puede hacer un poco de manipulación antes que nada. por ejemplo, cambie todas las líneas nuevas a espacios en blanco, luego sustituya 2 ocurrencias y más de <br /> a algún otro delimitador como |. después de eso puedes obtener tus campos.

html=""" 
Company A<br /> 
123 Main St.<br /> 
Suite 101<br /> 
Someplace, NY 1234<br /> 
<br /> 
<br /> 
<br /> 
Company B<br /> 
456 Main St.<br /> 
Someplace, NY 1234<br /> 
<br /> 
<br /> 
<br /> 
""" 
import re 
newhtml=html.replace("\n","") 
pat=re.compile("(<br \/>){2,}",re.DOTALL|re.M) 
print pat.sub("|",newhtml) 

salida

$ ./python.py 
Company A<br />123 Main St.<br />Suite 101<br />Someplace, NY 1234|Company B<br />456 Main St.<br />Someplace, NY 1234| 

Ahora su información de la compañía están separados por tuberías.

0

Tal vez usted podría utilizar esta función:

def partition_by(pred, iterable): 
    current = None 
    current_flag = None 
    chunk = [] 
    for item in iterable: 
     if current is None: 
      current = item 
      current_flag = pred(current) 
      chunk = [current] 
     elif pred(item) == current_flag: 
      chunk.append(item) 
     else: 
      yield chunk 
      current = item 
      current_flag = not current_flag 
      chunk = [current] 
    if len(chunk) > 0: 
     yield chunk 

añadir algo a comprobar por ser un <br /> etiqueta o salto de línea:

def is_br(bs): 
    try: 
     return bs.name == u'br' 
    except AttributeError: 
     return False 

def is_br_or_nl(bs): 
    return is_br(bs) or u'\n' == bs 

(O cualquier otra cosa que es más apropiado ... Soy no tan bueno con BeautifulSoup.)

continuación, utilice partition_by(is_br_or_nl, cs) para producir (por cs conjunto a BeautifulSoup.BeautifulSoup(your_example_html).childGenerator())

[[u'Company A'], 
[<br />], 
[u'\n123 Main St.'], 
[<br />], 
[u'\nSuite 101'], 
[<br />], 
[u'\nSomeplace, NY 1234'], 
[<br />, u'\n', <br />, u'\n', <br />, u'\n', <br />], 
[u'\nCompany B'], 
[<br />], 
[u'\n456 Main St.'], 
[<br />], 
[u'\nSomeplace, NY 1234'], 
[<br />, u'\n', <br />, u'\n', <br />, u'\n', <br />]] 

Eso debería ser lo suficientemente fácil de procesar.

Para generalizar esto, probablemente tenga que escribir un predicado para verificar si su argumento es algo que le importa ... Entonces podría usarlo con partition_by para agrupar todo lo demás. Tenga en cuenta que las cosas que le interesan también están agrupadas: básicamente, debe procesar cada elemento de cada segunda lista producida por el generador resultante, comenzando por el primero que incluye las cosas que le interesan.

6

Debe buscar en el atributo .strings que se encuentra en las etiquetas, luego use "\ n" .join() en eso.

0

tengo problema slimier .THIS cómo resolví

html=html.replace('<br>','<br />') 
Cuestiones relacionadas