3.爬虫案例

311 阅读2分钟

流程

  1. 确定爬取对象(网站/网页)
  2. 分析页面内容(目标数据/DOM结构)
  3. 确定开发语音、框架、工具等
  4. 编码测试,爬取数据
  5. 优化

案例

确定爬取对象(网站/网页)

百度新闻 news.baidu.com/ 分析页面内容(目标数据/DOM结构)

确定开发语音、框架、工具等

node.js(express)+VSCode 编码

  • 安装依赖
cnpm i express superagent cheerio nightmare -S

express : 搭建服务器
superagent : superagent是node里一个非常方便的、轻量的、渐进式的第三方客户端请求代理模块,用他来请求目标页面
cheerio : cheerio相当于node版的jQuery,它主要是用来获取抓取到的页面元素和其中的数据信息
Nightmare : nightmare是一个基于electron的自动化库(自带浏览器),用于实现爬虫或自动化测试

const express = require('express');
//充当客户端向百度新闻发起请求
const superagent = require('superagent');
const cheerio = require('cheerio');
//使用 Nightmare 自动化测试工具
const Nightmare = require('nightmare')
const nightmare = Nightmare({
    show: false
}) //show:true 显示内置模拟浏览器
const app = express();
// a标签 :新闻的标题和链接

let hotNews = [];
let localNews = [];

//渲染内容
// let pageRes = {};

/* 
  使用superagent.get()方法来获取百度新闻首页
*/
superagent.get('http://news.baidu.com/').end((err, res) => {
    if (err) {
        console.log('热点新闻抓取失败-' + err);

    } else {
        //返回的数据包含在res中
        // console.log(res.text);
        hotNews = getHotNews(res);
        localNews = getLocalNews(res);

        //渲染内容
        // pageRes = res;
        /* 
        将来后续的操作
            1.存入数据库
            2.跳转对应的路由  /echarts
        */
    }
})

nightmare.goto('http://news.baidu.com/')
    .wait('div#local_news')
    .evaluate(() => document.querySelector('div#local_news').innerHTML)
    .then(htmlStr => {
        localNews = getLocalNews(htmlStr);
    })
    .catch(err => {
        console.log(err);
    })

/* 
获取本地新闻
*/
let getLocalNews = htmlStr => {
    let localNews = [];
    let $ = cheerio.load(htmlStr);
    $('ul#localnews-focus li a').each((index, item) => {
        let news = {
            title: $(item).text(), //获取新闻标题
            href: $(item).attr('href') //获取新闻网页链接
        }
        localNews.push(news);
    })

    $('div#localnews-zixun ul li a').each((index, item) => {
        let news = {
            title: $(item).text(), //获取新闻标题
            href: $(item).attr('href') //获取新闻网页链接
        }
        localNews.push(news);
    })
    return localNews;
}

/* 
获取热点新闻
*/
let getHotNews = res => {
    let hotNews = [];
    // 通过第三方的库得到 $
    let $ = cheerio.load(res.text);
    $('#pane-news ul li a').each((idx, ele) => {
        let news = {
            title: $(ele).text(), //获取新闻标题
            href: $(ele).attr('href') //获取新闻网页链接
        }
        hotNews.push(news);
    })
    return hotNews;
}

app.get('/', (req, res) => {
    // res.send('爬虫实战');
    res.send({
        hotNews: hotNews,
        localNews: localNews
    });
    //渲染内容
    // res.send(pageRes.text);
})

let server = app.listen(3000, () => {
    //获取地址
    let host = server.address().address;
    //获取端口号
    let port = server.address().port;
    // %s 占位符
    console.log('Your App is running at http://%s:%s', host, port);
})