Seite 1 von 1

Zahlen aus HTML extrahieren

Verfasst: Montag 2. April 2007, 15:33
von kritz
hallo

ich möchte in einer funktion aus folgendem html-code eine zahl extrahieren:

Code: Alles auswählen

<tr class=t2 height=30 valign=top>
  <td rowspan=2 class=s align=right>225,89<p align=right></td>

  <td rowspan=2 class=s align=center><a target=_blank href="/redir.cgi?h=it-designworks&loc=http:%2F%2Fwww.haym.info%2FSHOP%2Findex.html%3Fartikelnr%3D6A03198"><b>it-designworks (haym.infotec)</b></a><p><center><small><p><div align=right><nobr><a href="./?qlink=it-designworks%20%28haym.infotec%29&subi=infos">Infos</a> <a href="/redir.cgi?h=it-designworks&loc=http%3A%2F%2Fwww.haym.info%2FSHOP%2Fagb.htm" target=_blank>AGB</a> <a href="http://forum.geizhals.at/search.jsp?k=&author=&topic=%22%7Eit%5B%20-%5D%2Adesignworks%20%28haym%22&area=1&maxAge=0">Meinungen</a></nobr></div></td>
  <td rowspan=2 class=s align=center><p><a href="./?sb=555"><img border=0 valign=absmiddle vspace=2 src=http://geizhals.at/b/1_ani.gif alt="Note: 1,21" title="Note: 1,21 - Spitze!"></a><br><small>Note: 1,21</small><p class=x><small><a href="./?sb=555">708</a> Bewertungen</small><p></td>
  <td class=s width=150>nicht verfügbar</td>

  <td rowspan=2 class=s width="75%">Acer AM.<wbr>K0203.<wbr>001<br>Acer - Acer CI-<wbr>8330 (AM.<wbr>K0203.<wbr>001) (AM.<wbr>K0203.<wbr>001)<br>(Art# 6A03198)<p>(02.04.2007, 12:10)</td>
</tr>
Dazu habe ich folgendes geschrieben:

Code: Alles auswählen

    def auswerten(self):
        
        re1 = compile('<tr>.*?' + 'it-designworks' + '.*?</tr>') # Damit suche ich mir den teil, in welchem "It-designworks" vorkommt...das ist der oben angegebene teil
        re2 = compile('\d+<p align=right></td>') # damit suche ich zahlen, die vor dem text "<p align=right></td>" stehen
        re3 = compile('\d+') #damit hole ich mir die zahl
        zeile = re1.findall(self.htmltext)
        letztesStueck = re2.findall(zeile)
        return re3.findall(letztesStueck)
Ich erhalte die Fehlermeldung:
File "test5.py", line 24, in auswerten
letztesStueck = re2.findall(zeile)
TypeError: expected string or buffer

WARUM?

Verfasst: Montag 2. April 2007, 15:37
von Leonidas
Hallo kritz, willkommen im Forum,

Welche Zahl willst du nochmal extrahieren? Denn ich denke, es ist für mich einfacher den Code neu zu schrieben, als deinen Code zu verstehen.

In der Regel ist es auch eine schlechte Idee HTML mit Regulären Ausdrücken zu parsen - dafür eigenen sich Scraper-Tools wie BeautifulSoup wesentlich besser. Du solltest überlegen ob du nicht besser BeeautifulSoup einsetzen kannst, denn damit ist die Arbeit oft einfacher und zuverlässiger.

Verfasst: Montag 2. April 2007, 15:44
von kritz
ich hätte gerne die Zahl 225,89 (steht eh fast am anfang)

ich ein ähnliches skript gefunden, wo das so gemacht wird. deshalb hab ich diesen weg gewählt.

wichtig ist, dass das html file sehr groß ist. ich möchte die zahl aus jenem tag, wo ein bestimmter Text (z.B. "it-designworks (haym.infotec)") vorkommt.

danke

Verfasst: Montag 2. April 2007, 16:45
von BlackJack
Mit `BeautifulSoup` könnte man so vorgehen: Den Text suchen. Von dort aus das umschliessende ``tr``-Tag suchen und von da dann auf den Inhalt des ersten ``td``-Tags zugreifen:

Code: Alles auswählen

import re
from BeautifulSoup import BeautifulSoup


def main():
    html_file = open('test.html')
    soup = BeautifulSoup(html_file.read())
    html_file.close()
    
    text_node = soup.find(text=re.compile('it-designworks'))
    tr_node = text_node.findParent('tr')
    print tr_node.td.contents[0]

Verfasst: Montag 2. April 2007, 17:12
von kritz
ich hab mich schon herumgespielt, aber das "findParent" hat mir noch gefehlt....DANKE

Verfasst: Mittwoch 4. April 2007, 18:49
von kritz
Ich möchte gerne das ganze Objektorientiert gestalten, d.h. ich hätte gerne eine Klasse "Abfrage" mit den entsprechenden Methoden.

Wie kann ich jetzt von HTML aus die KLasse instanzieren, die suche starten und das Ergebnis an HTML zurückliefern?

Code: Alles auswählen

#! D:\Programme\Python25\python.exe
import cgi
import urllib2
from BeautifulSoup import BeautifulSoup
import re

class Abfrage:
    def __init__(self)
        url = "test.html"
        produkt = "it-designworks"
        page = urllib2.urlopen(url)
        soup = BeautifulSoup(page)

    def __search__(self)
        text_node = soup.find(text=re.compile(produkt))
        tr_node = text_node.findParent('tr')
        preis = tr_node.td.contents[0]

import cgitb
cgitb.enable()
print 'Content-type: text/html'
print
print '<html>'
print '<head><title>Abfrage</title></head>'
print '<body>'
print '<h3> Der Preis betraegt', preis, ' </h3>'
print '</body>'
print '</html>'


Verfasst: Mittwoch 4. April 2007, 19:19
von BlackJack
Was genau soll die Klasse denn bringen? Du teilst da völlig ohne Notwendigkeit eine einfache Funktion auf zwei Methoden auf. Das macht das ganze einfach nur komplizierter ohne einen Mehrwert.

Verfasst: Mittwoch 4. April 2007, 19:49
von kritz
ich habe bereits einige weitere dateien, wo ich dann die preise abspeichere. diese sind dann viel umfangreicher und ich hab mir gedacht, dass das ganze dann übersichtlicher aussieht. oder soll ich es lieber so lassen?

mich würds auch interessieren, wie es funktioniert!

Verfasst: Mittwoch 4. April 2007, 23:23
von Leonidas
kritz hat geschrieben:idiese sind dann viel umfangreicher und ich hab mir gedacht, dass das ganze dann übersichtlicher aussieht. oder soll ich es lieber so lassen?
Nein, dadurch Komplizierst du die Sache nur unnötig - statt einer Funktion mit Rückgabewert hast du nun eine Klasse, die du instanziieren musst, eine Funktion mit seltsamen Namen aufrufen musst und dann dern Preis isrgendwo aus deren Interna rausholen. Mehrwert hast du dadurch überhaupt keinen. Außer dass es nun einfacher nach Java portiert werden kann ;)