小梅梅的二狗子 小梅梅的二狗子
首页
  • fileReader
  • canvas
  • 【css世界】学习笔记
  • Vue

    • vue cli2 升级vue cli3 采坑记录
    • vue-cli3 项目 token.type.endsWith is not a function 生产事故分析
    • 使用vuepress 搭建团队文档
  • node

    • nodjs 爬取喜欢的的背景图片
    • 使用 puppeteer + nodejs 爬取喜欢的动漫资源
    • puppeteer爬取aspx网站
  • jenkins

    • Jenkins 从安装到自动部署h5
    • vue自动部署项目到服务器
    • jenkins自动打包前端代码并发布到测试或者生产
  • Vscode

    • Visual Studio Code 入门简介 常用插件介绍
    • vscode prettier eslint 插件格式化不生效的问题
  • 其他的

    • 声卡问题
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

qinyuanqi

搬砖使我变强!冲!!!
首页
  • fileReader
  • canvas
  • 【css世界】学习笔记
  • Vue

    • vue cli2 升级vue cli3 采坑记录
    • vue-cli3 项目 token.type.endsWith is not a function 生产事故分析
    • 使用vuepress 搭建团队文档
  • node

    • nodjs 爬取喜欢的的背景图片
    • 使用 puppeteer + nodejs 爬取喜欢的动漫资源
    • puppeteer爬取aspx网站
  • jenkins

    • Jenkins 从安装到自动部署h5
    • vue自动部署项目到服务器
    • jenkins自动打包前端代码并发布到测试或者生产
  • Vscode

    • Visual Studio Code 入门简介 常用插件介绍
    • vscode prettier eslint 插件格式化不生效的问题
  • 其他的

    • 声卡问题
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前端基础

  • 日常采坑

  • 前端框架

    • Vue

    • node

      • nodjs 爬取喜欢的的背景图片
      • 使用 puppeteer + nodejs 爬取喜欢的动漫资源
      • puppeteer + cheerio + mysql 模拟用户去爬取一个aspx网站
    • Angular

    • backbone

    • requirejs

  • 部署相关

  • 微信

  • 网易

  • 浏览器

  • 七牛云

  • 前端
  • 前端框架
  • node
qinyuanqi
2023-04-25

nodjs 爬取喜欢的的背景图片

  • 直接从幕布考过来的,懒得改排版了, 😄😄😄,

  • 幕布地址: https://mubu.com/doc/_77_RCP9GG

  • 前言

    • 公司搬家了, 换了新的电脑, 感觉桌面有点空荡荡,想去搞几张高级的背景图片来装下13,于是便有了这个项目

    • 经过一番谷歌,感觉比较喜欢wallhaven (opens new window)这种风格的背景图,开始搞起 ~~~

  • 搞搞搞

    • 思路

        1. 解析页面,分析页面结构,然后拿到图片地址
        1. 然后发起请求,只用写入本地
    • 具体操作

      • 解析页面,分析页面结构,然后拿到图片地址,

        • 缩略图的页面结构

        • 详情图的页面结构

        • 缩略图地址: https://th.wallhaven.cc/small/rd/rd7dlq.jpg (opens new window)

        • 大图地址: https://w.wallhaven.cc/full/rd/wallhaven-rd7dlq.jpg (opens new window)

        • 找规律

          • 通过知道小图地址,找出大图地址,不同网站不同哦
        • 找分页接口

      • 知道网站的布局和规律之后,我们就可以开始编码了

      • 编码思路:

        • 先把所有的缩略图都爬取出来,爬完之后,再按照每次10个 ,10秒一次去下载,然后写入本地
      • 具体步骤

        • Express 应用程序生成器 (opens new window)来构建一个express应用,具体步骤参考官网

        • 需要使用的库

          • consola (opens new window) 让日志好看点,方便观赏

          • cheerio (opens new window) node 版本的jquery,用来解析页面

          • axios (opens new window) 发送请求,下载图片

        • 核心代码

            1. 发起请求,获取到缩略图的地址,然后存到一个数组里面
            1. 轮询,调用分页接口获取缩略图地址
            1. 下载图片,然后存储到本地电脑,楼主使用万年window,穷😄
            1. 效果,美滋滋
            • 5核心代码
const reptileUrl = 'https://wallhaven.cc/toplist?page='
// 本地存储路径
const saveDir = 'E:/myExpressDownload/toplist3/'
let currentPage = 1
const maxPage = 2

const imgUrlList = []


init()

/**
 * 爬取主程序入口
 */
async function init() {
    log.info('主程序开始启动,请您耐心等待~')
    log.info(`开始爬取${reptileUrl}的图片`)
    log.info(`文件将会被保存到以下地址中:${saveDir}`)

    // 判断本地存储文件夹是否存在
    if (!fs.existsSync(saveDir)) {
        log.info('目标文件不存在,开始创建新的文件夹~')
        fs.mkdirSync(saveDir);
    }

    if (currentPage > maxPage) {
        log.error('超出最大页数,停止收集源数据,开始爬取图片~')
        try {
            const downloadTimer = setInterval(() => {
                if(!imgUrlList.length){
                    log.error('没有更多了,收工了~~~~')
                    clearInterval(downloadTimer)
                    return false
                }
                log.success('开始轮询下载图片~')
                downloadPicture(imgUrlList.splice(0, 10))
            }, 10000);
        } catch (error) {
            log.error(`downloadPicture fail===>`, error)
        }
        
        // const downloadTimer  = setInterval(() => {
        //     if(!imgUrlList.length){
        //         log.error('没有图片了, 终于干完活了, 累死了~~~')
        //         clearInterval(downloadTimer)
        //     }
        //     log.success('开始轮询下载图片咯~')
        //     downloadPicture(imgUrlList.splice(0, 10))
        // }, 20000);
        return false
    }
    try {
        log.info(`开始爬取第${currentPage}页`)
        const websiteHtml = await axiosRequest.get(`${reptileUrl}${currentPage}`)
        const html = websiteHtml
        const $ = cheerio.load(html);
        $('.thumb img').each((i, v) => {
            const smallUrl =  v.attribs['data-src'] ||  v.attribs.src
            const urlArray = smallUrl.split('/')
            const fileName = urlArray[urlArray.length-1]
            const fullUrl = `https://w.wallhaven.cc/full/${fileName.substring(0, 2)}/wallhaven-${fileName}`
            smallUrl && imgUrlList.push({
                        smallUrl: smallUrl,
                        fullUrl: fullUrl,
                        fileName
                    })
            
        })

        log.error(`imgUrlList==>`, imgUrlList)
        sleep(init)
    } catch (error) {
        log.error(`爬取错误,错误信息如下==>`, error)
    }
}

function sleep(callback) {
    currentPage++
    const sleepTimeout = commonUtils.getRandomNumber(1, 10)
    let copyTimeout = sleepTimeout
    log.info(`爬太多了,有点累了,休息${sleepTimeout}秒,后再继续😄`)
    const logTimer = setInterval(() => {
        if (copyTimeout <= 1) {
            clearInterval(logTimer)
        }
        log.success(`倒计时  ${--copyTimeout}   秒后开始继续干活~`)
    }, 1000);
    setTimeout(() => {
        typeof callback === 'function'  &&  callback()
    }, sleepTimeout * 1000);
}

async function findPicture(aTagArray) {
    log.info('开始解析图片内容~')
    const array = aTagArray.map(v => axiosRequest.get(v))
    return Promise.all(array)
}


function downloadPicture(pictureArray) {
    log.info('开始发送请求下载图片~')
    return pictureArray.reduce((accumulator, currentValue, currentIndex, array) => {
        console.log(currentValue.fullUrl, 'currentValue.fullUrl')
        const promise = axiosRequest.get(currentValue.fullUrl, {
            responseType: 'stream'
        }).then(res => {
            const result = res.pipe(fs.createWriteStream(`${saveDir}${currentValue.fileName}`))
            log.success(`成功保存图片到本地,保存位置==>${saveDir}${currentValue.fileName}`)
        })
        accumulator.push(promise)
        return accumulator
    }, [])
}
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  • 完整代码

    • https://github.com/qinyuanqiblog/express-demo
  • 结束语

    • 本文如有错误,欢迎指正,非常感谢

    • 觉得有用的老铁,点个双击,小红心走一波

    • 欢迎灌水,来呀,互相伤害哈 o(∩_∩)o 哈哈

上次更新: 2023/12/18, 15:00:26
vue2 jsx 语法
使用 puppeteer + nodejs 爬取喜欢的动漫资源

← vue2 jsx 语法 使用 puppeteer + nodejs 爬取喜欢的动漫资源→

最近更新
01
若依3.8.5版本vue-cli升级到 5.0.8碰到的一些问题
10-08
02
vuepress添加sitemap
05-17
03
vscode Live Server 插件使用教程
05-16
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式