Các phương pháp crawl dữ liệu và code mẫu chi tiết

Bear Technology

2018/07/13

Bài viết sẽ hướng dẫn bạn từ khái niệm đến code mẫu chi tiết, giúp bạn có thể tự viết công cụ crawl dữ liệu cho riêng mình

Trước khi bắt đầu, các bạn có thể đọc qua khái niệm về crawl ở bài viết dưới đây:

Lưu ý: Trong bài này, mình sẽ demo song song code C# & nodejs, các code mẫu này có thể chưa tối ưu & còn lỗi tiềm ẩn, các bạn cân nhắc & chỉnh sửa lại khi dùng thực tế.

Phải làm sao?

Hiểu theo tư duy lập trình thì crawl là ta phải tải toàn bộ mã html của trang gốc về, sau đó sử dụng các phương pháp lập trình để bóc tách được phần nội dung mà ta muốn.

Bắt tay vào code thôi!

Vậy thì tải toàn bộ mã html của trang gốc bằng cách nào? nói chung là có rất nhiều cách, ví dụ 1 số cách như sau:

Với C# thì bạn có thể sử dụng WebRequest, code sẽ là:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create('https://beartech.vn/crawler-thu-thap-thong-tin-tu-dong-la-gi--4890.htm');
request.Method = "GET";
var response = (HttpWebResponse)request.GetResponse();
var responseString = "";
using (StreamReader r = new StreamReader(response.GetResponseStream()))
{
    responseString = r.ReadToEnd();
}

`responseString` chính là toàn bộ mã nguồn của trang. 

Với nodejs thì sẽ là:

var request = require('request');
request('https://beartech.vn/crawler-thu-thap-thong-tin-tu-dong-la-gi--4890.htm', function (error, response, html) {
     //tương tự như trên, html cũng là mã nguồn của trang mà bạn muốn lấy
});

Sau khi đã lấy được mã nguồn trang gốc, bóc tách được phần nội dung mà ta muốn như thế nào?

Việc này thì rất đơn giản khi đã có đoạn html nguồn, việc tiếp theo chỉ là lựa chọn phương thức để bóc tách. Về cơ bản chi làm 2 hướng:

  • Làm việc với html string qua regular expression (regex)
  • Parse html về Document Object Model (DOM) sau đó sử dụng các selector để lấy dữ liệu (kết hợp với regex để xử lý thêm dữ liệu trả ra cuối cùng nếu cần thiết)

Với C#

  • Nếu dùng DOM thì C# có 2 thư viện khá tốt:
  • Sử dụng Regular Expression (Regex) - vì sử dụng Regex thao tác với html có nhiều hạn chế, chỉ nên sử dụng khi không dùng được DOM (lấy danh sách email, link ảnh...)

Với NodeJs

  • Cheeriojs: jQuery chạy trên Nodejs
  • Jsdom: thư viện làm việc với DOM trên nodejs
  • YUI: thư viện js của Yahoo (đã ngừng phát triển)

Trong nội dung bài này, mình sẽ sử dụng HAP cho C# và Cheeriojs cho Nodejs, vì mình thấy 2 thư viện này khá dễ dùng, và để ví dụ về 2 phương thức bóc tách khác nhau: Xpath & DOM query

C#: HtmlAgilityPack

Mình bỏ qua các bước hướng dẫn tải thư viện, import vào project mà đi vào code sử dụng mẫu luôn.

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.OptionFixNestedTags = true;
htmlDoc.OptionCheckSyntax = false;
htmlDoc.LoadHtml(responseString); //responseString là đoạn html mà bạn lấy được ở phần trước.
var nodes = htmlDoc.DocumentNode.SelectNodes("//*[contains(@class,'post-title')]");

Ở ví dụ này, mình tiến hành lấy tiêu đề bài viết (class post-title) (bỏ qua các bước check null...) Sau khi đã lấy ra được tập các node chứa nội dung mình muốn, chỉ cần duyệt từng node và lấy nội dung ra thôi:

foreach (HtmlNode node in nodes)
{
    var title = node.InnerText; // Tiêu đề bài viết muốn lấy.
}

Làm tương tự ta sẽ lấy được các thông tin cần lấy.

NodeJs: CheerioJs

var $ = cheerio.load(responseString); //responseString là đoạn html mà bạn lấy được ở phần trước.
var title = $('.post-title').text(); //Tiêu đề bài viết muốn lấy.

Rất đơn giản phải không nào?

Dựa vào các đoạn code cơ bản này, các bạn có thể viết chương trình crawl tự động toàn bộ website hoặc các thành phần mong muốn. Chúc các bạn thành công!

DMCA.com Protection Status Bản quyền bài viết thuộc về Bear Technology. Vui lòng tôn trọng bản quyền.

Bài viết khác