Node.js实战cheerio网页抓取器

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

Node.js实战 封面

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


1、提取图书书名

详情页中图书名称HTML代码

<h2>
         Node.js实战(第2版)
</h2>

提取片段的cheerio代码如下

const html = `
    <h2>
             Node.js实战(第2版)
    </h2>
`;

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

2、提取简介

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

提取代码如下

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

3、提取作者

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

HTML代码

<div class="book-author">
                                <span>
[英] 亚历克斯•杨 等                                    (作者)
                                </span>
                                <span>
<a href="/space/87796">吴海星</a>                                    (译者)
                                </span>
                            </div>

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

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);
});
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Node.js第一天 1. 初识Node.js 1.1 Node.js是什么 Node.js® is a Java...
    再见天才阅读 4,710评论 1 24
  • 弟兄们,我还有话说:我们靠着主耶稣求你们,劝你们,你们既然受了我们的教训,知道该怎样行可以讨神的喜悦,就要照你们现...
    澳新好物种草阅读 1,674评论 0 0
  • 昨晚亲爸喝醉酒给于朵打电话。 谈了很多事情,直到夜里十点。后来姐和妹也加入进来。 他很开心,看样子是吧。他眼神很温...
    笠早阅读 288评论 0 1
  • 妹妹应聘某银行大堂经理失败,回来和我说面试的事。 第一关面试应该是看颜值吧,毕竟银行这种窗口单位,颜值放在首位也不...
    恋枫林阅读 1,707评论 0 4
  • 云在他乡常做客 月留一半照故乡 思亲辛苦心憔悴 深夜无眠空自伤
    白鹤来翔阅读 57评论 0 0