Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    82

    Estrapolare elenco di stringhe da un file html remoto

    Cerco di spiegarmi:

    ho un file html che contiene parecchio testo inutile quindi contiene una serie di stringhe bene delimitate, quindi altro testo inutile.

    le stringhe sono delimitate all'inizio dal carattere '#' e terminano tutte con le tre lettere 'ppp'

    Come faccio ad estrapolare in un array ogni singola riga?

    ho provato con split '#' ma l'ultimo risultato va ben oltre il 'ppp' ovviamente e contiene tutto il testo inutile finale

    dovrei estrapolare tutto ciò che è contenuto tra '#' e 'ppp', ma non so come fare, non ho quasi mai usato perl

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    21,188
    Evidentemente non hai mai usato le Regular Expressions (RE).
    Puoi vederle (anche) come un linguaggio a se stante per la manipolazione delle stringhe; il bello e` che e` uguale in molti linguaggi di programmazione, il che` le rende ancora piu` comode.
    Perl ha un ottimo supporto a tale linguaggio, ben documentato nella documentazione (man perl e vari supporti alle RE: perlreftut , perlfaq6 , perlreref , perlre ).

    Se il pezzo da estrarre e` unico in ciascuna stringa, la RE che ti serve e`:
    /\#(.+)ppp/ #se vuoi che il # e le p finali siano fuori dalla stringa
    /(\#.+ppp)/ # se i delimitatori devono far parte della stringa estratta
    Nuova politica di maggiore severita` sui titoli delle discussioni: (ri)leggete il regolamento
    No domande tecniche in messaggi privati

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    82
    Facciamo così ti faccio vedere da che cosa devo estrapolare cosa

    (e cmq no, non ho mai usato le regexp, se non in php, e so benissimo cosa siano)

    codice:
    http://listaeagles.altervista.org/index.php?m=1&q=Operazione.Valchiria
    Vedi che c'è un elenco di risultati che inizia con un #, seguito da una o due cifre indicanti il numero del file, seguita da una stringa seguita da uno spazio, seguita da un'altra stringa indicante la dimensione del file (una-tre cifre seguita da M o K o G), seguita da uno spazio, infine il nome del file

    Dopo l'ultimo risultato c'è dell'altro testo, quindi non necessariamente un altro cancelletto.

    Suggerimenti?

    Su quest'altra pagina,
    codice:
    get("http://www.oceanirc.net/lista/?m=1&q=$ricerca $ricerca2 $ricerca3");
    in perl viene eseguito con eccellente risultato il parsing usando:

    codice:
    while($cont =~ m/#(.*) (.*) (.*) (.*)/g) {
    	open SCRIVI, ">>", $xchatdir."/ocebot.txt";
    	open SCRIVI2, ">>", $xchatdir."/ocepack.txt";
    	print SCRIVI "$2\n";
    	print SCRIVI2 "$1\n";
    	close SCRIVI2;
    	close SCRIVI;
    	Xchat::print("9,1___________________\n4,1Risultato n.°:9,1 $i\n4,1Pack:9,1 $1\n4,1Bot:9,1 $2\n4,1Dimensioni:9,1 $3\n4,1File:9,1 $4\n9,1___________________\n");
    	$i++;	
    }
    La stessa espressione sul primo indirizzo invece non da buon esito, mi raggruppa le colonne a due a due e lascia le ultime due vuote. Prova pure...

    Aggiungo una domanda: ho letto qualcosa sulle regexp ma da nessuna parte ho trovato una spiegazione alla 'm' iniziale e alla 'g' finale. Cosa sono?

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    21,188
    ho letto qualcosa sulle regexp ma da nessuna parte ho trovato una spiegazione alla 'm' iniziale e alla 'g' finale. Cosa sono?
    La m/ iniziale non fa parte della RE, ed e` il comando Perl per dire "trova". Si puo` anche omettere. Come spiegato nel man perlre (3. capoverso) e` spiegato in man perlop.

    La /g finale vuol dire "globale", cioe` cerca in tutta la stringa (altrimenti la ricerca si ferma alla prima occorrenza).

    ===
    La RE che hai postato
    /#(.*) (.*) (.*) (.*)/
    significa:
    Cerca (e salva in $1, $2, $3 e $4 rispettivamente):
    - il pezzo tra la # e il primo spazio (potrebbe essere tra 0 e molti caratteri alfanumerici)
    - il pezzo compreso tra il primo e il secondo spazio (idem)
    - il pezzo compreso tra il secondo e il terzo spazio (idem)
    - il pezzo seguente al terzo spazio (idem) (potrebbe arrivare a fine stringa)

    ===
    Ho visto il primo file postato: sono una serie di stringhe, forse non corrette per una visualizzazione copme pagina Web, ma forse non e` quello lo scopo.

    Invece il secondo link mi pare contenga delle variabili (di cui non conosco il valore), per cui non ha senso che io lo apra.

    ===
    Non ho visto i caratteri ppp nel file postato.

    E non ho capito cosa vuoi fare esattamente.
    Devi modificare la RE per ottenere altri dati?
    Devi ripetere la cosa su file diversi?
    Devi fare un loop come quello postato per fare altre cose?
    Nuova politica di maggiore severita` sui titoli delle discussioni: (ri)leggete il regolamento
    No domande tecniche in messaggi privati

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    82
    Prologo: Lasciamo stare il ppp e il primo post, rimaniamo concentrati sul secondo post. Avevo 'glissato' sulla vera natura dello script per evitare problemi vista la natura delle pagine web, ma ho necessità di chiarimenti e devo essere chiaro ed esplicito anche io, per cui corro il rischio. Mal che vada mi bannano. Motivo per cui ho inserito i link come codice e non come url qui nel post

    Spiegazione: Entrambi i link sono due pagine web, create dal medesimo script, credevo, e, credevo, formattate nel medesimo modo, appositamente per il parsing. Difatti togliendo il primo paramentro m=1 dall'url di entrambi gli indirizzi si ottengono delle pagine web 'classiche'.
    Appurato questo, quindi, entrambi i link sono validi, il secondo l'ho inserito per puro scopo dimostrativo, per farti vedere come lo usavo nello script, che accetta fino a tre parametri sulla riga di comando (e/o da Xchat che è un client mIrc per linux). Lo script crea un link con i tre parametri da riga di comando passati come parametri della ricerca per la/le pagine web di cui sopra.

    Esempio: digitando 'ocecerca' (nome dello script) seguito da 'pippo', lo script recupera la pagina web, che avrà eseguito l'opportuna query di ricerca, all'url
    codice:
    http://www.oceanirc.net/lista/?m=1&q=pippo
    se voglio cercare operazione valchiria mi preleva la pagina dal link
    codice:
    http://www.oceanirc.net/lista/?m=1&q=operazione+valchiria
    E la pagina, grazie al parametro m=1 viene creata in modo apposito con quel aspetto strano, per facilitare il parsing, senza nessun html intorno.

    I due link sui cui ti chiedo di confrontare lo stesso script sono quindi i seguenti:
    Ti prego, prova ad usare la stessa regexp su entrambi gli url
    codice:
    m/#(.*) (.*) (.*) (.*)/g
    Obbiettivo: Ho uno script perfettamente funzionante contenente la regexp ed il loop che ti ho scritto che lavora benissimo sulla prima pagina (oceanirc ).
    Sto copia/incollando il codice per fare un secondo script che funziona sulla seconda pagina (quella su listaeagles).

    ProblemaUsando però quella stessa regexp sulla pagina web listaeagles ottengo non 4 stringhe ma solo due, la prima comprende "#nn nome-bot" ignorando lo spazio in mezzo e la seconda
    "dimensione nome-file" ignorando ancora una volta lo spazio in mezzo. Io, grazie alla regexp sto cercando di ottenere:
    $1 = numero del file, compreso o no il #, non importa
    $2 = nome-del-bot
    $3 = dimensione (compreso il carattere K, M, o G per l'unità di misura)
    $4 = nome-del-file

    Grazie al while riportato nel precedente post riesco sia a salvare su file che a scrivere a video su xChat i risultati, con tanto di formattazione

    Richiesta: Sto appunto chiedendo aiuto per far funzionare l'estrapolazione delle quattro stringhe dalla seconda pagina. Di per se, a parte l'm e la g che tu mi hai spiegato, sapevo leggere la regexp, so cosa fanno, ma non mi riesce proprio di capire come mai la stessa regexp sulla seconda pagina web da risultati così diversi. Mi chiedo se gli 'spazi vuoti' della seconda pagina siano semplici spazi o caratteri speciali, dato che vengono ignorati dal pattern matching perl

    Ringraziamento formale: grazie per la pazienza e per avermi indicato il 'man perlre' di cui ignoravo l'esistenza.

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    21,188
    E` stata dura, ma ci sono riuscito (credo).

    Ma ho dovuto veriifcare i dati con il m=1 in piu`, perche` altrimenti i codici HTML nascondevano il problema.

    I due file non sono uguali: nel secondo ci sono due spazi tra il terzo e il quarto campo.

    Quindi: ignora il numero di spazi, e sostituisci al RE con:
    codice:
    /#(.*)\s+(.*)\s+(.*)\s+(.*)/
    \s vuol dire qualsiasi tipo di separatore bianco, comprendendo anche tab;
    il + indica che possono essere uno o piu`

    Fammi sapere !!
    Nuova politica di maggiore severita` sui titoli delle discussioni: (ri)leggete il regolamento
    No domande tecniche in messaggi privati

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    82
    Diciamo che ci siamo quasi: ora sembra esserci solo il problema dell'ultimo risultato, che accoda anche un sacco di altra roba

    Per esempio funziona benissimo con query 'valchiria' o 'operazione'

    Prova con 'bau' (dal film recente 'hotel bau') e vedrai che accoda all'ultimo risultato una serie di schifezze non indifferenti.

    Tu pensa che per aggirare l'ostacolo ho creato uno script php sul mio server che dalla pagina di query normale, cioè senza m=1, preleva via dom e xpath i dati che mi servono e mi ridà un comodo elenco separato da virgole e \n.

    a quel punto io faccio il get non dell'url di eagles, ma dell'url del mio script, che passa i parametri di ricerca alla pagine di eagles.

    perl legge il mio elenco CSV (comma separated values) con un semplice split /\n/ prima e poi, riga per riga con un semplice split /,/

    e il gioco è fatto.

    solo che così faccio lavorare DUE server e non mi va.

    Posso aprire una parentesi? Visto che in php sono 4 righe di codice, non esiste in perl un semplice equivalente di:

    - carica un file da remoto
    - tramite xpath ricava una lista di nodi
    - per ciascun nodo prelevo il suo valore stringa

    Segue PHP di esempio per prelevare solo il nome del bot, e funziona da dio
    codice:
    $doc = new DOMDocument();
    $q  = $_GET["q"];
    $q = trim(str_replace (" ",".",$q));
    
    $url= "http://listaeagles.altervista.org/index.php?q=$q";
    @$doc->loadHTMLFile($url) or die("Problemi nel caricare la pagina");
    $query = "//table[@id='table5']/tr/td[1]"; 
    $xpath = new DOMXPath($doc);
    
    $debugList = $xpath->evaluate($query);
    $array_nome_bot =  Array();
    
    
    $count = 0;
    
    foreach ($debugList as $domElement){
    
       $domNode = $output->importNode($domElement, true);
       $testo = $domNode->firstChild->nodeValue;
    
       $array_nome_bot[$count] = $testo;
       $count ++;
    
    }
    sarebbe semplicissimo, ho visto che l'xpath per prelevare i quattro valori che mi servono, caricando la pagina normalmente senza m=1 è semplicemente questo:

    //table[@id='table5']/tr/td

    semplicemente.

    Se esiste il modo per fare questi tre semplici passi, allora chi se ne frega di m=1 e regexp, mi piace di più lavorare su html e dom a me. Che ne pensi?

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    21,188
    Non so rispondere a tutto quanto chiedi ... Comunque provo con qualcosa.

    ora sembra esserci solo il problema dell'ultimo risultato, che accoda anche un sacco di altra roba
    Te l'avevo detto che l'ultimo campo legge tutto, fino a fine stringa. Devi vedere cosa c'e` dopo il campo che ti interessa. Se c'e` uno spazio, modifica la RE cosi`:
    codice:
    /#(.*)\s+(.*)\s+(.*)\s+(.*)\s+?/
    Prova con e senza il punto di domanda finale.
    Se il carattere di fine stringa e` diverso, occorre capire qual e`.

    Visto che in php sono 4 righe di codice, non esiste in perl un semplice equivalente di:
    Che io sappia, quello che si fa in PHP si puo` fare anche in Perl. Il come e` una domanda che pero` esula dalle mie conoscenze (tra l'altro io non o mai usato PHP).

    - carica un file da remoto
    Si puo` fare (ma io non conosco la sintassi)
    - tramite xpath ricava una lista di nodi
    Non so cosa siano i nodi; forse in Perl sono chiamati in altro modo - sicuramente Shishii a questo sa rispondere (se hai fretta usa il bottone "segnala al moderatore", chiedendo una sua risposta)
    - per ciascun nodo prelevo il suo valore stringa
    Idem come sopra.


    mi piace di più lavorare su html e dom a me. Che ne pensi?
    personalmente mi pare una cosa inutile: in pratica fai aggiungere al file una serie di tag, che poi filtri per usare i dati. Pero` se il "tempo" e/o il "lavoro" dei computer non e` una variabile importante (per il tuo progetto), fai pure: in fondo e` il risultato che conta.


    A proposito di lavoro dei computer ...
    Gia` ieri lo avevo notato: nel tuo loop, tu ad ogni ciclo fai aprire e chiudere due file:" mi sembra un lavoro inutile. Ecco il tuo codice (commenti miei)
    codice:
    while($cont =~ m/#(.*) (.*) (.*) (.*)/g) {
    	open SCRIVI, ">>", $xchatdir."/ocebot.txt";           # apre file 1
    	open SCRIVI2, ">>", $xchatdir."/ocepack.txt";         # apre file 2
    	print SCRIVI "$2\n";                                  # scrive nel file 1
    	print SCRIVI2 "$1\n";                                 # scrive nel file 2
    	close SCRIVI2;                                     # chiude file 1
    	close SCRIVI;                                         # chiude file 2
    	Xchat::print("9,1___________________\n4,1Risultato .... ___\n");
    	$i++;	
    }
    Ecco come invece farei io:
    codice:
    open SCRIVI, ">>", $xchatdir."/ocebot.txt";                # apre file 1
    open SCRIVI2, ">>", $xchatdir."/ocepack.txt";             # apre file 2
    while($cont =~ m/#(.*) (.*) (.*) (.*)/g) {
    	print SCRIVI "$2\n";                                  # scrive nel file 1
    	print SCRIVI2 "$1\n";                                 # scrive nel file 2
    	Xchat::print("9,1___________________\n4,1Risultato .... ___\n");
    	$i++;	
    }
    close SCRIVI2;                                               # chiude file 1
    close SCRIVI;                                                # chiude file 2
    Credo che in questo modo acceleri di molto (probabilmente un fattore 10 o piu` - aprire e chiduere file sono procedure piuttosto lente).
    Nuova politica di maggiore severita` sui titoli delle discussioni: (ri)leggete il regolamento
    No domande tecniche in messaggi privati

  9. #9
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    82
    Peccato che tu non conosca le librerie dom / xpath / xml relative in perl .... ora apro un thread appostio

    ... il loop che ti ho postato fa schifo, ma non l'ho fatto io, era un addon di un altro canale che, col permesso del suo creatore, stavo cercando di adattare. Nel mio difatti avevo risolto come te, aprendo ad inizio e chiudendo alla fine, anche io odio gli sprechi... mica siamo sotto windows , eh eh eh

    Comunque quella maledetta stringa mi fa impazzire, con o senza ? continua a comportarsi in modo imprevedibile, è proprio lo script di partenza a dare fuori i risultati mal formattati.

    Senti, grazie mille, anzi due mila, della chiacchierata e dell'aiuto fornitormi, cmq sia qualcosa in più ho aggiunto al mio bagaglio di programmatore.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.