2011-01-07 10 views
5

Sono qui per la prima volta poster che cerca di acquisire alcune abilità di Python; per favore sii gentile con me :-)Come eseguire il ciclo di un set di dati html-table in Python

Anche se non sono completamente estraneo ai concetti di programmazione (ho lavorato prima con PHP), la transizione a Python si è rivelata alquanto difficile per me. Immagino che questo abbia principalmente a che fare con il fatto che mi manca la maggior parte - se non tutto - la comprensione di base dei "modelli di progettazione" (?) E così via.

Detto questo, questo è il problema. Parte del mio attuale progetto prevede la scrittura di un semplice raschietto utilizzando Beautiful Soup. I dati da elaborare hanno una struttura in qualche modo simile a quella che è esposta di seguito.

<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> 

Il problema principale è che ho semplicemente non riesco a ottenere la mia testa intorno come 1) tenere traccia della data corrente (TR> td class = "data"), mentre 2) il ciclo sulle voci in il successivo tr: s (tr class = "item" -> td class = "headline" e tr class = "item" -> td class = "link") e 3) memorizza i dati elaborati in un array.

Inoltre, tutti i dati verranno inseriti in un database in cui ogni voce deve contenere le seguenti informazioni;

  • data
  • titolo
  • collegamento

Nota che crud: ing il database non è parte del problema, ho detto solo che questa, al fine di illustrare meglio quello che sto cercando per realizzare qui :-)

Ora, ci sono molti modi diversi per pelle di un gatto. Quindi, mentre una soluzione al problema in esame è davvero molto gradita, sarei estremamente grato se qualcuno si preoccupasse di elaborare la logica e la strategia effettiva che useresti per "attaccare" questo tipo di problema :-)

Ultimo ma non meno importante, mi dispiace per una domanda così noobish.

risposta

5

Il problema di base è che questa tabella è contrassegnata per gli aspetti, non per la struttura semantica. Fatto correttamente, ogni data e i relativi elementi devono condividere un genitore. Sfortunatamente no, quindi dovremo arrangiarci.

La strategia di base è quella di scorrere ogni riga della tabella

  • se la prima TableData ha classe 'data', otteniamo il valore della data e l'aggiornamento last_seen_date
  • In caso contrario, si ottiene estrarre un titolo e un collegamento, quindi salvare (last_seen_date, headline, link) al database

.

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 
+0

Ciao Hugh, ho deciso di seguire il tuo suggerimento, ha funzionato molto bene. Grazie per i tuoi sforzi! :-) – Mattias

2

È possibile utilizzare la struttura ad albero che è inclusa nel pacchetto python.

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 

Questo dovrebbe essere sufficiente per ottenere il vostro cammino per l'analisi di questo.

+0

Ciao, grazie per l'input. Attualmente sto usando beautifulsoup per scopi di scraping, ma probabilmente guarderò Element Tree in qualsiasi momento presto. Saluti! :-) – Mattias

Problemi correlati