Come analizzare centinaia di file di codice sorgente HTML nella shell?


23

Ho un paio di centinaia di file di codice sorgente HTML. Ho bisogno di estrarre il contenuto di un particolare <div>elemento da ciascuno di questi file, quindi scriverò uno script per scorrere ogni file. La struttura dell'elemento è così:

<div id='the_div_id'>
  <div id='some_other_div'>
  <h3>Some content</h3>
  </div>
</div>

Qualcuno può suggerire un metodo con cui posso estrarre il div the_div_ide tutti gli elementi e contenuti figlio da un file usando la riga di comando di Linux?

Risposte:


27

Il pacchetto html-xml-utils , disponibile nella maggior parte delle principali distribuzioni Linux, ha una serie di strumenti utili per la gestione di documenti HTML e XML. Particolarmente utile per il tuo caso è hxselectche legge da input standard ed estrae elementi basati su selettori CSS. Il tuo caso d'uso sarebbe simile a:

hxselect '#the_div_id' <file

Potresti ricevere un reclamo in merito al fatto che l'input non sia ben formato a seconda di cosa lo stai alimentando. Questo reclamo viene fornito per errore standard e quindi può essere facilmente eliminato se necessario. Un'alternativa a questa sarebbe quella di usare il pacchetto HTML :: PARSER di Perl; tuttavia, lo lascerò a qualcuno con abilità Perl meno arrugginite delle mie.


1
hxselectè più esigente riguardo al formato di input rispetto a pup. Ad esempio, sto arrivando Input is not well-formed. (Maybe try normalize?)a hxselect dove lo sto pupsolo analizzando.
AB

12

Prova pup, uno strumento da riga di comando per l'elaborazione di HTML. Per esempio:

pup '#the_div_id' < file.html

Terrrrrrific!
CC,

4

Ecco uno script Perl non testato che estrae <div id="the_div_id">elementi e il loro contenuto utilizzando HTML::TreeBuilder.

#!/usr/bin/env perl
use strict;
use warnings;
use HTML::TreeBuilder;
foreach my $file_name (@ARGV) {
    my $tree = HTML::TreeBuilder->new;
    $tree->parse_file($file_name);
    for my $subtree ($tree->look_down(_tag => "div", id => "the_div_id")) {
        my $html = $subtree->as_HTML;
        $html =~ s/(?<!\n)\z/\n/;
        print $html;
    }
    $tree = $tree->delete;
}

Se sei allergico al Perl, lo ha Python HTMLParser.

PS Non provare a usare espressioni regolari. .



1

Ecco Ex one-liner per estrarre quella parte da ciascun file:

ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html

Per salvare / sostituire sul posto, cambiare -cqa!in -cxae rimuovere la %psezione. Per la ricorsività, considera l'utilizzo di globbing ( **/*.html).

Fondamentalmente per ogni buffer / file ( bufdo), sta facendo le seguenti azioni:

  • /pattern - trova lo schema
  • norm - inizia a simulare le normali sequenze di tasti Vi
    • n - passa al modello successivo (richiesto in modalità Ex)
    • vatd - rimuovere la sezione tag esterna selezionata (vedere: saltare tra i tag html )
    • ggdG- rimuovere l'intero buffer (equivalente a :%d)
    • "2p - incollare nuovamente il testo eliminato in precedenza

Forse non molto efficiente e non POSIX ( :bufdo), ma dovrebbe funzionare.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.