# 编写一个简单的Node爬虫

# 关于爬虫

爬虫就是模拟用户浏览网站的行为。获取你要爬取页面的html源码。通过cheerio工具模块解析获取到的源码。cheerio跟jQuery原理一样,jQuery的API基本都可用。这是最基本的原理,但是只针对一些反爬措施不怎么强的网站。😢。

爬虫编写的样式千奇百怪,但是背后的逻辑都是一样的

# 下载模块化工具

  1. 新建一个文件夹
  2. 在当前文件夹下执行终端命令npm init -y创建配置文件
  3. 下载相应的模块化工具npm i cheerio,此时会自动生成一个node_modules文件
  4. node_modules文件下存放的是你所下载的模块化工具

注意:🤞下载node.js,配置好环境变量,如果网络不佳切换镜像(切换方法参考node.js文章)🤞

# 编写一个简单的爬虫脚本

# 1.导入需要的的模块

新建index.js文件夹

除了cheerio其他的https和fa路径模块都是node内置的模块

// 导入http模块
const https = require('https');

// 导入路径模块
const fs = require('fs');

// 导入cheerio工具解析模块
const cheerio = require('cheerio');
1
2
3
4
5
6
7
8

# 2.使用https模块发送请求

这里使用豆瓣的url地址

let req = https.request('https://movie.douban.com/chart', res => {
    let html = '';
    res.on('data', chunk => {
        html += chunk;
    });
    res.on('end', () => {
        // 结束数据监听后将所有内容拼接存放进html
        let $ = cheerio.load(html);
        let text = [];
        // 将筛选的内容存放到text数组
        $('.article .indent .item').each(function(i, ele) {
            const imgs = $('.nbg img', this).attr('src');
            text.push({
                pic: imgs
            });
        });
        downloadImg(text);
    });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 分支解析

将目标url的页面通过字符串形式拼接并交给html

image-20220707150801513

在数据监听结束后使用cheerio工具解析模块将得到的页面筛选,并存入到text数组中

image-20220718104439830

# 3.编写下载方法

循环得到的存放地址的text数组,将每个数组中的pic属性赋值给picUrl变量接收,使用https的get方法读取picUrl,字符串拼接并以二进制存放,res.setEncoding('binary');

注:也可以使用download工具下载,具体用法见官方文档download npm 官方网站 (opens new window)

// 编写下载方法
// 将获取过来的数据进行下载
function downloadImg(allFilms) {
    for (let i = 0; i < allFilms.length; i++) {
        // 获取每个对象的url地址给picUrl
        const picUrl = allFilms[i].pic;
        https.get(picUrl, function(res) {
            // 读取picUrl写入到本地
            // 设置二进制存放
            res.setEncoding('binary');
            let str = '';
            res.on('data', function(chunk) {
                str += chunk;
            });
            res.on('end', function() {
                // 写入模块
                // 创建images文件夹
                fs.mkdir('./images', function(err) {
                    if (!err) {
                        console.log('imgages文件写入成功!');
                    }
                });
                // 往images文件中写入图片文件
                // str, 'binary' 将str转换为二进制存放
                fs.writeFile(`./images/${i}.png`, str, 'binary', function(err) {
                    if (!err) {
                        console.log(`${i}张图片下载成功`);
                    }
                })
            })
        })
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

将读取的url以字符串型形式拼接,并在数据读写完毕后,使用fs路径模块,将数据下载到指定文件夹下。

# 4.结束请求

// 结束请求
req.end();
1
2

# 5.执行脚本

在终端使用node '你js文件名字'指令,例如:node index.js

# 工程已上传gitee

在工程文件中使用git clone git@gitee.com:bl_ack233/watercress-reptile.git指令将文件克隆下载。

前提是有git,下载地址git官网 (opens new window) (大概率被墙)

# 爬虫Pro版本Puppeteer

Puppeteer是一个Node库,由Chrome官方团队进行维护,提供接口来控制headless Chrome。Headless Chrome是一种不使用Chrome来运行Chrome浏览器的方式。简单的来说就是一个运行在命令行中的 chrome,我们可以通过代码来实现我们常规的浏览器浏览网页的功能。原文链接 (opens new window)

就是使用代码模拟人的操作来浏览页面

Puppeteer官方文档 (opens new window)

# 下载

同上下载方式一样,在工程文件下使用终端命令 npm i puppeteer

注意:如果你不想在全局下安装npm包,或者安装到别的地方,就在工程目录下运行指令

# 下载中所遇问题

通常情况下,下载这个包的时候会包含下载chrome的过程,这个阶段常常报错,可以通过指令 npm i --save puppeteer-core 来跳过下载,原帖子 (opens new window)

# 编写代码

const puppeteer = require('puppeteer')

// 导入cheerio工具解析模块
const cheerio = require('cheerio');

// 导入路径模块
const fs = require('fs');

//设置网址
var url = 'https://www.jd.com/';

async function start(bool) {
    //启动浏览器,传入headless为false可以打开窗口
    //executablePath为你的谷歌浏览器下载地址
    const browers = await puppeteer.launch({
            headless: false,
            executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe'
        
        })
        //启动新页面
    const page = await browers.newPage()
        //设置页面打开时的页面宽度高度
    await page.setViewport({
        width: 1920,
        height: 1080,
    })

    //打开链接网址
    await page.goto(url)
    var content, $
    await page.evaluate(function() {
        // 好多电商类或者其他数据较多的网站都会有懒加载,通过puppeteer内置的滚动事件模拟用户滚动行为
        // 让完整的页面加载出来,这时候获取的页面就是完整的页面
        var top = 0
            //每200毫秒滚动100px
        var timer = setInterval(() => {
            console.log(window.scrollY);
            window.scrollTo(0, top += 100)
        }, 200);
        //15秒后清除定时器并开始获取内容
        setTimeout(() => {
            clearInterval(timer);

            var box = $('.more2_item')
                // console.log(box);
            let List = []
            for (let i = 0; i < box.length; i++) {
                let e = box.eq(i)
                console.log(e);
                let title;
                let obj = {
                    title: $(e).find('.more2_info_name').text(),
                    src: $(e).find('.lazyimg_img').prop('src'),
                    price: $(e).find('.more2_info_price_txt').text(),
                };
                List.push(obj);
            };
            console.log(List);
            List = JSON.stringify(List, undefined, 4);
            //以下是下载json,创建元素
            var ele = document.createElement('a');
            //设置下载文件名
            ele.download = "jingdong.json";
            //隐藏元素
            ele.style.display = "none";
            //字符内容转变成blob地址
            var blob = new Blob([List], { type: 'text/json' });
            //如果是链接,这里也可以直接设置链接地址
            ele.href = URL.createObjectURL(blob);
            document.body.appendChild(ele);
            //模拟点击
            ele.click();
            //移除元素
            document.body.removeChild(ele);

        }, 25000);
    })
}

start(false)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  1. 好多电商类或者其他数据较多的网站都会有懒加载,通过Puppeteer内置的滚动事件模拟用户滚动行为。让完整的页面加载出来,这时候获取的页面就是完整的页面.
  2. 最终的数据下载,并没有使用fs模块,是因为没法用!尝试过,但是不成功。也许是Puppeteer的原因,这里使用的是HTML5中给a标签增加的一个download属性,原帖子使用a标签下载文件 (opens new window)
Last Updated: 2/23/2023, 9:05:22 AM