在运行代码前,请确保本机是否有nodejs环境

1 D:\ > node -v
2 v12.1.0 //版本号

需要用到的包

axios //请求页面
cheerio // 把get请求的页面 可以使用jq的方法来获取dom
fs // 文件读写模块
request // 请求模块 用来请求下载地址
path // 路径模块
url // 路由模块

爬虫遵循的规则

  1. 遵守 Robots 协议,谨慎爬取
  2. 限制你的爬虫行为,禁止近乎 DDOS 的请求频率,一旦造成服务器瘫痪,约等于网络攻击
  3. 对于明显反爬,或者正常情况不能到达的页面不能强行突破,否则是 Hacker 行为
  4. 如果爬取到别人的隐私,立即删除,降低进局子的概率。另外要控制自己的欲望

本次案例百度图片表情包

  1 const axios = require("axios")
2 const cheerio = require("cheerio")
3 const fs = require('fs');
4 const request = require("request");
5 const path = require('path');
6 const url = require("url")
7
8 /**
9 * 休眠方法,因为一次访问太多次目标网址会被拉黑
10 * @param {Number} time 休眠时间以毫秒为单位
11 * @returns Promise
12 */
13 const sleep = time => {
14 return new Promise(function (resolve, reject) {
15 setTimeout(function () {
16 resolve();
17 }, time);
18 })
19 }
20
21 /**
22 * 爬取某个地址下的img 图片
23 * @param {String} httpUrl 目标地址
24 * @param {Boolean} isBaidu 是否为百度图片地址
25 */
26 async function start(httpUrl, isBaidu) {
27
28 // 获取目标网址的dom节点,使用jq的方法来获取dom节点
29 const { data } = await axios.get(httpUrl)
30 let img = [];
31 // 针对百度 进行爬取数据
32 if (isBaidu) {
33 img = getBaiDuImg(data)
34 } else {
35 const $ = cheerio.load(data)
36 // 根据dom获取img src
37 $(".imgbox img").each(function () {
38 let src = dealImgUrl($(this).attr("src"), httpUrl)
39 img.push(src)
40 })
41 }
42
43 // 检测当前文件夹是否存在存储图片的文件夹
44 const random = parseInt(Math.random() * 100)
45 const dirPath = "./img" + random
46 if (!fs.existsSync(dirPath)) {
47 fs.mkdirSync(dirPath)
48 }
49 fs.writeFileSync("./data.json", JSON.stringify(img), "utf-8")
50
51 /**
52 * 在这里为什么不使用forEach遍历? 答案在下方链接
53 * https://blog.csdn.net/yumikobu/article/details/84639025
54 */
55 for (let i = 0; i < img.length; i++) {
56 const item = img[i]
57 await sleep(1500)
58
59 console.log(item + "开始下载");
60 // const extname = path.extname(item) || '.jpg'
61 // const filename = (i + 1) + extname
62 let myUrl = new URL(item) // node vision must v10 up!
63 let httpUrl = myUrl.origin + myUrl.pathname
64 let filename = i + path.basename(httpUrl)
65 const write = fs.createWriteStream(dirPath + "/" + filename)
66 request.get(item).on('error', function (err) {
67 console.log(item + "下载失败", err);
68 }).pipe(write)
69 console.log(item + "本地下载结束");
70 }
71 }
72 process.on("exit", () => {
73 console.log("爬取结束");
74 })
75 /**
76 * 处理img的src
77 * @param {String} src 路径
78 * @param {String} pathurl url地址
79 * @returns 返回图片链接地址
80 */
81 function dealImgUrl(src, pathurl) {
82 if (src.substr(0, 8) === 'https://' || src.substr(0, 7) === 'http://' || src.substr(0, 2) === "//" || src.substr(0, 5) === "data:") {
83 return src
84 }
85 return url.resolve(pathurl, src)
86 }
87
88 /**
89 *
90 * @param {String} str 百度返回的html字符
91 * @returns {Array} 返回图片链接地址
92 */
93 function getBaiDuImg(str) {
94 var reg = /app\.setData\(\'imgData\'\,\s+\{(.*?)\"data\":(.*?)\]\}/g
95 var result = reg.exec(str)[2] + ']'
96 result = result.replace(/\'/g, '"')
97 result = JSON.parse(result)
98 const img = []
99 result.forEach(item => {
100 if (item.objURL) {
101 img.push(item.objURL)
102 }
103 })
104 return img
105 }
106 // const HTTPURL = "https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1605517415488_R&pv=&ic=0&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&hs=2&sid=&word=%E7%94%B5%E8%84%91%E5%A3%81%E7%BA%B8++%E6%A2%85%E8%A5%BF"
107 const HTTPURL = "https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&sf=1&fmq=1389861203899_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&ala=6&ori_query=%E8%A1%A8%E6%83%85%E5%8C%85&fr=ala&ala=1&alatpl=adress&pos=2&oriquery=%E8%A1%A8%E6%83%85%E5%8C%85&alaTag=0&&word=%E8%A1%A8%E6%83%85%E5%8C%85%20%E6%90%9E%E7%AC%91&hs=2&xthttps=111111"
108 // 开始调用start函数进行爬取图片
109 start(HTTPURL, true)

仔细分析了一下,百度图片并不是在请求页面的时候就把图片的数据渲染到dom上了,而是通过js脚本创建出img的.所以使用正则匹配到img的数据,就可以知道图片链接地址了.

若是一般常规的网站图片 可以使用cheerio来操作dom获取图片路径地址

在代码里使用了一个sleep函数就是为了多次访问网站防止被拉黑,请勿频繁请求!

在爬取个别页面需要配置请求头或者https证书还须自行网上查阅方法.

使用nodejs爬取图片的更多相关文章

  1. Java jsoup爬取图片

    jsoup爬取百度瀑布流图片 是的,Java也可以做网络爬虫,不仅可以爬静态网页的图片,也可以爬动态网页的图片,比如采用Ajax技术进行异步加载的百度瀑布流. 以前有写过用Java进行百度图片的抓取, ...

  2. python如何使用request爬取图片

    下面是代码的简单实现,变量名和方法都是跑起来就行,没有整理,有需要的可以自己整理下: image2local: import requests import time from lxml import ...

  3. [python爬虫] 爬取图片无法打开或已损坏的简单探讨

    本文主要针对python使用urlretrieve或urlopen下载百度.搜狗.googto(谷歌镜像)等图片时,出现"无法打开图片或已损坏"的问题,作者对它进行简单的探讨.同时 ...

  4. scrapy爬虫,爬取图片

    一.scrapy的安装: 本文基于Anacoda3, Anacoda2和3如何同时安装? 将Anacoda3安装在C:\ProgramData\Anaconda2\envs文件夹中即可. 如何用con ...

  5. scrapy爬虫系列之三--爬取图片保存到本地

    功能点:如何爬取图片,并保存到本地 爬取网站:斗鱼主播 完整代码:https://files.cnblogs.com/files/bookwed/Douyu.zip 主要代码: douyu.py im ...

  6. vue+node+mongoDB火车票H5(七)-- nodejs 爬12306查票接口

    菜鸟一枚,业余一直想做个火车票查票的H5,前端页面什么的已经写好了,node+mongoDB 也写了一个车站的接口,但 接下来的爬12306获取车次信息数据一直卡住,网上的爬12306的大部分是pyt ...

  7. 孤荷凌寒自学python第八十二天学习爬取图片2

    孤荷凌寒自学python第八十二天学习爬取图片2 (完整学习过程屏幕记录视频地址在文末) 今天在昨天基本尝试成功的基础上,继续完善了文字和图片的同时爬取并存放在word文档中. 一.我准备爬取一个有文 ...

  8. 孤荷凌寒自学python第八十一天学习爬取图片1

    孤荷凌寒自学python第八十一天学习爬取图片1 (完整学习过程屏幕记录视频地址在文末) 通过前面十天的学习,我已经基本了解了通过requests模块来与网站服务器进行交互的方法,也知道了Beauti ...

  9. 爬取图片过程遇到的ValueError: Missing scheme in request url: h 报错与解决方法

    一 .scrapy整体框架 1.1 scrapy框架图 1.2 scrapy框架各结构解析 item:保存抓取的内容 spider:定义抓取内容的规则,也是我们主要编辑的文件 pipelines:管道 ...

随机推荐

  1. uni-app开发经验分享一: 多页面传值的三种解决方法

    开发了一年的uni-app,在这里总结一些uni-app开发中的问题,提供几个解决方法,分享给大家: 问题描述:一个主页面,需要联通一到两个子页面,子页面传值到主页面,主页面更新 问题难点: 首先我们 ...

  2. Scrapy——將數據保存到MySQL數據庫

    Scrapy--將數據保存到MySQL數據庫 1. 在MySQL中創建數據庫表job_inf: 1 Create table job_inf( 2 id int(11) not null auto_i ...

  3. selenium浏览器弹出框alert 操作

    1.简介 在WebDriver中要处理JS生成的alert.confirm以及prompt,需要 switch_to.alert() 来选取(定位)警告弹窗,在对弹窗进行关闭.输入等信息操作. 2.操 ...

  4. UT /SIT/ UAT

    UT /SIT/ UAT - 云+社区 - 腾讯云 https://cloud.tencent.com/developer/article/1541268 我们公司只有测试环境--准生产环境--生产环 ...

  5. 获取控制台的错误信息 onerror

    js 获取控制台的错误信息 https://www.bbsmax.com/A/Vx5ML2NmJN/ <!DOCTYPE html> <html lang="en" ...

  6. CSRF Laravel Cross Site Request Forgery protection¶

    Laravel 使得防止应用 遭到跨站请求伪造攻击变得简单. Laravel 自动为每一个被应用管理的有效用户会话生成一个 CSRF "令牌",该令牌用于验证授权用 户和发起请求者 ...

  7. git database 数据库 平面文件 Git 同其他系统的重要区别 Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异 Git 的设计哲学

    小结: 1.如果要浏览项目的历史更新摘要,Git 不用跑到外面的服务器上去取数据回来 2.注意 git clone  应指定版本,它复制的这个版本的全部历史信息: 各个分支  git init 数据库 ...

  8. 《CSP.OI吟》

    吟 CSP·OI 这个LCT,我听得很懵逼 在 Splay 里面,好像有重链 不用线段树,Splay 来维护 树的形态有改变,不只是那一条边 所以要把整棵树,重新剖一遍 什么重链 ~ 什么轻边 ~ 什 ...

  9. how2j SpringMVC学习心得

    http://how2j.cn/k/springmvc/springmvc-form/618.html 注意 addProduct.jsp 是放在了WebContent(即web目录)下,访问的时候, ...

  10. Python 中 sorted 如何自定义比较逻辑

    在 Python 中对一个可迭代对象进行排序是很常见的一个操作,一般会用到 sorted() 函数 num_list = [4, 2, 8, -9, 1, -3] sorted_num_list = ...