Bagaimana cara mem-parsing seratus file kode sumber html di shell?

23

Saya punya beberapa ratus file kode sumber html. Saya perlu mengekstraksi konten <div>elemen tertentu dari masing-masing file ini jadi saya akan menulis skrip untuk mengulangi setiap file. Struktur elemennya seperti ini:

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

Adakah yang bisa menyarankan metode dimana saya dapat mengekstrak div the_div_iddan semua elemen anak dan konten dari file menggunakan baris perintah linux?

Conorgriffin
sumber

Jawaban:

27

Paket html-xml-utils , tersedia di sebagian besar distribusi Linux utama, memiliki sejumlah alat yang berguna ketika berhadapan dengan dokumen HTML dan XML. Yang sangat berguna untuk kasus Anda adalah hxselectyang membaca dari input standar dan mengekstraksi elemen berdasarkan pemilih CSS. Kasus penggunaan Anda akan terlihat seperti:

hxselect '#the_div_id' <file

Anda mungkin mendapatkan keluhan tentang input yang tidak terbentuk dengan baik tergantung pada apa yang Anda berikan. Keluhan ini diberikan karena kesalahan standar dan dengan demikian dapat dengan mudah ditekan jika diperlukan. Alternatif untuk ini adalah dengan menggunakan paket Perl :: HTML PARSER; Namun, saya akan menyerahkan itu kepada seseorang dengan keterampilan Perl kurang berkarat dari saya.

Steven D
sumber
1
hxselectlebih pilih-pilih tentang format input daripada pup. Misalnya, saya mendapatkan Input is not well-formed. (Maybe try normalize?)dengan hxselect mana puphanya parsing itu.
AB
12

Coba pup, alat baris perintah untuk memproses HTML. Sebagai contoh:

pup '#the_div_id' < file.html
Trevor Dixon
sumber
Terrrrrifik!
CC
4

Berikut skrip Perl yang belum teruji yang mengekstraksi <div id="the_div_id">elemen dan kontennya menggunakan 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;
}

Jika Anda alergi terhadap Perl, Python menderita HTMLParser.

PS Jangan coba-coba menggunakan ekspresi reguler. .

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Python memiliki seluruh doc.scrapy.org/en/latest/intro/overview.html ;)
AB
1

Berikut adalah Ex one-liner untuk mengekstrak bagian itu dari setiap file:

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

Untuk menyimpan / mengganti di tempat, ubah -cqa!menjadi -cxadan hapus %pbagian. Untuk rekursif, pertimbangkan menggunakan globbing ( **/*.html).

Pada dasarnya untuk setiap buffer / file ( bufdo), ia melakukan tindakan berikut:

  • /pattern - temukan polanya
  • norm - mulai mensimulasikan penekanan tombol Vi normal
    • n - lompat ke pola berikutnya (diperlukan dalam mode Ex)
    • vatd- hapus bagian tag luar yang dipilih (lihat: beralih di antara tag html )
    • ggdG- hapus seluruh buffer (setara dengan :%d)
    • "2p - Tempel ulang teks yang sudah dihapus sebelumnya

Mungkin tidak terlalu efisien dan bukan POSIX ( :bufdo), tetapi harus bekerja.

kenorb
sumber