2010-02-21 3 views
9

Ich habe eine Seite, die wie folgt aussieht:Verwenden von BeautifulSoup, um Zeilen zu analysieren, die durch <br> Tags getrennt sind?

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

Manchmal gibt es zwei statt drei „br“ Tags, um die Einträge zu trennen. Wie würde ich BeautifulSoup verwenden, um dieses Dokument zu analysieren und die Felder zu extrahieren? Ich bin ratlos, weil die Teile des Textes, die ich brauche, nicht in Absatz- (oder ähnlichen) Tags enthalten sind, die ich einfach durchlaufen kann.

Antwort

2

Sobald Sie dieses HTML-Fragment haben, verwenden Sie einfach eine Regex, um <br />, gefolgt von einem optionalen Zeilenumbruch durch einen einzigen Zeilenumbruch zu ersetzen, dann auf mehrere Zeilenumbrüche aufgeteilt. Dies sollte zu mehreren einzelnen Absätzen führen, die Sie manuell bearbeiten können.

+0

Danke für die Antwort, aber leider ist es nicht so einfach wie nur eine Regex verwenden. Ich habe das obige Dokument vereinfacht, um meine Frage besser zu veranschaulichen. Das tatsächliche Dokument hat ein Wirrwarr von HTML-Formatierungs-Tags und dergleichen. – jamieb

+1

Aber Sie kümmern sich nicht um das Dokument, nur der Teil getrennt durch '
' Tags. Verwende BeatifulousSup, um diesen Teil zuerst zu extrahieren. –

+0

Ich bin mir nicht sicher, warum jemand Ihre Antwort abgelehnt hat; Ich schätze die Hilfe. Ich werde ein paar Ideen basierend auf Ihrem Vorschlag versuchen. Ich hatte nur gehofft, dass BeautifulSoup das manuelle Parsen überflüssig gemacht hätte. Vielen Dank. – jamieb

0

Sie können ein wenig Manipulation vor allem tun. ZB ändern Sie alle Zeilenumbrüche in Leerzeichen, dann ersetzen Sie 2 Vorkommen und mehr von <br /> durch ein anderes Trennzeichen wie |. Danach kannst du deine Felder bekommen.

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) 

Ausgang

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

Jetzt Ihr Unternehmen Informationen über Rohrleitungen getrennt sind.

0

Vielleicht könnten Sie diese Funktion verwenden:

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 

etwas hinzufügen dafür, ein <br /> Tag oder Newline zu überprüfen:

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 

(oder was auch immer besser geeignet ist ... Ich bin nicht so gut mit BeautifulSoup.)

(für cs Satz BeautifulSoup.BeautifulSoup(your_example_html).childGenerator() ergeben Dann partition_by(is_br_or_nl, cs) verwenden)

[[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 />]] 

Das sollte leicht genug zu verarbeiten sein.

Um dies zu verallgemeinern, müssten Sie wahrscheinlich ein Prädikat schreiben, um zu prüfen, ob sein Argument etwas ist, das Ihnen wichtig ist ... Dann könnten Sie es mit partition_by verwenden, um alles andere in einen Topf zu werfen. Beachten Sie, dass die Dinge, die Ihnen wichtig sind, auch zusammengeballt werden - Sie müssen im Grunde jedes Element jeder zweiten Liste verarbeiten, die von dem resultierenden Generator erzeugt wird, beginnend mit dem ersten, der Dinge enthält, die Ihnen wichtig sind.

6

Sie sollten sich das in den Tags gefundene Attribut .strings ansehen und dann "\ n" .join() verwenden.

0

ich schleimigeren Problem haben .this, wie ich

gelöst
html=html.replace('<br>','<br />') 
Verwandte Themen