Thứ hai, 16/09/2013 | 00:00 GMT+7

Cách sử dụng node.js, request và cheerio để thiết lập Web-Scraping đơn giản


Giới thiệu:

Trong hướng dẫn này, ta sẽ lược bỏ trang đầu của Hacker News để lấy tất cả các liên kết xếp hạng hàng đầu cũng như metadata của chúng - chẳng hạn như tiêu đề, URL và số điểm / comment mà nó nhận được. Đây là một trong nhiều kỹ thuật extract dữ liệu từ các trang web bằng node.js và chủ yếu sử dụng một module có tên là cheerio của Matthew Mueller, module này triển khai một tập hợp con của jQuery được thiết kế đặc biệt cho việc sử dụng server .

Cheerio nhẹ, nhanh, linh hoạt và dễ sử dụng, nếu bạn đã quen làm việc với jQuery. Ta cũng sẽ sử dụng module yêu cầu tuyệt vời của Mikael Rogers như một ứng dụng HTTP đơn giản hóa.

Yêu cầu:

Tôi sẽ giả sử rằng bạn đã quen thuộc với node.js, jQuery và các việc quản trị Linux cơ bản như kết nối với VPS của bạn bằng SSH.

Nếu bạn không quen với node.js hoặc nếu bạn chưa cài đặt nó, vui lòng tham khảo phần Bài viết & Hướng dẫn ở trên để tìm hướng dẫn cài đặt cho hệ điều hành của bạn.

Mã:

Để cài đặt các module cần thiết bằng NPM, chỉ cần nhập lệnh sau:

npm install request cheerio

Thao tác này sẽ chỉ cài đặt các module trong folder làm việc hiện tại của bạn.

Để cài đặt các module chạy trên phạm vi global : npm install -g request cheerio

Tạo một file có tên là scrape.js và thêm các dòng sau:

  var request = require('request');  var cheerio = require('cheerio');  

Điều này sẽ tải tất cả các phụ thuộc module của ta .

Bây giờ ta sẽ tải trang đầu của Hacker News với một yêu cầu đơn giản và hiển thị mã HTML của trang, nếu không có lỗi xảy ra và mã trạng thái HTTP bằng 200.

Nối các dòng này vào file :

  request('https://news.ycombinator.com', function (error, response, html) {    if (!error && response.statusCode == 200) {      console.log(html);    }  });  

Hãy thử chạy tập lệnh bằng node scrape.js và bạn sẽ thấy mã HTML được ghi trong cửa sổ terminal của bạn.

Để biết cách extract metadata mong muốn của ta , ta cần biết cách các phần tử được cấu trúc trong mã HTML. Một cách ưa thích là sử dụng các công cụ dành cho nhà phát triển web được tích hợp trong Google Chrome để kiểm tra phần tử mục tiêu mong muốn trên trang web chỉ bằng cách nhấp chuột phải vào phần tử đó và chọn "Kiểm tra phần tử".

Trong ví dụ này, tôi đã mở Hacker News trong Chrome, nhấp chuột phải và kiểm tra tiêu đề của câu chuyện xếp hạng hàng đầu:

Công cụ dành cho nhà phát triển web trên Chrome

Sau khi xem nhanh console dành cho nhà phát triển web, tôi đi đến kết luận rằng ta có thể chỉ cần chọn mỗi phần tử "span" có một lớp được thêm vào nó có tên "comhead" và chọn phần tử "a" phía trên nó bằng cách sử dụng jQuery Hàm API prev () để dễ dàng phân tích cú pháp tất cả 30 liên kết xếp hạng hàng đầu và tiêu đề của chúng.

Ta có thể kiểm tra giả định của bạn bằng cách thay đổi mã yêu cầu của ta thành:

  request('https://news.ycombinator.com', function (error, response, html) {    if (!error && response.statusCode == 200) {      var $ = cheerio.load(html);      $('span.comhead').each(function(i, element){        var a = $(this).prev();        console.log(a.text());      });    }  });  

Như mong đợi, bằng cách chạy mã, ta nhận được danh sách 30 tiêu đề. Hãy sửa đổi nó nhiều hơn một chút để phân tích cú pháp metadata còn lại:

  request('https://news.ycombinator.com', function (error, response, html) {    if (!error && response.statusCode == 200) {      var $ = cheerio.load(html);      $('span.comhead').each(function(i, element){        var a = $(this).prev();        var rank = a.parent().parent().text();        var title = a.text();        var url = a.attr('href');        var subtext = a.parent().parent().next().children('.subtext').children();        var points = $(subtext).eq(0).text();        var username = $(subtext).eq(1).text();        var comments = $(subtext).eq(2).text();        // Our parsed meta data object        var metadata = {          rank: parseInt(rank),          title: title,          url: url,          points: parseInt(points),          username: username,          comments: parseInt(comments)        };        console.log(metadata);      });    }  });  

Dưới đây là Tổng quan về những gì Mã được Thêm vào:

Chọn phần tử trước:

  var a = $(this).prev();  

Nhận thứ hạng bằng cách phân tích cú pháp phần tử hai cấp phía trên phần tử "a":

  var rank = a.parent().parent().text();  

Phân tích cú pháp tiêu đề liên kết:

  var title = a.text();  

Phân tích cú pháp thuộc tính href từ phần tử "a":

  var url = a.attr('href');  

Lấy các phần con của văn bản phụ từ hàng tiếp theo trong bảng HTML:

  var subtext = a.parent().parent().next().children('.subtext').children();  

Extract dữ liệu liên quan từ trẻ em:

  var points = $(subtext).eq(0).text();  var username = $(subtext).eq(1).text();  var comments = $(subtext).eq(2).text();  

Chạy tập lệnh đã sửa đổi sẽ xuất ra một mảng các đối tượng như sau:

  [ { rank: 1,      title: 'The Meteoric Rise of DigitalOcean ',      url: 'http://news.netcraft.com/archives/2013/06/13/the-meteoric-rise-of-digitalocean.html',      points: 240,      username: 'beigeotter',      comments: 163 },    { rank: 2,      title: 'Introducing Private Networking',      url: 'https://www.digitalocean.com/blog_posts/introducing-private-networking',      points: 172,      username: 'Goranek',      comments: 75 },  ...  

Đó là nó! Đến đây bạn có thể lưu trữ dữ liệu được extract trong database như MongoDB hoặc Redis để xử lý thêm. Đây là mã nguồn đầy đủ của file scrape.js của ta :

  var request = require('request');  var cheerio = require('cheerio');    request('https://news.ycombinator.com', function (error, response, html) {    if (!error && response.statusCode == 200) {      var $ = cheerio.load(html);      var parsedResults = [];      $('span.comhead').each(function(i, element){        // Select the previous element        var a = $(this).prev();        // Get the rank by parsing the element two levels above the "a" element        var rank = a.parent().parent().text();        // Parse the link title        var title = a.text();        // Parse the href attribute from the "a" element        var url = a.attr('href');        // Get the subtext children from the next row in the HTML table.        var subtext = a.parent().parent().next().children('.subtext').children();        // Extract the relevant data from the children        var points = $(subtext).eq(0).text();        var username = $(subtext).eq(1).text();        var comments = $(subtext).eq(2).text();        // Our parsed meta data object        var metadata = {          rank: parseInt(rank),          title: title,          url: url,          points: parseInt(points),          username: username,          comments: parseInt(comments)        };        // Push meta-data into parsedResults array        parsedResults.push(metadata);      });      // Log our finished parse results in the terminal      console.log(parsedResults);    }  });  

Tags:

Các tin liên quan

Cách tạo một ứng dụng web nhỏ với CakePHP trên VPS (Phần 1)
2013-08-23
Cách mở rộng ứng dụng web trên Ubuntu 12.10
2013-04-11