Italian Estrarre dati da una tabella html

AlpVir

Well-Known Member
Licensed User
Longtime User
Esiste una qualche funzione che estragga il dato contenuto in una certa cella (X,Y) di una tabella di un file html prelevato dal web ? In pratica si tratta di leggere ed interpretare il tag <TD>.
Ad esempio
S=Estrai(3,5)
Ho provato con Regex, con XmlSax, con JTidy ed anche con enorme lavorio di left, mid, right (e compagnia bella), ma senza risultati, probabilmente perchè la tabella contiene anche vari tag quali CLASS, WIDTH, NOWRAP, COLSPAN, ROWSPAN e simili; aggiungo che il file html sembra non essere formattato correttamente e la sua trasformazione in XML non ha successo.
Come si potrebbe operare ?
Grazie per l'attenzione.
 

udg

Expert
Licensed User
Longtime User
Esattamente cosa non funzionava con Regex?
Hai modo di pubblicare un pezzo della tabella e il Regex utilizzato, unitamente alle note sul mancato funzionamento?
Specifica anche se hai un qualche controllo sul sito web da cui trai la tabella o meno.
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Traendo ispirazione dal post https://www.b4x.com/android/forum/threads/jtidy-library-convert-html-pages-to-xml.27038/
ho scritto qualcosa del genere
B4X:
 Dim m As Matcher
   m = Regex.Matcher("<td [^>]+>([^<]+)</td>[^>]+>([^<]+)</td>[^>]+>([^<]+)</td>", s)
   Do While m.Find
      Log("col1=" & m.Group(1))
      Log("col2=" & m.Group(2))
      Log("col3=" & m.Group(3))
      ' ecc ecc
   Loop
sperando di ricavare il contenuto di una cella della pagina (ad esempio) :
http://www.itcgalilei.it/ORARIO/classi/classe0.html
Aggiungo che il risultato è apparentemente nullo e non ho alcun controllo sulla pagina html in questione.
Grazie anticipatamente.
 

udg

Expert
Licensed User
Longtime User
Sono io che ti ringrazio. Sto per iniziare le ferie e questa è un po' come la settimana enigmistica..certo non posso portarla in spiaggia, ma almeno in altri momenti potrò mantenere la mente allenata e sveglia eheh
 

udg

Expert
Licensed User
Longtime User
Un primo tentativo (presumo tu sia interessato ad estrarre materie/docenti)

1. Download della pagina HTML
2. Con IndexOf cerca "<TABLE BORDER=2 WIDTH="90%" CELLSPACING=0 CELLPADDING=4>" e lo memorizi come Inizio
3. Con IndexOf cerca "</TABLE>" e lo memorizzi come Fine
4. Estrai la sottostringa tra inizio e fine (in pratica tutto il codice relativo alla tabella)
5. Applichi Regex: >\n.*<BR>\n.*<\/A> (i segni > all'inizio e alla fine sono parte della stringa); ricorda che come flag/modifier deve esserci /g (ovevro global) in modo che la ricerca si applichi all'intera superstringa della tabella

A questo punto, ottieni tanti blocchi del tipo:
FRANCESE<BR>
<A HREF="../Docenti/Docente58.html" class="nodecBlack">SESIA</A>

Su questi si potrebbe applicare ancora Regex per isolare i due elementi materia/docente (in un caso vai da inizio blocco a <BR> e nell'altro da class=".." a </A> oppure estrai le sottostringhe utilizzando ancora IndexOf.

Buona giornata.
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Estrarre solo il codice relativo alla tabella è semplice. Più complicato, per me, estrarre il contenuto delle 48 celle.
Ho provato varie soluzioni :
B4X:
    Dim m2 As Matcher
    Dim pattern As String
    pattern=">\n.*<BR>\n.*<\/A>"           ' come da te suggerito
    pattern="<a href=\""(.*?)\"">(.*?)</a>"    ' dovrebbe trovare tutti gli A HREF
    pattern="<TR(\s[^>*)?>.*?<TD(\s[^>]*)?>.*?</TR(\s[^>]*)?>"
    m2 = Regex.Matcher(pattern, Tutto)

    Do While m2.Find
        Log("col1=" & m2.Group(1))
        Log("col2=" & m2.Group(2))
        Log("col3=" & m2.Group(3))
        Log("col4=" & m2.Group(4))
        Log("col5=" & m2.Group(5))
        Log("col6=" & m2.Group(6))
        Log("col7=" & m2.Group(7))
    Loop
e, come già detto, mi aspettavo che almeno un m2.Group(n) contenesse tutto quanto c'è fra un inizio tag ed un fine tag, ma ... nulla.
 

udg

Expert
Licensed User
Longtime User
Ciao,

ti allego un esempio funzionante in B4J.
La sub "prepara" è una scorciatoia per quello che avrai già, ovvero il download dal sito e l'estrazione del codice tra <TABLE> e </TABLE>.
Adatta pure il resto in modo da avere la funzione Estrai che chiedevi all'inizio.

Tieni presente che alcuni istituti potrebbero avere anche il sabato (immagino) o più fasce orarie. Giusto per dire che l'esempio funziona ma qualche ritocco va apportato di sicuro.

udg
 

Attachments

  • alpvir1.zip
    1.7 KB · Views: 334

AlpVir

Well-Known Member
Licensed User
Longtime User
L'esempio funziona egregiamente. Lo adatterò allo specifico caso, un po' più complicato di quello che ho illustrato in questo post.
Molte grazie.
 

udg

Expert
Licensed User
Longtime User
Due brevi note.
Se le tabelle derivano da un tuo sw, allora per facilitarti il compito potresti prevedere dei class id (esattamente come class="nodecBlack") in corrispondenza di orari, materie e docenti in modo che il parsing sia estremamente semplificato.
Un altra considerazione è che per fare le cose pulite ed essere in grado di gestire una casistica più completa, probabilmente conviene selezionare riga per riga (tramite <TR> e </TR>) e poi all'interno di ciascuno di questi blocchi cercare ed isolare le info su materie e docenti, sempre che non ti occorrano anche gli orari.
 
Top