Seite 1 von 1
HTML File nach bestimmten Tags greppen
Verfasst: Dienstag 17. Februar 2009, 18:46
von bankkind
Hallo Leute,
ich suche eine einfache möglichkeit eine bestimmte HTML/XML Datei aus dem Netz, oder auch lokal nach bestimmten werten zu durchsuchen und anschließend bestimmte Paramter in eine Datenbank zu schreiben.
Da sich diese Datei regekmäßig ändert, kann ich nicht sagen, in welcher Zeile sie stehen.
Ich kenne quasi nur einige Teilwerte, die in meine Tabelle sollen.
Also ich will quasi nach meinem Suchbegriff greppen und will als Ausgabe die komplette Zeile der Tabelle aus dem HTML.
Gibt es da bereits etwas?
Falls nein wie setze ich das am besten um?
bankkind
Verfasst: Dienstag 17. Februar 2009, 18:49
von helduel
Moin,
BeautifulSoup wird hier im Forum immer wieder genannt. Verwendet habe ich das selber aber noch nie.
Gruß,
Manuel
Verfasst: Dienstag 17. Februar 2009, 18:49
von sea-live
jo er war schneller
Code: Alles auswählen
#!/usr/bin/env python
import re
import urllib2
from BeautifulSoup import BeautifulSoup
try:
url = urllib2.urlopen("http://www.fz-juelich.de/gs/meteo/metmess1de/")
soup = BeautifulSoup(url.read(),
convertEntities=BeautifulSoup.HTML_ENTITIES)
temp = soup.find(text=re.compile("Lufttemperatur")).findNext("td")
output = temp.contents[0].string.strip()
except urllib2.URLError:
output = "Unknown"
print output
Verfasst: Dienstag 17. Februar 2009, 19:37
von bankkind
Also dieses Beautiful Soup habe ich mal grob überflogen, aber irgendwie werde ich damit nicht warm. Keine Ahnung...
gibt es dazu ein verständliches deutsches Tutorial? oder eine Übersetzung etc. Oder von mir aus auch eine Alternative Technik zu der es gute Turorials gibt?
Verfasst: Dienstag 17. Februar 2009, 19:43
von lunar
bankkind hat geschrieben:gibt es dazu ein verständliches deutsches Tutorial? oder eine Übersetzung etc. Oder von mir aus auch eine Alternative Technik zu der es gute Turorials gibt?
lxml.html wäre eine Alternative, es hat die bessere API und läuft schneller und speicherschonender.
Deutschsprachige Dokumentation und/oder Tutorials kenne ich aber weder zu lxml.html noch zu BeautifulSoup. Trotzdem sei dir die Nutzung eines vernünftigen HTML-Parsers nahegelegt, reguläre Ausdrücke sind für deine Anforderungen
nicht das geeignete Werkzeug.
Re: HTML File nach bestimmten Tags greppen
Verfasst: Dienstag 17. Februar 2009, 20:39
von ms4py
bankkind hat geschrieben:HTML/XML Datei
Hast du eine HTML oder eine XML Datei?
Für XML gibt es bereits Pakete in der StandardLibrary:
http://openbook.galileocomputing.de/pyt ... 5cdc7fb80f
Verfasst: Mittwoch 18. Februar 2009, 16:45
von bankkind
Es ist HTML, aber ich will mir alle möglichkeiten offen halten. Falls mir der Webmaster mal eine vernünftige XML Schnittstelle zur Verfügung stellt, das ich schnell umschwenken kann.
OK. Benutzt hier jemand BeautifulSoap? Kann mir jemand mal ein kleines Beispiel zeigen:
Wie komme ich an den Inhalt eines bestimmten Tags?
Den Tag identifiziere ich anhand mehrerer Dinge: Farbe, Class etc.
Verfasst: Mittwoch 18. Februar 2009, 17:17
von Hyperion
Also ich habe mal für die Live-Ergebniss-Tabellle von eurosport.de einen scraper geschrieben. Ich habe dazu lxml verwendet. Das ist imho sehr leicht und intuitiv zu benutzen. Mittels XPath habe suche ich mir den Weg zu der Tabelle, die ich parsen will. (Hat halt eine bestimmte Klasse iirc, mittel id wärs natürlich noch schicker)
Ich hab das Script grad nicht greifbar, lade es aber gerne mal hoch.
Ansonsten nutz doch mal die SuFu! Ist noch nicht lange her, da hatten wir hier einen Thread zum Thema Temperatur-Auslesen ...
Verfasst: Mittwoch 18. Februar 2009, 17:29
von sea-live
wenn das ganze nicht zu geheim ist dann gib doch mal ne richtung der webpage die du grappen möchstest und welche zahl oder text du haben willst
also zum verständniss soup gräppt die komplette HTML quellcode
dann mit .find die gewünschte zeile ansteuern und zb nach den nächsten /TD
den wert übernehmen!
beispiel ist oben
im 3ten post
Verfasst: Mittwoch 18. Februar 2009, 17:56
von bankkind
ich will die page leider ungern nennen, sorry. Aufjedenfall ist es ein Browsergame.
ich möchte nun per Cronjob von meinem vServer jeden Tag um die selbe Zeit darauf zugreifen die Daten auslesen und mir per Mail aufs handy schicken.
Da diese Datei sich aber auch jeden Tag ändert (Die Tabellenstruktur bleibt aber die Selbe) kann ich die Zeile nicht bestimmen.
Verfasst: Mittwoch 18. Februar 2009, 19:14
von sea-live
das ist doch genau das oben genannte script was du brauchst wo liegt denn da dein problem
geh auf die HTML
Ansicht seitenquelltext anzeigen ZB im Firefox
die stelle suchen die du gern möchtest
1zeile davor den suchbefehl drauf ansetzen
find(text=re.compile("was halt da steht")).findNext("td")
und die nächste TD TR UR odder halt HTML TAG verarbeiten
so schwer ist das nicht
Verfasst: Mittwoch 18. Februar 2009, 22:48
von bf
Also mit python fange ich gerade erst an, daher kann ich dir keine Beispiele nennen. Aber vom Prinzip her ist das doch ganz einfach:
"fische" <tag x> aus string
gehe solange zeichen für zeichen weiter bis </tag x> kommt
sobald "..g x>" fertig ist, schreibe Zeichen für Zeichen dort hin wo du willst
Am Schluss "</tag x>" wieder rausnehmen oder vorher gar nicht mit rein schreiben lassen.
In Tags wie z.B. "<tag="bla" blubb="möp">" würde ich erstmal an den Leerzeichen Splitten, < > wegmachen, von " bis " Zeichen für Zeichen dorthin, wo es hin soll.
Allzuschwer dürfte sowas nicht sein, da sowas sogar in Bash kein unlösbares Problem darstellt.
Verfasst: Mittwoch 18. Februar 2009, 22:51
von lunar
Man parst Markup nicht auf diese Weise, das ist viel zu instabil.
Verfasst: Mittwoch 18. Februar 2009, 23:35
von ms4py
Alternative:
Du konvertierst dein HTML zu XML mit HTML Tidy und verwendest einen XML-Parser.
http://www.ibm.com/developerworks/libra ... ptidy.html
Verfasst: Donnerstag 19. Februar 2009, 00:40
von Leonidas
Oder du nimmst lxml.html oder html5lib. Der Umweg über den XML-Parser ist IMHO recht aufwending, da nimmt man lieber einen brauchbaren Tagsoup-Parser.
Verfasst: Donnerstag 19. Februar 2009, 00:52
von ms4py
Leonidas hat geschrieben:Der Umweg über den XML-Parser ist IMHO recht aufwending
Warum?
Code: Alles auswählen
from xml.dom import minidom as dom
import os
os.system("tidy -asxhtml -numeric < index.html > index.xml")
parsed_xml = dom.parse("index.xml")
Verfasst: Donnerstag 19. Februar 2009, 00:59
von lunar
Klasse, du hast gezeigt, wie man os.system missbrauchen und aus einer Datei einen MiniDOM-Baum erzeugen kann ...
Wie wäre es mal, wenn du mal versuchst, zu demonstrieren, wie man mit minidom nach einem Element mit einer bestimmten Klasse sucht und dessen HTML-Inhalt durch etwas anderes ersetzt? Dann merkst du wohl selbst, was Leonidas gemeint hat

Verfasst: Donnerstag 19. Februar 2009, 01:05
von Leonidas
ice2k3 hat geschrieben:Leonidas hat geschrieben:Der Umweg über den XML-Parser ist IMHO recht aufwending
Warum?
Weil der rechnerische Aufwand, die Datei erstmal auf die Festplatte zu speichern, dann tidy zu suchen und zu starten, damit das erstmal das HTML parst und wieder XML auf die Platte schreibt was dann wiederrum vom Python-Prozess gelesen wird größer ist als html5lib zu machen, was genau das gleiche wie tidy macht, aber ohne den umweg über die Festplatte, dafür aber mit einer vergleichsweise angenehmen Python-API. Und dort bekommt man entweder Minidom, ElementTree oder lxml-ElementTree heraus, zudem parst es nach den Regeln von HTML5, also eigentlich genauso wie Browser es auch machen.
Verfasst: Mittwoch 25. Februar 2009, 18:39
von bankkind
Da ich es bisher noch nicht hinekommen habe, ist mir eine vorläufige andere Lösung eingefallen... Ich könnte ja den gesamten HTML Code in die Mail kopieren und dann absenden.
Leider funktioniert das auch nicht, weil ich dann folgenden Fehler bekomme:
Ich nehme mal an, das irgend eine Zeile zu lang ist für SMTP.
Wie kann ich das steuern, das er bestimmte Zeileumbrüche einbaut?
Ich habe bereits \n nach jeder Zeile in die Variable gesetzt, aber dennoch kommt der Fehler.
Verfasst: Mittwoch 25. Februar 2009, 21:26
von BlackJack
@bankkind: Das ist eine Antwort vom Server, den Du zum Versenden verwendest. Der findet die Mail hat zu viele Zeilen.