2009-04-09 6 views
5

Sto usando PHP e libtidy per tentare di schermare quello che potrebbe essere l'uso più orrendo e malformato delle tabelle HTML nella storia. Il sito chiude pochi tag table, tr, td, font o grass e nidifica costantemente molti diversi livelli di tabelle all'interno delle tabelle.Screensare il più brutto HTML che abbiate mai visto nella vostra vita

frammento di esempio:

<center> 
<table border="1" bordercolor="#000000" cellspacing="0" cellpadding="0"> 
<tr> 
<td width="50%"> 
<center> 
Home Team - <b>Wildcats<td> 
<center> 
Away Team - <b>Polar Bears<tr> 
<td colspan="2"> 
<center> 
<b><font size="+1">Rosters<tr> 
<td valign="top"> 
<center> 
<table border="0" cellspacing="0"> 
<tr> 
<td> 
<font size="2">1&nbsp;<td> 
<font size="2">Baird, T<tr> 
<td> 
<font size="2">2&nbsp;<td> 
<font size="2">Knight, P<tr> 
<td> 
<font size="2">8&nbsp;<td> 
<font size="2">Miller, B<tr> 
<td> 
<font size="2">9&nbsp;<td> 
<font size="2">Huebsch, B<tr> 
<td> 
<font size="2">11&nbsp;<td> 
<font size="2">Buschmann, C<tr> 
<td> 
<font size="2">12&nbsp;<td> 
<font size="2">Reding, J<tr> 
<td> 
<font size="2">14&nbsp;<td> 
<font size="2">Simpson, S<tr> 
<td> 
<font size="2">27&nbsp;<td> 
<font size="2">Kupferschmidt, M<tr> 
<td> 
<font size="2">28&nbsp;<td> 
<font size="2">Anderson, D<tr> 
<td> 
<font size="2">31&nbsp;<td> 
<font size="2">Gehrts, J<tr> 
<td> 
<font size="2">39&nbsp;<td> 
<font size="2">McGinnis, G<tr> 
<td> 
<font size="2">42&nbsp;<td> 
<font size="2">Temple, B<tr> 
<td> 
<font size="2">44&nbsp;<td> 
<font size="2">Kemplin, A<tr> 
<td> 
<font size="2">77&nbsp;<td> 
<font size="2">Weiner, B<tr> 
<td> 
<font size="2">95&nbsp;<td> 
<font size="2"> 
Zytkoskie, D</table> 
<td valign="top"> 
<center> 
<table border="0" cellspacing="0"> 
<tr> 
<td> 
<font size="2">5&nbsp;<td> 
<font size="2">Mack, A<tr> 
<td> 
<font size="2">8&nbsp;<td> 
<font size="2">Foucault, R<tr> 
<td> 
<font size="2">11&nbsp;<td> 
<font size="2">Oberpriller, D *<tr> 
<td> 
<font size="2">12&nbsp;<td> 
<font size="2">Underwood, J<tr> 
<td> 
<font size="2">15&nbsp;<td> 
<font size="2">Oberpriller, M<tr> 
<td> 
<font size="2">19&nbsp;<td> 
<font size="2">Langfus, B<tr> 
<td> 
<font size="2">25&nbsp;<td> 
<font size="2">Carroll, R<tr> 
<td> 
<font size="2">30&nbsp;<td> 
<font size="2">Hirdler, T<tr> 
<td> 
<font size="2">33&nbsp;<td> 
<font size="2">Gibson, S<tr> 
<td> 
<font size="2">35&nbsp;<td> 
<font size="2">Marthaler, C<tr> 
<td> 
<font size="2">44&nbsp;<td> 
<font size="2">Yurik, J<tr> 
<td> 
<font size="2">58&nbsp;<td> 
<font size="2"> 
Gronemeyer, S</table> 
<tr> 
<td colspan="2"> 
<center> 
<b><font size="+1">Goals<tr> 
<td valign="top"> 
<center> 
<table border="1" cellspacing="0" width="100%"> 
<td> 
<b><font size="2">Player<td> 
<b><font size="2">Period<td> 
<b><font size="2">Time<td> 
<b><font size="2">Assist 1<td> 
<b><font size="2">Assist 2<td> 
<b><font size="2">SH<td> 
<b><font size="2">PP<tr> 
<td nowrap> 
<font size="2">Kupferschmidt,&nbsp;M<td> 
<font size="2">1<td> 
<font size="2">12:51<td nowrap> 
<font size="2">Kemplin,&nbsp;A<td nowrap> 
<font size="2">None<td> 
<font size="2"> 
<center> 
<td> 
<font size="2"> 
<center> 
<tr> 
<td nowrap> 
<font size="2">McGinnis,&nbsp;G<td> 
<font size="2">1<td> 
<font size="2">12:33<td nowrap> 
<font size="2">Huebsch,&nbsp;B<td nowrap> 
<font size="2">None<td> 
<font size="2"> 
<center> 
<td> 
<font size="2"> 
<center> 
<tr> 
<td nowrap> 
<font size="2">Kupferschmidt,&nbsp;M<td> 
<font size="2">2<td> 
<font size="2">16:01<td nowrap> 
<font size="2">None<td nowrap> 
<font size="2">None<td> 
<font size="2"> 
<center> 
<td> 
<font size="2"> 
<center> 
<tr> 
<td nowrap> 
<font size="2">Buschmann,&nbsp;C<td> 
<font size="2">3<td> 
<font size="2">00:38<td nowrap> 
<font size="2">None<td nowrap> 
<font size="2">None<td> 
<font size="2"> 
<center> 
<td> 
<font size="2"> 
<center> 
</table> 
<td valign="top"> 
<center> 
<table border="1" cellspacing="0" width="100%"> 
<td> 
<b><font size="2">Player<td> 
<b><font size="2">Period<td> 
<b><font size="2">Time<td> 
<b><font size="2">Assist 1<td> 
<b><font size="2">Assist 2<td> 
<b><font size="2">SH<td> 
<b><font size="2">PP<tr> 
<td nowrap> 
<font size="2">Oberpriller,&nbsp;D *<td> 
<font size="2">3<td> 
<font size="2">12:31<td nowrap> 
<font size="2">Gronemeyer,&nbsp;S<td nowrap> 
<font size="2">None<td> 
<font size="2"> 
<center> 
<td> 
<font size="2"> 
<center> 
</table> 
<tr> 
<td colspan="2"> 
<center> 
<b><font size="+1">Penalties<tr> 
<td valign="top"> 
<center> 
<table border="1" cellspacing="0" width="100%"> 
<td> 
<b><font size="2">Player<td> 
<font size="2"><b>Period<td> 
<font size="2"><b>Minutes<td> 
<font size="2"><b>Offense<td> 
<font size="2"><b>Start<td> 
<font size="2"><b>Expired<tr> 
<td nowrap> 
<font size="2">Buschmann,&nbsp;C<td> 
<font size="2"> 
<center> 
3<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2">Interference<td> 
<font size="2">11:11<td> 
<font size="2">09:11<tr> 
<td nowrap> 
<font size="2">Buschmann,&nbsp;C<td> 
<font size="2"> 
<center> 
3<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2">Unsportmanlike Conduct<td> 
<font size="2">03:26<td> 
<font size="2">01:26<tr> 
<td nowrap> 
<font size="2">Bench<td> 
<font size="2"> 
<center> 
3<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2">Too Many Men<td> 
<font size="2">01:46<td> 
<font size="2"> 
00:00</table> 
<td valign="top"> 
<center> 
<table border="1" cellspacing="0" width="100%"> 
<td> 
<b><font size="2">Player<td> 
<font size="2"><b>Period<td> 
<font size="2"><b>Minutes<td> 
<font size="2"><b>Offense<td> 
<font size="2"><b>Start<td> 
<font size="2"><b>Expired<tr> 
<td nowrap> 
<font size="2">Marthaler,&nbsp;C<td> 
<font size="2"> 
<center> 
1<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2">Interference<td> 
<font size="2">01:19<td> 
<font size="2">16:19<tr> 
<td nowrap> 
<font size="2">Underwood,&nbsp;J<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2">Interference<td> 
<font size="2">12:32<td> 
<font size="2">10:32<tr> 
<td nowrap> 
<font size="2">Marthaler,&nbsp;C<td> 
<font size="2"> 
<center> 
3<td> 
<font size="2"> 
<center> 
2<td> 
<font size="2">Interference<td> 
<font size="2">11:39<td> 
<font size="2"> 
09:39</table> 
<tr> 
<td colspan="2"> 
<center> 
<font size="+1"><b>Goalies<tr> 
<td> 
<center> 
<table border="1" cellspacing="0" width="100%"> 
<td> 
<b><font size="2">Name<td> 
<font size="2"><b>Shots<td> 
<font size="2"><b>Goals<tr> 
<td> 
<font size="2">Baird,&nbsp;T<td> 
<font size="2">20<td> 
<font size="2">1<tr> 
<td> 
<font size="2"><b>Open Net<td> 
<td> 
<font size="2"> 
0</table> 
<td> 
<center> 
<table border="1" cellspacing="0" width="100%"> 
<td> 
<b><font size="2">Name<td> 
<font size="2"><b>Shots<td> 
<font size="2"><b>Goals<tr> 
<td> 
<font size="2">Hirdler,&nbsp;T<td> 
<font size="2">42<td> 
<font size="2"> 

Magicamente, tutti i browser sembrano per rendere questo più che bene. PHPTidy riesce a dare un buon senso a tutto questo, ma le tabelle sono nidificate in modo così profondo e quasi casuale che è davvero difficile attraversarle usando DOM XPath.

Qualcuno ha qualche raccomandazione per altri approcci per fare questo?

POST-MORTEM: Dopo troppe birre di frumento belghe e sporcare il mio codice vero bene ho ottenuto grandi risultati, rimuovendo tutti i tag tramite strip_tags() ad eccezione tavolo, tr e td, quindi esecuzione attraverso libtidy. Ora è formattato magnificamente e molto facilmente attraversato. Sembra che fosse necessario un po 'di massaggio prima di inviarlo al parser.

+0

La cosa veramente triste è, ho visto di peggio !!! – SirDemon

+0

Secondato. È peggio quando vedi un codice come questo con PHP mescolato con esso. – epochwolf

+0

lo script SO prettify non può analizzare questo codice HTML – bendewey

risposta

3

Esistono alcuni trucchi che è possibile utilizzare per pulire strutture altamente prevedibili come le tabelle. Prima di eseguire l'ordine HTML, è possibile utilizzare Regex o qualcosa per cercare gli <tr> e gli <td> seguiti da un altro <tr> o <td> e inserire immediatamente il corrispondente più vicino. Ci sono alcuni trucchi aggiunti per ospitare tabelle all'interno di un <td> ma nulla che sia impossibile da gestire. Iniziare localizzando la struttura più interna e muovendoti verso l'esterno da lì.

Il vero rompicapo è qualcosa di simile a <div> e <p>, che può essere molto più difficile da abbinare ai corrispondenti (o carenti) corrispondenti.

0

Forse dovresti avere più fortuna a recuperare i risultati necessari usando le espressioni regolari invece di analizzarli come XML.

2

Se si è aperti ad altri linguaggi come Python, Beautiful Soup è ottimo per ricostruire HTML scritto male. Ho appena provato a eseguire il codice HTML tramite il frammento seguente e ora è abbastanza leggibile.

#!/usr/bin/env python 

from BeautifulSoup import BeautifulSoup 

html = "long string of html" 
soup = BeautifulSoup(html) 
print soup.prettify() 
+0

Sì, per la cronaca non sono necessariamente dipendente da PHP per ottenere questo risultato. –

+0

Sicuramente dai un'occhiata a Beautiful Soup then. È di gran lunga il miglior raschia schermo che ho usato. È disponibile anche una versione di Ruby, nel caso in cui la preferisci a Python. –

2

Se siete alla ricerca di dati, vorrei solo rimuovere tutti html e gestirlo come linea per linea di ingresso crudo. È possibile utilizzare la funzione strip_tags.

$clean = strip_tags($input); 

// example: <p>Test paragraph.</p> <a href="#fragment">Other text</a> 
// returns: Test paragraph. Other text 
0

ho usato XPath con la libreria di Python lxml per analizzare IMDB Top pagina 250. View the source per te stesso per vedere quanto è male.

Il codice seguente analizza un salvato IMDB Top 250 pagine (top250.html) e memorizza le informazioni estratte in un database SQLite (top250.db)

import sqlite3 
from lxml import html 

tree = html.parse('top250.html') 

class TopMovie(object): 
    base_xpath = "/html/body/div/div[2]/layer/div[3]/table/tr/td[3]/div/table/tr/td/table/tr[%d]" 

    def __init__(self, num): 
     self.rank = num 
     self.xpath = self.base_xpath % (self.rank + 1) 

    def rating(self): 
     return tree.xpath(self.xpath + '/td[2]/font')[0].text 

    def link(self): 
     return tree.xpath(self.xpath + '/td[3]/font/a')[0].values()[0] 

    def title(self): 
     return tree.xpath(self.xpath + '/td[3]/font')[0].text_content() 

    def votes(self): 
     return tree.xpath(self.xpath + '/td[4]/font')[0].text 


def main(): 
    conn = sqlite3.connect('top250.db') 
    conn.execute("""DROP TABLE IF EXISTS movies""") 
    conn.execute(""" 
     CREATE TABLE movies (
      id INTEGER PRIMARY KEY, 
      title TEXT, 
      link TEXT, 
      rating TEXT, 
      votes INTEGER 
     )""") 

    for n in xrange(1, 251): 
     m = TopMovie(n) 
     query = r'INSERT INTO movies VALUES (%d, "%s", "%s", "%s", "%s")' \ 
      % (n, m.title(), m.link(), m.rating(), m.votes().replace(',', '')) 
     conn.execute(query) 

    conn.commit() 
    conn.close() 


if __name__ == "__main__": 
    main() 
Problemi correlati