Hallo,
ich bin recht unerfahren in python und Programmieren allgemein. Für kleinere Scripts reicht es jedoch noch.
Nun stehe ich vor der Aufgabe HTML mittles html.parser zu parsen (Python 3).
Ich schaffe es Text „Text1“ zu Filter bei Tags in der Form von:
<td class="Class1"> Text1 </td>
Indem ich Tags <td> mit class “Class1” filtere und mittels
def handle_data(self, data):
print(data)
rausschreibe
Nun kommt es vor das in der HTML außerdem Sachen in der Form von:
<td class="ClassB”> Some Text</td>
<td class="ClassB”> Some Text1</td>
<td class="ClassB”> Some Text2</td>
.
.
</tr>
<tr class="new"><td class="ClassA">Text A</td>
<td class="ClassB”> Text Eins A</td>
</tr>
</tr>
<tr class="new"><td class="ClassA">Text A</td>
<td class="ClassB”> Text Eins B</td>
</tr>
Nun kann ich das Script davor nicht nutzen das ClassB öfter vorkommt ich jedoch nur den Text brauche (Text Eins) wenn „Text A“ in dem Feld davor steht.
Wäre es möglich class „new“ zu filtern und sich dann zwei Tags runter zu hangeln?
Habe da leider nichts gefunden
Gruß und Danke
Error1
HTMLparser nächstes Tag finden
@error1: Ich würde da eher einen Parser verwenden der mit real existierendem HTML klar kommt und auch eine einfachere Navigation im Ergebnis erlaubt. `lxml.html` oder `BeautifulSoup` sind dafür geeignet. Ich weiss allerdings nicht ob und welcher davon für Python 3 verfügbar ist.
Na dann kann man sich ja zum Beispiel für `lxml` entscheiden und hat dort die Auswahl zwischen `cssselect()` und `xpath()`. Falls ich die Kriterien richtig verstanden habe:
Code: Alles auswählen
from lxml import html
def main():
root = html.parse('test.html').getroot()
#
# Variante 1
#
nodes = (
n.itersiblings('td').next()
for n in root.cssselect('tr.new td.ClassA')
if n.text == 'Text A'
)
result = [n.text.strip() for n in nodes if n.get('class') == 'ClassB']
print result
#
# Variante 2
#
result = [
s.strip() for s in root.xpath(
'//tr[@class="new"]'
'/td[@class="ClassA" and text()="Text A"]'
'/following-sibling::td[@class="ClassB"][1]'
'/text()'
)
]
print result
if __name__ == '__main__':
main()
Hallo,
vielen dank für die anregungen. Habe sowas schon vermutet.
Ich werde es mal mit lxml versuchen.
Der Test ode an im Schnelltest nicht funktioniert aber ich werde mich mal in lxml einlesen und gucken ob ich es zustande bekommen. Ansonsten melde ich mich bestimmt nochmal.
Gruß
EDIT: hab sowas ähnliches wie deine xpath variante erstellt. funktioniert bestens. Danke
vielen dank für die anregungen. Habe sowas schon vermutet.
Ich werde es mal mit lxml versuchen.
Der Test ode an im Schnelltest nicht funktioniert aber ich werde mich mal in lxml einlesen und gucken ob ich es zustande bekommen. Ansonsten melde ich mich bestimmt nochmal.
Gruß
EDIT: hab sowas ähnliches wie deine xpath variante erstellt. funktioniert bestens. Danke
Hi,
ich stehe nun vor folgendem problem ich habe tags in derform von
<td class="ClassA"> Text <a href="..."> Zusatz </a></td>
wie kriege ich denn nur "Text Zusatz" raus.
Es würde funktionieren mit a = tree.xpath( //td[@class="ClassA"]/text())
was "Text" auswirft
+
b = tree.xpath(//td[@class="ClassA"]/a/text())
was "Zusatz" auswirft
und dann zusammenfügen
Nun kommt es aber vor das manchmal
<td class="ClassA"> Text1 <a href="..."> Zusatz1 </a></td>
...
<td class="ClassA"> Text2 </td>
...
<td class="ClassA"> Text3 <a href="..."> Zusatz3 </a></td>
im html steht.
Da würde ja dann 2 Listen mit ungleicher Länge ausgeben.
Gibt hier ne leichte Lösung?
Gruß
da steht
ich stehe nun vor folgendem problem ich habe tags in derform von
<td class="ClassA"> Text <a href="..."> Zusatz </a></td>
wie kriege ich denn nur "Text Zusatz" raus.
Es würde funktionieren mit a = tree.xpath( //td[@class="ClassA"]/text())
was "Text" auswirft
+
b = tree.xpath(//td[@class="ClassA"]/a/text())
was "Zusatz" auswirft
und dann zusammenfügen
Nun kommt es aber vor das manchmal
<td class="ClassA"> Text1 <a href="..."> Zusatz1 </a></td>
...
<td class="ClassA"> Text2 </td>
...
<td class="ClassA"> Text3 <a href="..."> Zusatz3 </a></td>
im html steht.
Da würde ja dann 2 Listen mit ungleicher Länge ausgeben.
Gibt hier ne leichte Lösung?
Gruß
da steht
@error1: Suche nur nach den Knoten mit der gewünschten CSS-Klasse und rufe auf denen dann die `text_content()`-Methode auf.