Rút trích nội dung trang web (Web Scraping)


Bạn thấy một số trang web có nội dung hoặc dữ liệu mà bạn cần, bạn sẽ làm gì nhỉ? Nhấn Ctrl + S để lưu lại nội dung trang web đó hoặc copy phần nội dung mình thích sang Word. Vậy giả sử bạn cần lấy dữ liệu của 1 nghìn trang web về lưu vào database trên máy tính thì sao? Cách làm thủ công sẽ không thể nào khả thi trong trường hợp này. Web Scraping chính là phương pháp dùng để rút trích thông tin từ những trang web mà bạn mong muốn

Mục tiêu của bài viết này là giúp bạn hiểu được cách lấy nội dung của trang web cũng như xử lý nội dung đó để chọn lựa thông tin bạn cần từ nội dung đó. Sản phẩm demo là một chương trình cho phép bạn nhập vào một từ tiếng Anh và hiển thị cách phát âm của từ tiếng Anh đó. Chúng ta sẽ sử dụng trang web vdict.com như là nguồn dữ liệu cung cấp cách phát âm cho một từ tiếng Anh bất kỳ.

image

Sau khi bạn nhập từ tiếng Anh và nhấn nút Tìm kiếm, các việc sau sẽ được thực hiện:

  • Một Request được gửi đến trang vdict.com có kèm theo từ vừa được nhập
  • Server gửi về chuỗi HTML tương ứng. Thực hiện việc phân tích chuỗi HTML này để tìm ra vị trí chứa phần phát âm và hiển thị lên giao diện

Chúng ta sẽ lần lượt đi qua từng bước của quá trình này

1. Gửi Request đến vdict.com

vDict.com là trang web từ điển online cho phép bạn tra cứu nghĩa, cách phát âm cũng như là xem ví dụ của những từ ở nhiều ngôn ngữ khác nhau. Trong demo này chúng ta sẽ tập trung vào bộ từ điển Anh-Việt. Việc đầu tiên của Web Scraping là bạn phải biết được cách trang web nhận dữ liệu vào như thế nào. Hãy thử nhập từ “good” vào trong ô tìm kiếm và nhấn nút “Tìm”, bạn sẽ có được trang web sau
image 
Bạn hãy để ý đến URL của trình duyệt lúc này, địa chỉ sẽ là http://vdict.com/good,1,0,0.html, nghĩa là từ tiếng Anh sẽ được truyền như là một GET request thông qua URL. Chỉ cần bạn thay từ good bằng một từ khác thì kết quả trang web trả về cũng thay đổi tương ứng. Như vậy, trong C# chúng ta chỉ cần xây dựng chuỗi có dạng http://vdict.com/{word},1,0,0.html với {word} là vị trí chúng ta sẽ thay bằng từ được người dùng nhập vào.

Việc tiếp theo là phải thực hiện gửi một Request dạng GET đến địa chỉ ở bên trên. Các bạn có thể tham khảo bài viết Gửi Request trong C#để hiểu rõ hơn về cách thực hiện.

Trong ví dụ demo, tôi sử dụng lớp WebClient thay vì WebRequest, WebClient là một lớp ở mức cao hơn của WebRequest cho phép bạn nhanh chóng thực hiện các thao tác gửi Request và nhận dữ liệu từ Server. Cách sử dụng WebClient rất là dễ dàng, bạn có thể tham khảo http://www.dotnetperls.com/webclient hoặc xem code demo.

2. Phân tích chuỗi HTML trả về

Bạn gửi request lên server và nhận được chuỗi HTML từ server dùng để hiển thị trên trình duyệt. Tuy nhiên, thay vì hiển thị cả chuỗi HTML, chúng ta chỉ quan tâm tới thành phần có chứa phát âm của chuỗi HTML này. Bằng cách sử dụng các công cụ soi mã HTML trên Chrome hoặc Firefox, ta có thể dễ dàng biết được chuỗi phát âm đó nằm ở đâu

image

Như trên hình, chúng ta thấy được rằng chuỗi phát âm của từ “good” nằm trong một thẻ <div> có class là pronounce. Chỉ cần phân tích chuỗi HTML và tìm ra vị trí chính xác của thẻ <div> này là có thể lấy được nội dung bên trong nó.

Có nhiều cách để tìm kiếm chuỗi theo mẫu, bạn có thể tìm kiếm tuần tự, sử dụng phương thức IndexOf của string hoặc dùng Regular Expression. Tuy nhiên các cách này có thể đòi hỏi bạn thực hiện nhiều thao tác so sánh và kết quả có thể không chính xác. Ở đây, tôi sử dụng thư viện HtmlAgilityPack để phân tích nội dung trang web. Thư viện này cho phép bạn duyệt qua nội dung HTML như là một tài liệu XML bằng cách sử dụng cú pháp của XPath. Sử dụng HtmlAgilityPack làm cho code của bạn sáng sủa và dễ hiểu hơn rất nhiều. Trong chương trình demo, sau khi đã có được chuỗi HTML, tôi sử dụng đoạn code sau để tìm ra chính xác thẻ <div class=”pronounce”> như sau:

HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
document.LoadHtml(html);
HtmlNode divNode = document.DocumentNode.SelectSingleNode("//div[@class='pronounce']");

Cú pháp XPath: //div[@class=’pronounce’] có nghĩa là: chọn ra thẻ <div> tại bất kỳ vị trí nào trong chuỗi HTML mà có thuộc tính class là pronounce. Biến divNode là kết quả trả về chứa thông tin của thẻ <div> tìm thấy. Lưu ý nếu như không tìm thấy thẻ tương ứng thì divNode sẽ có giá trị null.

Các bạn có thể download chương trình demo tại đây: VDictPronunciation

Kết luận: Qua bài viết này, các bạn có thể hiểu rõ hơn về Web Scraping cũng như cách thức thực hiện nó. Tôi có thể nói với bạn rằng đây là phương pháp sẽ cực kỳ hữu dụng với các bạn sau này. Tôi còn nhớ đã từng có lần được yêu cầu phải tải Quốc kỳ của hơn 200 quốc gia trên thế giới từ một trang web và đổi tên file tương ứng với quốc gia đó. Tôi đã dùng Web Scraping và nhanh chóng tải tất cả về máy chỉ trong khoảng 15 phút (với 14 phút là dùng để viết code ^_^). Và tôi tin rằng bạn đã có thể bắt đầu xây dựng cho mình một trang tổng hợp tin tức tự động từ web như phương pháp đã trình bày ở trên.

Tác giả: xuanchien

Tran Xuan Chien. Japan Advanced Institute of Science and Technology - Japan. Senior Developer - NUS Technology.

17 thoughts on “Rút trích nội dung trang web (Web Scraping)”

  1. Bạn ơi cho mình hỏi là hiện tại mình có down 01 cái file của web. Trong cái đống tập tin đó có phần dữ liệu được trích trên scribd (người ta nhúng cái file pdf đó zô cái trang đó) mình mún lấy cái file pdf đó thì làm sao? Bạn có yahoo ko cho mình xin với. Thanks nha. Yahoo mình là an_huynh39@yahoo.com

      1. Nếu trang web đó sử dụng Flash thì sẽ không lấy được nội dung bên trong flash đâu bạn.

        Regards,

        Tran Xuan Chien School of Information Science Japan Advanced Institute of Science and Technology (JAIST)

        >

  2. Trước tiên mình cảm ơn bạn vì những bài viết rất hay.
    Cho mình hỏi một tí : mình muốn viết một phần mềm có thể upload một ảnh lên website lưu trữ trực tuyến sau đấy lấy link trực tiếp của ảnh đấy thì nên bắt đầu như thế nào nhỉ ví dụ : upanh.com

  3. Mong bạn giúp mình vấn đề này, bỏ vào vòng lặp foreach nó chỉ trả về 1 kết quả duy nhất nên mình không đưa vào list được. Mình lấy dữ liệu từ đây http://vtv.vn/LichPS/GetLichPhatsong?nam=2012&thang=8&ngay=5&kenh=VTV1
    Code :
    foreach (HtmlNode row in doc.DocumentNode.SelectNodes(“//tr”))
    {
    HtmlNode timeNode = row.SelectSingleNode(“//nobr”);
    time += timeNode.InnerHtml + “—————–“;
    }
    textBox1.Text = time;
    Và kết quả trả về :
    00h : 00—————-00h : 00—————–
    Có nghĩa là nó chỉ lấy 1 timeNode từ đầu đến cuối. Mình đã thử nhiều cách sử dụng XPath khác nhau nhưng vẫn không được, và mình cũng nghĩ là lỗi ở đấy thôi. Nếu ta lấy //tr bằng selectSingleNode thì vẫn ok, duyệt foreach với row.innerHtml vẫn ok. Mình không hiểu nó bị lỗi chỗ nào nữa, mong bạn có thể giúp mình. Thanks and brgrds !

  4. Mình có đề tài về rút trích thực thể trên các trang web để đưa vào cơ sở dữ liệu, bạn có thể hướng dẫn mình vấn đề này được ko

  5. chào bạn. vậy bây giờ chúng ta muốn tải file video từ trang Newtitan.com ví dụ:
    http://newtitan.vn/karaoke/play/chi-con-trong-ky-uc-ho-quang-hieu.titan
    thì bạn cso thể hướng đẫn tải file từ trang này không? tôi đã làm tải được có 1 pphaanf vi deo. ví dụ: file có dung lượng 40MB nhưng tôi chỉ tải dược cso tầm 10 đến 15 MB thì nó không tải được nữa và khi xem video vân xem được khúc đầu. đến phần tiếp theo thì trình WMP cũng đứng không chạy video nữa

    1. Cái đó là do website đó đã rất thông minh, chặn không cho user có thể lấy video của họ tự động bằng cách chia nhỏ 1 video ra thành nhiều phần khác nhau. Muốn lấy full thì mình phải biết cách làm sao đó lấy được từng phần của video. Việc này không dễ và cần phải phân tích kỹ cái website đó. Mình không thể giúp được trong trường hợp này.

      >

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s