Làm thế nào để phân tích hàng trăm tệp mã nguồn html trong shell?


23

Tôi có một vài trăm tệp mã nguồn html. Tôi cần trích xuất nội dung của một <div>yếu tố cụ thể từ mỗi tệp này để tôi sẽ viết một tập lệnh để lặp qua từng tệp. Cấu trúc phần tử là như thế này:

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

Bất cứ ai cũng có thể đề xuất một phương pháp mà tôi có thể trích xuất div the_div_idvà tất cả các phần tử và nội dung con từ một tệp bằng cách sử dụng dòng lệnh linux?

Câu trả lời:


27

Gói html-xml-utils , có sẵn trong hầu hết các bản phân phối Linux chính, có một số công cụ hữu ích khi xử lý các tài liệu HTML và XML. Đặc biệt hữu ích cho trường hợp của bạn là hxselectđọc từ đầu vào tiêu chuẩn và trích xuất các phần tử dựa trên bộ chọn CSS. Trường hợp sử dụng của bạn sẽ trông như sau:

hxselect '#the_div_id' <file

Bạn có thể nhận được một khiếu nại về đầu vào không được hình thành tốt tùy thuộc vào những gì bạn đang cho nó ăn. Khiếu nại này được đưa ra trên lỗi tiêu chuẩn và do đó có thể dễ dàng được loại bỏ nếu cần. Một thay thế cho điều này sẽ là sử dụng gói HTML :: PARSER của Perl; tuy nhiên, tôi sẽ để điều đó cho người có kỹ năng Perl ít gỉ hơn của tôi.


1
hxselectlà kén chọn về định dạng đầu vào hơn pup. Ví dụ, tôi nhận được Input is not well-formed. (Maybe try normalize?)với hxselect nơi pupchỉ phân tích nó.
AB

12

Hãy thử pup, một công cụ dòng lệnh để xử lý HTML. Ví dụ:

pup '#the_div_id' < file.html

Khủng khiếp!
CC

4

Đây là tập lệnh Perl chưa được kiểm tra trích xuất <div id="the_div_id">các phần tử và nội dung của chúng bằng cách sử dụng 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;
}

Nếu bạn dị ứng với Perl, Python có HTMLParser.

PS Đừng thử sử dụng các biểu thức thông thường. .


1

1

Đây là Ex one-liner để trích xuất phần đó từ mỗi tệp:

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

Để tiết kiệm / thay thế tại chỗ, thay đổi -cqa!vào -cxavà loại bỏ %pphần. Đối với đệ quy, hãy xem xét sử dụng Globing ( **/*.html).

Về cơ bản, đối với mỗi bộ đệm / tệp ( bufdo), nó thực hiện các hành động sau:

  • /pattern - tìm mẫu
  • norm - bắt đầu mô phỏng tổ hợp phím Vi bình thường
    • n - nhảy vào mẫu tiếp theo (bắt buộc trong chế độ Ex)
    • vatd- xóa phần thẻ bên ngoài đã chọn (xem: nhảy giữa các thẻ html )
    • ggdG- loại bỏ toàn bộ bộ đệm (tương đương :%d)
    • "2p - dán lại văn bản đã bị xóa

Có thể không hiệu quả lắm và không phải POSIX ( :bufdo), nhưng nó sẽ hoạt động.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.