Vinova tuyển lập trình viên Mobile & Web ở Hà Nội, lương $300-1000

Article: Phân tích cấu trúc HTML với Hpricot 1622

Ruby căn bản
tnd.myopenid.com 17
Updated over 4 years ago
Khi có nhu cầu phân tích tệp HTML hay XML, chắc mọi người nghĩ đến ngay REXML. Tuy nhiên REXML có một nhược điểm là tệp HTML phải đúng cấu trúc XHTML (XML well-formed), nếu không thì REXML sẽ không phân tích được tệp HTML. Mà đa phần các trang HTML hiện hữu đều không đúng cấu trúc XML.

Trong cuốn sách “Ruby Cookbook” tác giả có đề cập đến việc sử dụng rubyful_soupSGMLParser để phân tích các tệp HTML, tuy nhiên trong bài này tôi sẽ giới thiệu với các bạn về Hpricot, một parser linh hoạt dùng cho cả XMLHTML.

Cài đặt

Cài đặt Hpricot với rubygems rất đơn giản:

$ gem install hpricot

Nếu bạn muốn thử phiên bản đang đưọc phát triển thì có thề làm như sau:

$ gem install hpricot --source http://code.whytheluckystiff.net

Ví dụ sử dụng

Chúng ta hãy xem xét cách phân tích HTML với Hpricot qua ví dụ sau:

  
 1. #!/usr/bin/env ruby
 2. require 'rubygems'
 3. require 'open-uri'
 4. require 'net/http'
 5. require 'hpricot'
 6. 
 7. url = 'http://forum.vnoss.org'
 8. doc = Hpricot(open("#{url}/help.php"))
 9. doc.search('/html/body//img').each do |img|
10.    img_path = img.attributes['src']
11.    img_url = "#{url}/#{img_path}" 
12.    if /img\/smilies\/\w+/.match(img_path)
13.        fname = img_path.split('/')[2]
14.        File.open(fname, 'wb+')  {|f| f.write(Net::HTTP.get(URI.parse(img_url))) }
15.    end
16. end

Đoạn mã trên sẽ tải về tất cả các tệp hình ảnh chứa mặt cười từ trang VnOSS Help từ dòng 12 đến 14 là tạo tệp hình ảnh cục bộ

  • Dòng số 8 dùng hàm open của open-uri để lấy về trang web và đọc thông tin vào trong Hpricot
  • Dòng số 9 dùng cú pháp XPath ”/html/body//img” để tìm tất cả các tag “img”
  • Dòng số 10 lấy ra giá trị của thuộc tính “src” của “img”. Một khi đã có giá trị về URL của tệp hình, việc còn lại

Với đoạn mã đơn giản trên, bạn đã có thể lấy được thông tin mình cần từ một trang HTML.

Lưu ý

Một số trang web ASP.NET có sử dụng giá trị VIEW_STATE làm cho kích thước của trang web khá lớn. Để parse được các trang này Hpricot cần được cấu hình để có thể sử dụng buffer memory lớn hơn.

Với phiên bản Hpricot >= 0.5 thì ta có thể đặt lại thuộc tính đó như sau

Hpricot.buffer_size = 262144

cho văn bản <= 256KB để tránh bị lỗi OUT OF BUFFER SPACE

Tài liệu tham khảo

Bài tập cho độc giả

Hãy viết lại đoạn mã trên dùng cú pháp CSS thay vì XPath

Comments

ngocdaothanh.myopenid.com 172
over 4 years ago

Khi có nhu cầu phân tích tệp HTML hay XML, chắc mọi người nghĩ đến ngay REXML

Anh tnd có thể bàn thêm về mức độ “nổi” của REXML cũng như Hpricot được k ạ? REXML thì em đã từng dùng qua để xử lí XML, nhưng là vì thấy được giới thiệu trong quyển Ruby Cookbook nên dùng đại :D. Hpricot thì em có nghe jishin nói qua nhưng chưa có cơ hội dùng thử.

id.cntt.tv/[Anonymous] 9
over 4 years ago
REXML có chế độ streaming parse tránh cho việc nạp nguyên một file XML lớn vào bộ nhớ, còn Hpricot sẽ nạp vào bộ nhớ ngay từ đầu.
tnd.myopenid.com 17
over 4 years ago
Mặc định thì Hpricot sẽ giới hạn dung lượng bộ nhớ cho một tài liệu HTML cần parse.

Với phiên bản Hpricot >= 0.5 thì ta có thể đặt lại thuộc tính đó như sau

 Hpricot.buffer_size = 262144 

cho văn bản <= 256KB để tránh bị lỗi OUT OF BUFFER SPACE

You must login to be able to comment

Uploaded files

No file uploaded yet

You must login to be able to upload

Nhà tài trợ:

Mọi người đều tự do viết bài, sửa bài của người khác, và bình luận ở trang web này. Bạn muốn chủ động tạo bài mới để chia sẻ kinh nghiệm với mọi người? Xin click link ở dưới.

Create new content