Văn bản giữa hai thẻ


23

Tôi muốn lấy bất cứ thứ gì nằm giữa hai thẻ này - <tr> </tr>- từ một tài liệu html. Bây giờ tôi không có bất kỳ yêu cầu html cụ thể nào sẽ đảm bảo cho trình phân tích cú pháp html. Tôi chỉ đơn giản cần một cái gì đó mà trận đấu <tr></tr>và được tất cả mọi thứ ở giữa và có thể có nhiều trs. Tôi đã thử awk, nó hoạt động, nhưng vì một số lý do, cuối cùng nó cho tôi các bản sao của mỗi hàng được trích xuất.

awk '
/<TR/{p=1; s=$0}
p && /<\/TR>/{print $0 FS s; s=""; p=0}
p' htmlfile> newfile

Làm thế nào để đi về điều này?


IIUC kịch bản awk của bạn nên : '/<tr/{p=1}; p; /<\/tr>/{p=0}'. Đăng một số ví dụ đầu vào và đầu ra dự kiến ​​nếu nó không hoạt động.
Thor

vì bạn awkđang làm việc nhưng đưa ra các bản sao cố gắng vượt qua đầu ra của awk của bạn sort -uđể làm cho chúng khác biệt
igiannak

Câu trả lời:


14

Nếu bạn chỉ muốn ...tất cả <tr>...</tr>làm:

grep -o '<tr>.*</tr>' HTMLFILE | sed 's/\(<tr>\|<\/tr>\)//g' > NEWFILE

Đối với đa dòng làm:

tr "\n" "|" < HTMLFILE | grep -o '<tr>.*</tr>' | sed 's/\(<tr>\|<\/tr>\)//g;s/|/\n/g' > NEWFILE

Kiểm tra HTMLFILE trước tiên của char "|" (không thông thường, nhưng có thể) và nếu nó tồn tại, hãy đổi thành một thứ không tồn tại.


1
Điều đó sẽ chỉ hoạt động nếu các thẻ bắt đầu và kết thúc nằm trên cùng một dòng.
l0b0

echo "bla<tr>foo</tr>bla<tr>bar</tr>bla" | grep -o '<tr>.*</tr>' | sed 's/\(<tr>\|<\/tr>\)//g'cho fooblabar. Có blanên ở đó không?
NN

@ l0b0 đúng. sẽ sử dụng loại tương thích đa dòng ...
xx4h

grep -Po '<tr>.*?</tr>'sẽ trả về một kết quả trên mỗi dòng trong trường hợp của @ NN, nhưng nó không mang tính di động.
l0b0

Tôi không chắc ý của bạn là 'thông số kỹ thuật' hay 'phong cách đặc tả' nhưng lưu ý rằng trình duyệt web của bạn sử dụng trình phân tích cú pháp html và trình phân tích cú pháp html sẽ phân tích cú pháp html bất kể nó được viết như thế nào. Nó sẽ không phân tích những thứ không phải là html, nhưng sau đó, trình duyệt của bạn cũng vậy, vì vậy không ai sẽ bận tâm viết "html" mà trình phân tích cú pháp không thể phân tích cú pháp. Nói cách khác: Một trình phân tích cú pháp tốt hoàn toàn chắc chắn là đặt cược tốt nhất của bạn để làm điều này.
goldilocks

11

Bạn có một yêu cầu bảo đảm một trình phân tích cú pháp HTML: bạn cần phân tích cú pháp HTML. HTML của Perl :: TreeBuilder , BeautifulSoup của Python và các công cụ khác rất dễ sử dụng, dễ dàng hơn so với việc viết các biểu thức thông thường phức tạp và dễ vỡ.

perl -MHTML::TreeBuilder -le '
    $html = HTML::TreeBuilder->new_from_file($ARGV[0]) or die $!;
    foreach ($html->look_down(_tag => "tr")) {
        print map {$_->as_HTML()} $_->content_list();
    }
' input.html

hoặc là

python -c 'if True:
    import sys, BeautifulSoup
    html = BeautifulSoup.BeautifulSoup(open(sys.argv[1]).read())
    for tr in html.findAll("tr"):
        print "".join(tr.contents)
' input.html

9

sedawkkhông phù hợp cho nhiệm vụ này, bạn nên sử dụng một trình phân tích cú pháp html thích hợp. Ví dụ hxselecttừ w3.org:

<htmlfile hxselect -s '\n' -c 'tr'

Tôi không biết nếu hxselect là lựa chọn tốt nhất; Tôi đã không sử dụng nó nhưng trang người đàn ông nói rằng "đọc một tài liệu XML được định dạng tốt" mà nhiều tài liệu html thì không. Có lẽ đáng để thử tho. Các trình phân tích cú pháp html libs có sẵn cho perl, python, et. al. sẽ tốt hơn nhiều, nếu đó là một lựa chọn.
goldilocks

2
@goldilocks: Lựa chọn tốt nhất tùy thuộc vào tình huống. Theo kinh nghiệm của tôi, hxselectcông việc khá tốt với các tài liệu html / xml được hình thành tốt. Ngoài ra, nó nhanh hơn để sử dụng hơn perl, python và những người khác. Tôi nghĩ hxselectlà một trung gian tốt giữa sed/ awkvà libs trình phân tích cú pháp.
Thor

1
Nếu nó hoạt động thật tuyệt! Tôi chỉ thêm một lời cảnh báo cho TechJack trong trường hợp không được - vì tôi cũng đã khuyến nghị sử dụng một số loại trình phân tích cú pháp;)
goldilocks

Thor, có hxselectvẻ tốt, chắc chắn sẽ khám phá nó nhiều hơn. Cảm ơn.
TechJack

@goldilocks: hxnormalizechăm sóc các tệp html / xml không được định dạng tốt.
tokland

5

Nếu rubycó sẵn bạn có thể làm như sau

ruby -e 'puts readlines.join[/(?<=<tr>).+(?=<\/tr>)/m].gsub(/<\/?tr>/, "")' file

filetập tin html đầu vào của bạn ở đâu Lệnh thực thi một Ruby-liner. Đầu tiên, nó đọc tất cả các dòng từ filevà nối chúng thành một chuỗi , readlines.join. Sau đó, từ chuỗi, nó chọn bất cứ thứ gì giữa (nhưng không bao gồm) <tr><\/tr>đó là một ký tự hoặc dài hơn bất kể dòng mới , [/(?<=<tr>).+(?=<\/tr>)/m]. Sau đó, nó loại bỏ bất kỳ <tr>hoặc </tr>khỏi chuỗi, gsub(/<\/?tr>/, "")(điều này là cần thiết để xử lý các trthẻ lồng nhau ). Cuối cùng, nó in chuỗi , puts.

Bạn nói rằng một phân tích cú pháp html không bảo hành cho bạn, nhưng nó là rất dễ sử dụng Nokogiri với rubyvà nó làm cho các lệnh đơn giản hơn.

ruby -rnokogiri -e 'puts Nokogiri::HTML(readlines.join).xpath("//tr").map { |e| e.content }' file

-rnokogiritải Nokogiri. Nokogiri::HTML(readlines.join)đọc tất cả các dòng của file. xpath("//tr")chọn ra mọi tryếu tố và map { |e| e.content }chọn ra nội dung cho từng yếu tố, tức là những gì nằm giữa <tr></tr>.


1

grep

Để lấy nội dung trong trthẻ qua nhiều dòng, xargsví dụ: chuyển qua nội dung trước:

curl -sL https://www.iana.org/ | xargs | egrep -o "<tr>.*?</tr>"

Để chỉ trả lại HTML bên trong, hãy sử dụng:

curl -sL https://www.iana.org/ | xargs | grep -Po "<tr>\K(.*?)</tr>" | sed "s/..tr.//g"

Kiểm tra cú pháp cho perlrecác mẫu mở rộng .

Lưu ý: Để có hiệu suất nhanh hơn, bạn có thể xem xét ripgrepcái nào có cú pháp tương tự.


nó được in ra trông đẹp hơn mà không cần xargs, rất tiện để tìm javascript nội tuyến bằng cách sử dụng egrep -o "<script. *? </ script>"
Andrew

0

pup

Ví dụ sử dụng pup(sử dụng bộ chọn CSS ):

pup -f myfile.html tr

Để chỉ in văn bản không có thẻ, sử dụng : pup -f myfile.html tr text{}.

Dưới đây là một vài ví dụ với curl:

curl -sL https://www.iana.org/ | pup tr text{}
pup -f <(curl -sL https://www.iana.org/) tr text{}

xpup

Ví dụ sử dụng xpupđể phân tích cú pháp HTML / XML (hỗ trợ XPath):

xpup -f myfile.html "//tr"

0

nếu nó chỉ là một danh sách nhanh của <tr>s thì điều này có thể giúp:

perl -ne 'print if /<tr>/../</tr>/' your.html > TRs.log

chúc mừ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.