2016-05-11 8 views
0

Ich versuche, den gesamten Text in einer bestimmten Spalte in einem bestimmten Teil einer XML-Datei zu erhalten. Zu diesem Zweck benutze ich BeautifulSoup.Verwenden von findAll innerhalb eines bestimmten Tags in BeautifulSoup

Wenn ich BeautifulSoup die FindAll Funktion verwenden, gibt es die Spalten aus dem bestimmten Teil, wie es sollte, Plus alle passenden Spalten nach diesem Teil, so dass nach dem schließenden Tag.

Zur Veranschaulichung eines Beispiels:

Meine Datei:

<?xml version="1.0" encoding="UTF-8"?> 
<doc> 
    <row> 
     <entry colname="col2" align="left"><p>stuff</p></entry> 
    </row> 
    <body> 
     <row><!--[1]--> 
      <entry colname="col1" align="right"><p><id="1"/>1</p></entry> 
      <entry colname="col2" align="left"><p>I want this part</p></entry> 
     </row> 
     <row><!--[2]--> 
      <entry colname="col1" align="right"><p><id="2"/>2</p></entry> 
      <entry colname="col2" align="left"><p>I want this part2</p></entry> 
     </row> 
     <row> 
      <othertag>moreStuff</othertag> 
     </row> 
    </body> 
    <row> 
     <entry colname="col2" align="left"><p>I <b>don't</b> want this part</p></entry> 
    </row> 
</doc> 

Mein Skript:

from bs4 import BeautifulSoup as bs 
soup = bs(open('test.xml', encoding='utf-8').read(), 'xml') 
soup.body.findAll('entry', {'colname': 'col2'}) 

Edited Skript mit identischem Ausgang:

soup = bs(open('test.xml', encoding='utf-8').read(), 'xml') 
part = soup.find('body') 
part.findAll('entry', {'colname': 'col2'}) 

Der Ausgang:

[<entry align="left" colname="col2"><p>I want this part</p></entry>, 
<entry align="left" colname="col2"><p>I want this part2</p></entry>, 
<entry align="left" colname="col2"><p>I <b>don't</b> want this part</p></entry>] 

Wo der letzte Eintrag sollte nicht da sein. Wie behebe ich das?

(Aufgrund der unterschiedlichen Anzahl der richtigen und falschen Einträge in meinem Dateien nur das letzte Element des Arrays Notwasserung ist keine Option)

+0

Finden 'body' zuerst, dann tun Sie Ihre' findAll' drauf? – Cyrbil

Antwort

2

für body Suchen, dann findAll mit darauf sollten Sie, was Sie wollen .
Aber Sie sagten, dass es nicht ... Also habe ich getestet und kann Ihr Problem nicht reproduzieren.

from bs4 import BeautifulSoup as bs 
xml = ''' 
<?xml version="1.0" encoding="UTF-8"?> 
<doc> 
    <row> 
     <entry colname="col2" align="left"><p>stuff</p></entry> 
    </row> 
    <body> 
     <row><!--[1]--> 
      <entry colname="col1" align="right"><p><id="1"/>1</p></entry> 
      <entry colname="col2" align="left"><p>I want this part</p></entry> 
     </row> 
     <row><!--[2]--> 
      <entry colname="col1" align="right"><p><id="2"/>2</p></entry> 
      <entry colname="col2" align="left"><p>I want this part2</p></entry> 
     </row> 
     <row> 
      <othertag>moreStuff</othertag> 
     </row> 
    </body> 
    <row> 
     <entry colname="col2" align="left"><p>I <b>don't</b> want this part</p></entry> 
    </row> 
</doc> 
''' 

soup = bs(xml, 'html.parser') 

print(soup.findAll('entry', {'colname': 'col2'})) 

part = soup.find('body') 
print(part.findAll('entry', {'colname': 'col2'})) 

die mir die erwartete Ausgabe gibt:

$ python /tmp/zbefberg.py 
[<entry align="left" colname="col2"><p>stuff</p></entry>, <entry align="left" colname="col2"><p>I want this part</p></entry>, <entry align="left" colname="col2"><p>I want this part2</p></entry>, <entry align="left" colname="col2"><p>I <b>don't</b> want this part</p></entry>] 
[<entry align="left" colname="col2"><p>I want this part</p></entry>, <entry align="left" colname="col2"><p>I want this part2</p></entry>] 

Von dort versuchen, mein kleines Beispiel aus, wenn das Problem versuchen persist BF4 Neuinstallation, dann lxml neu zu installieren, wenn es versuchen, beharren die 'html.parser' Parser .

+0

Der 'html.parser' löste das Problem, danke! – Swier

1

Mit "xml" -Option, um die Suppe irgendwie in allen <row> nach dem Öffnen Tag von body geht innerhalb der <body> Element. Drucken Sie soup.prettify(), um zu sehen, wie BS Ihre XML analysiert. Das heißt, „html.parser“ statt „xml“ verwendet wird, als auch in der anderen Antwort erwähnt, das Problem behoben

>>> print soup.prettify() 
<?xml version="1.0" encoding="utf-8"?> 
<doc> 
<row> 
    <entry align="left" colname="col2"> 
    <p> 
    stuff 
    </p> 
    </entry> 
</row> 
<body> 
    <row> 
    <!--[1]--> 
    <entry align="right" colname="col1"> 
    <p> 
    <id> 
     ="1"/&gt;1 
    </id> 
    </p> 
    <entry align="left" colname="col2"> 
    <p> 
     I want this part 
    </p> 
    </entry> 
    </entry> 
    <row> 
    <!--[2]--> 
    <entry align="right" colname="col1"> 
    <p> 
     <id> 
     ="2"/&gt;2 
     </id> 
    </p> 
    <entry align="left" colname="col2"> 
     <p> 
     I want this part2 
     </p> 
    </entry> 
    </entry> 
    <row> 
    <othertag> 
     moreStuff 
    </othertag> 
    </row> 
    </row> 
    <row> 
    <entry align="left" colname="col2"> 
    <p> 
     I 
     <b> 
     don't 
     </b> 
     want this part 
    </p> 
    </entry> 
    </row> 
    </row> 
</body> 
</doc> 
Verwandte Themen