2012-02-11 8 views
5

Ho un sacco di testo che devo elaborare per URL validi.Estrazione di URL da file di testo/HTML di grandi dimensioni

L'input è vagamente HTMLish, in quanto è principalmente html. Tuttavia, non è realmente valido HTML.

Ho provato a farlo con regex e problemi.

Prima di dire (o forse urlo - Ho letto le altre domande HTML + regex) "utilizzare un parser", c'è una cosa che dovete considerare:
I file con cui sto lavorando sono circa 5 GB di dimensioni

Non conosco alcun parser in grado di gestirlo senza errori o con giorni. Inoltre, mentre il contenuto del testo è in gran parte html, ma non necessariamente valido html significa che richiederebbe un parser molto tollerante. Infine, non tutti i collegamenti sono necessariamente nei tag <a> (alcuni potrebbero essere solo testo in chiaro).

Dato che non mi interessa davvero la struttura del documento, ci sono alternative migliori per l'estrazione di link WRT?

In questo momento sto usando la regex:
\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))) (in grep -E)
, ma anche con quello, ho rinunciato dopo aver farlo funzionare per circa 3 ore.

Ci sono differenze significative nelle prestazioni del motore Regex? Sto usando la riga di comando di MacOS grep. Se esistono altre implementazioni compatibili con prestazioni migliori, questa potrebbe essere un'opzione.


Non mi interessa troppo la lingua/piattaforma, anche se MacOS/riga di comando sarebbe bello.

+0

Dovrebbe prendere le cose senza uno schema? (cioè no 'http: //') – icktoofay

+0

@icktoofay - Sarebbe bello. –

risposta

2

Finii stringa di comandi di un paio grep insieme:

pv -cN source allContent | grep -oP "(?:\"([^\"' ]*?)\")|(?:'([^\"' ]*?)')|(?:([^\"' ]*?))" | grep -E "(http)|(www)|(\.com)|(\.net)|(\.to)|(\.cc)|(\.info)|(\.org)" | pv -cN out > extrLinks1

ho usato pv di darmi un indicatore di avanzamento.

grep -oP "(?:\"([^\"' ]*?)\")|(?:'([^\"' ]*?)')|(?:([^\"' ]*?))"
Estrae tutto ciò che assomiglia a una parola o testo quotato e non ha spazi.

grep -E "(http)|(www)|(\.com)|(\.net)|(\.to)|(\.cc)|(\.info)|(\.org)"
Filtra l'output per tutto ciò che potrebbe sembrare un URL.

Infine,
pv -cN out > extrLinks1
uscite in un file, e dà un bel metro di attività.

Probabilmente spingerò il file generato attraverso sort -u per rimuovere le voci duplicate, ma non volevo stringere quella alla fine perché aggiungerebbe un ulteriore livello di complessità, e sono abbastanza sicuro che sort proverà per bufferare l'intero file, che potrebbe causare un arresto anomalo.


In ogni caso, poiché è in esecuzione al momento, sembra che ci vorranno circa 40 minuti. Non sapevo di pv prima. È un'utilità davvero fantastica!

0

Penso che tu sia nella giusta direzione, e grep dovrebbe essere in grado di gestire un file 5Gb. Prova a semplificare la tua espressione regolare evita l'operatore | e così tante parentesi. Inoltre, usa il comando head per afferrare il primo 100Kb prima di eseguire l'intero file e concatenare i greps usando i pipe per ottenere maggiore specificità. Ad esempio,

head -c 100000 myFile | grep -E "((src)|(href))\b*=\b*[\"'][\w://\.]+[\"']" 

Che dovrebbe essere super veloce, no?

+0

Sto cercando di rilevare anche i link che non sono nei tag ''. –

Problemi correlati