Node.js实战cheerio网页抓取器

网络抓取要识别Web页面,并将其转换成结构化数据。比如说,你要负责升级出版社那古老的静态网站,需要把之前的页面下载下来,经过分析后提取所有图书的书名、介绍、作者和售价。你肯定不想自己手工完成这项任务,所以决定写个Node程序来做这件事。这种程序就是网络抓取器。
                           —— 《Node.js实战》 (第2版) P267

Node.js实战cheerio网页抓取器_第1张图片
Node.js实战 封面

找个出版社的静态网页,图灵社区不就是个正好的对象吗,那就以Node.js实战(第2版)这本书为例吧!


1、提取图书书名

详情页中图书名称HTML代码

Node.js实战(第2版)

提取片段的cheerio代码如下

const html = `
    

Node.js实战(第2版)

`; const cheerio = require('cheerio'); const $ = cheerio.load(html); console.log($('.book-title h2').text().trim());

2、提取简介

本书是Node.js的实战教程,涵盖了为开发产品级Node应用程序所需要的一切特性、技巧以及相关理念。 从搭建Node开发环境,到一些简单的演示程序,到开发复杂应用程序所必不可少的异步编程。第2版介绍了全栈开发者所需的全部技术,包括前端构建系统、选择Web框架、在Node中与数据库的交互、编写测试和部署Web程序,等等。

提取代码如下

$('.book-intro').text().trim();

3、提取作者

上面两个比较简单,只是热热身,作者的提取就稍微有些麻烦了。

HTML代码

[英] 亚历克斯•杨 等 (作者) 吴海星 (译者)

可以看到有一个作者,有一个译者,怎么把他们分别提取出来呢。我们先看看下面的代码

console.log($('.book-author').children().length);

运行的结果是2,说明在book-author这个节点下面有两个子节点,这与我们看到的HTML代码相符。

用一个each函数遍历,并把它们分别打印出来:

$('.book-author').children().each((i, e)=>{
  console.log($(e).text().trim());
});

再做些进一步的处理

$('.book-author').children().each((i, e)=>{
  
  let 名字 = $(e).text().trim();
  if (名字.indexOf('(作者)')  != -1) {
    console.log('作者:', 名字.replace(/\(作者\)/, '').trim());
  }

  if (名字.indexOf('(译者)')  != -1) {
    console.log('译者:', 名字.replace(/\(译者\)/, '').trim());
  }
});

完整代码

const superagent = require('superagent');
const cheerio = require('cheerio');

const url = 'http://www.ituring.com.cn/book/1993';

superagent.get(url).end( function(err, res) {
    // 抛错拦截
    if (err) {
        return
        throw Error(err)
    }

    const book = {};

    let $ = cheerio.load(res.text,{
        decodeEntities: false
    });

    book.title = $('.book-title h2').text().trim();

    book.intro = $('.book-intro').text().trim();

    book.status = 出版状态 = $('li:contains("出版状态")').text().replace(/出版状态/, '');

    $('.book-author').children().each((i, e)=>{
  
        let 名字 = $(e).text().trim();
        if (名字.indexOf('(作者)')  != -1) {
          book.auther = 名字.replace(/\(作者\)/, '').trim();
        }
      
        if (名字.indexOf('(译者)')  != -1) {
          book.translator = 名字.replace(/\(译者\)/, '').trim();
        }
    });

    let 定价 = $('li:contains("定  价")').text().replace(/定  价/, '');

    if (定价) {
        book.price = 定价;

        let 有电子书 = false;
        
        let 找电子书 = $('dt').filter( function() {
            let 有吗 = $(this).text().trim() === '电子书';
            if (有吗 === true) {
                有电子书 = true;
                return true;
            }
        });

        if (有电子书) {
            book.ePrice = 找电子书.next().children('.price').text().trim();
        }
    }

    book.tags = [];

    $('.post-tag').each((i, e)=>{
        book.tags.push($(e).text());
    });

    console.log(book);
});

你可能感兴趣的:(Node.js实战cheerio网页抓取器)