Nodejs - Các kỹ thuật Crawler, rút trích dữ liệu với Nodejs
Note: This post is over 11 years old. The information may be outdated.
Nhân dịp tuyển sinh ĐH này, mình có project về thu thập dữ liệu tuyển sinh của các thí sinh trên trang của các trường ĐH. Project này mục tiêu là thu thập toàn bộ thông tin của thí sinh (SBD, tên, tuổi, điểm các môn, nguyện vọng các ngành, trường mà thí sinh nộp xét tuyển, ...). Điều oái oăm là mỗi trường công bố dữ liệu 1 cách hết sức ... tùm lum và tào lao. Có trường hiện đại thì show dữ liệu trực tiếp lên web, trường thì up đại 1 file excel, oái hơn là bỏ vào file pdf :v Nhiệm vụ của mình là thu thập dữ liệu từ nhiều nguồn thô như vậy một cách tự động. Mỗi trường được viết thành 1 module riêng và có cách để crawler riêng. Bài viết này chủ yếu giới thiệu về các dạng để crawler đặc trưng nhất, và cho thấy được sức mạnh của Nodejs.
LƯU Ý (2025): Bài viết này được viết từ năm 2015 và chủ yếu là tài liệu tham khảo lịch sử. Các kỹ thuật cơ bản về web scraping vẫn còn có giá trị, nhưng hệ sinh thái Node.js đã phát triển đáng kể. Hiện nay, bạn nên xem xét sử dụng các công cụ hiện đại hơn như Puppeteer, Playwright, hoặc Cheerio thay vì node-crawler.
Github project
Có thể xem thêm code của project tại Github tại đây: https://github.com/duyet/Crawler-DKXT-DH-2015
Bóc tách bảng HTML và dò đường (với bảng có phân trang)
Đây là cách dễ và cũng là dạng crawler phổ biến nhất. Với bảng có phân trang, chúng ta phải lập trình để spider có thể dò được link của trang tiếp theo cho đến khi lấy hết được nội dung.
Mình sử dụng package node-crawler (npm package: crawler, source: https://github.com/duyet/node-crawler)
Cài đặt:
$ npm install crawler
Crawler module có khả năng:
- Bóc tách HTML theo DOM
- Có thể sử dụng selector của jQuery backend để dò và lấy các phần tử trong trang.
- Điều chỉnh được pool size, số lần request, retries (thử lại nếu request thất bại)
- Điều chỉnh độ ưu tiên của các link.
var Crawler = require('crawler')
var url = require('url')
var c = new Crawler({
maxConnections: 10,
// This will be called for each crawled page
callback: function (error, result, $) {
// $ is Cheerio by default
//a lean implementation of core jQuery designed specifically for the server
$('a').each(function (index, a) {
var toQueueUrl = $(a).attr('href')
c.queue(toQueueUrl)
})
},
})
// Queue just one URL, with default callback
c.queue('http://joshfire.com')
// Queue a list of URLs
c.queue(['http://jamendo.com/', 'http://tedxparis.com'])
// Queue URLs with custom callbacks & parameters
c.queue([
{
uri: 'http://parishackers.org/',
jQuery: false,
// The global callback won't be called
callback: function (error, result) {
console.log('Grabbed', result.body.length, 'bytes')
},
},
])
// Queue using a function
var googleSearch = function (search) {
return 'http://www.google.fr/search?q=' + search
}
c.queue({
uri: googleSearch('cheese'),
})
// Queue some HTML code directly without grabbing (mostly for tests)
c.queue([
{
html: '<p>This is a <strong>test</strong></p>',
},
])
Ghi chú
Bài viết gốc được viết để hướng dẫn các kỹ thuật crawling cơ bản. Project tham khảo hoàn chỉnh với các ví dụ thực tế có sẵn trên GitHub. Để tìm hiểu thêm về các kỹ thuật crawling hiện đại, bạn có thể tham khảo thêm các công cụ và thư viện được nhắc đến ở phần lưới ứuc ở trên.