5 Stimmen

Wie man in Python eine Schleife durch einen html-Tabellendatensatz zieht

Ich bin zum ersten Mal Poster hier versuchen, einige Python-Kenntnisse zu sammeln; bitte seien Sie freundlich zu mir :-)

Obwohl mir Programmierkonzepte nicht völlig fremd sind (ich habe schon mit PHP herumgespielt), hat sich der Übergang zu Python für mich als etwas schwierig herausgestellt. Ich schätze, das hat vor allem damit zu tun, dass mir die meisten - wenn nicht alle - grundlegenden Kenntnisse über gängige "Entwurfsmuster" (?) und dergleichen fehlen.

Doch genau hier liegt das Problem. Ein Teil meines aktuellen Projekts beinhaltet das Schreiben eines einfachen Scrapers unter Verwendung von Beautiful Soup. Die zu verarbeitenden Daten haben eine ähnliche Struktur wie die, die unten dargestellt ist.

<table>
    <tr>
        <td class="date">2011-01-01</td>
    </tr>
    <tr class="item">
        <td class="headline">Headline</td>
        <td class="link"><a href="#">Link</a></td>
    </tr>
    <tr class="item">
        <td class="headline">Headline</td>
        <td class="link"><a href="#">Link</a></td>
    </tr>
    <tr>
        <td class="date">2011-01-02</td>
    </tr>
    <tr class="item">
        <td class="headline">Headline</td>
        <td class="link"><a href="#">Link</a></td>
    </tr>
    <tr class="item">
        <td class="headline">Headline</td>
        <td class="link"><a href="#">Link</a></td>
    </tr>
</table>

Das Hauptproblem ist, dass ich einfach nicht meinen Kopf um, wie man 1) behalten den Überblick über das aktuelle Datum (tr->td class="date") während 2) Schleife über die Elemente in den nachfolgenden tr:s (tr class="item"->td class="headline" und tr class="item"->td class="link") und 3) speichern die verarbeiteten Daten in einem Array.

Außerdem werden alle Daten in eine Datenbank eingegeben, in der jeder Eintrag die folgenden Informationen enthalten muss;

  • Datum
  • Schlagzeile
  • Link

Beachten Sie, dass die Verschlüsselung der Datenbank nicht Teil des Problems ist. Ich habe dies nur erwähnt, um besser zu veranschaulichen, was ich hier zu erreichen versuche :-)

Nun gibt es viele verschiedene Arten, eine Katze zu häuten. Während eine Lösung für das vorliegende Problem in der Tat sehr willkommen ist, wäre ich sehr dankbar, wenn jemand die tatsächliche Logik und Strategie erläutern würde, die Sie anwenden würden, um diese Art von Problem "anzugehen" :-)

Zu guter Letzt, entschuldigen Sie, dass die Frage so unsinnig ist.

5voto

Hugh Bothwell Punkte 52831

Das Grundproblem ist, dass diese Tabelle für das Aussehen und nicht für die semantische Struktur erstellt wurde. Richtig gemacht, sollten jedes Datum und die zugehörigen Elemente ein übergeordnetes Element haben. Leider ist das nicht der Fall, also müssen wir uns damit begnügen.

Die grundlegende Strategie besteht darin, jede Zeile der Tabelle zu durchlaufen

  • wenn die erste Tabelle die Klasse 'date' hat, wird der Datumswert ermittelt und last_seen_date aktualisiert
  • Andernfalls werden eine Überschrift und ein Link extrahiert und dann in der Datenbank gespeichert (Datum des letzten Besuchs, Überschrift, Link).

.

import BeautifulSoup

fname = r'c:\mydir\beautifulSoup.html'
soup = BeautifulSoup.BeautifulSoup(open(fname, 'r'))

items = []
last_seen_date = None
for el in soup.findAll('tr'):
    daterow = el.find('td', {'class':'date'})
    if daterow is None:     # not a date - get headline and link
        headline = el.find('td', {'class':'headline'}).text
        link = el.find('a').get('href')
        items.append((last_seen_date, headline, link))
    else:                   # get new date
        last_seen_date = daterow.text

2voto

user407896 Punkte 920

Sie können Element Tree verwenden, das im Python-Paket enthalten ist.

http://docs.python.org/library/xml.etree.elementtree.html

from xml.etree.ElementTree import ElementTree

tree = ElementTree()
tree.parse('page.xhtml') #This is the XHTML provided in the OP
root = tree.getroot() #Returns the heading "table" element
print(root.tag) #"table"
for eachTableRow in root.getchildren(): 
    #root.getchildren() is a list of all of the <tr> elements
    #So we're going to loop over them and check their attributes
    if 'class' in eachTableRow.attrib:
        #Good to go. Now we know to look for the headline and link
        pass
    else:
        #Okay, so look for the date
        pass

Das sollte ausreichen, um die Sache zu analysieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X