2010-02-21 11 views
9

Ho una pagina che assomiglia a questo:Utilizzo di BeautifulSoup per analizzare le righe separate dai tag <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 volte ci sono due invece di tre tag "BR" che separano le voci. Come dovrei usare BeautifulSoup per analizzare questo documento ed estrarre i campi? Sono perplesso perché i frammenti di testo di cui ho bisogno non sono contenuti in tag paragrafo (o simili) che posso semplicemente scorrere.

risposta

2

Una volta ottenuto questo frammento HTML, utilizzare una regex per sostituire <br /> seguito da una nuova riga facoltativa con una nuova riga, quindi dividere su più righe nuove. Ciò dovrebbe comportare più paragrafi singoli che è possibile elaborare manualmente.

+0

Grazie per la risposta, ma purtroppo non è così semplice come solo utilizzando un'espressione regolare. Ho semplificato il documento sopra per illustrare meglio la mia domanda. Il documento vero ha un guazzabuglio di tag di formattazione HTML e simili. – jamieb

+1

Ma non ci si preoccupa * del documento, solo la parte separata dai tag '
'. Usa BeatifulSoup per estrarre prima quella parte. –

+0

Non sono sicuro del motivo per cui qualcuno ha downvoted la tua risposta; Apprezzo l'aiuto. Proverò un paio di idee sulla base del tuo suggerimento. Speravo solo che BeautifulSoup avrebbe eliminato la necessità di un parsing manuale. Grazie. – jamieb

0

si può fare un po 'di manipolazione prima di tutto. Ad esempio, modificare tutte le nuove righe in spazi vuoti, quindi sostituire 2 occorrenze e altre di <br /> in un altro delimitatore come |. dopodiché puoi ottenere i tuoi campi.

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) 

uscita

$ ./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| 

Ora le informazioni sulla società sono separati da tubi.

0

Forse si potrebbe utilizzare questa funzione:

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 

aggiungere qualcosa per controllare per essere un <br /> tag o di nuova riga:

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 qualsiasi altra cosa è più opportuno ... Sono non molto buono con BeautifulSoup.)

Quindi utilizzare partition_by(is_br_or_nl, cs) per produrre (per cs set di 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 />]] 

Questo dovrebbe essere abbastanza facile da elaborare.

Per generalizzare questo, probabilmente dovresti scrivere un predicato per verificare se il suo argomento è qualcosa che ti interessa ... Quindi potresti usarlo con partition_by per far raggruppare tutto il resto. Nota che le cose che ti interessano sono raggruppate insieme - in pratica devi elaborare ogni elemento di ogni secondo elenco prodotto dal generatore risultante, iniziando dal primo che include le cose che ti interessano.

6

Si dovrebbe esaminare l'attributo .strings trovato nei tag, quindi utilizzare "\ n" .join() su quello.

0

ho problema slimier .Questo come ho risolto

html=html.replace('<br>','<br />') 
Problemi correlati