nodejs爬虫 node + cheerio 爬取滚动加载页面
最近在学习nodejs,然后了解到nodejs也可以做爬虫就试了一试还可以就记录一下
- 爬取爱奇艺首页视频标题
用到的是node+cheerio,cheerio是jq核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对DOM进行操作的地方,感兴趣的小伙伴可以学习一下
中文文档 和 官方文档
https://www.jianshu.com/p/629a81b4e013
https://cheerio.js.org/
首先创建好文件夹以后,在powershell窗口(或者cmd)执行命令
npm install cheerio
接下来创建好我们要接的脚本文件开始敲代码
- 引用需要用到的模块和设置想要爬的网站
var http = require('https');//请求需要的,需要注意require('https')还是require('http')
var fs = require('fs');//下载需要保存的内容
var cheerio = require('cheerio');//解析html的
//初始url
var url = "https://www.iqiyi.com/";
- 使用http请求我们要爬取的页面,在此之前需要对页面有一个分析:
我只需要红框的标题一起以及蓝框的分类得出结论,电视剧电影综艺等都是固定的会出现且dom布局一样,可以用cheerio来获取所需内容,而新片速递,动漫,儿童,纪录片,以及滚动加载等都是可以在network里查到api的(如有模块数据来源查不到api的见这篇文章)
https://blog.csdn.net/qq_43017024/article/details/118787817
接下来直接上完整代码(我实在太懒了,我尽量在代码里写注释,不好的地方请多多指教)
var http = require('https');
var fs = require('fs');
var cheerio = require('cheerio');
//初始url
var url = "https://www.iqiyi.com/";function fetchPage(x) { //封装了一层函数startRequest(x);
}
//创建保存时的json文件格式title是保存的标题,list是传过来的数据,gettype是用来区分如何分类
function creatObj(title, List, getType) {let objif (getType == 'page') {obj = []} else {obj = {title: title,name: []}}if (getType == 'gethtml') {for (let i = 0; i < List.length; i++) {const e = List.eq(i);obj.name.push(e.text().trim())}} else if (getType == 'page') {for (let i = 0; i < List.length; i++) {const e = List[i];obj.push({title: e.title,name: []})for (let idx = 0; idx < e.rec_items.length; idx++) {const ele = e.rec_items[idx];obj[i].name.push(ele.name)}}} else {for (let i = 0; i < List.length; i++) {const e = List[i];obj.name.push(e.name)}}return obj
}function xpsd() {var mData = '';var val//封装了一个promise,好把请求到的数据配合async/await函数返回给调用者return new Promise((resolve, reject) => {http.get('https://pcw-api.iqiyi.com/strategy/pcw/data/indexXpsdRow', function (res) {res.on('data', function (data) {mData += data;//拿到的数据是二进制流,加上空字符串后可变成可查数据,res.data时请求并没有结束!返回数据的代码要写在res.end里,因为没有看官方文档导致我这里浪费了很长时间试错});res.on('end', function () {var data = JSON.parse(mData);val = data.data.formatData.listresolve(val)});}).on('error', function (err) {reject(err);});})
}function typelist(type) {var mData = '';var valreturn new Promise((resolve, reject) => {http.get(`https://pcw-api.iqiyi.com/video/recommend/homecard?area_list=${type}&is_vip=-1&ret_num_list=7&filter_list=`, function (res) {res.on('data', function (data) {mData += data;});res.on('end', function () {var data = JSON.parse(mData);val = data.data[type].listresolve(val)});}).on('error', function (err) {reject(err);});})}function page(id) {var mData = '';var valreturn new Promise((resolve, reject) => {let url = `https://pcw-api.iqiyi.com/strategy/pcw/data/indexThemeCardBlock?page_id=${id}&session=${sessionid()}`http.get(url, function (res) {res.on('data', function (data) {mData += data;});res.on('end', function () {var data = JSON.parse(mData);val = data.data.formatData.dataresolve(val)});}).on('error', function (err) {reject(err);});})
}
//因为里面有的参数是32位的sessionid,所以写个随机的id
function sessionid() {var chars = "abcdefhijkmnprstwxyz1234567890";var maxPos = chars.length;var pwd = "";for (var i = 0; i < 32; i++) {pwd += chars.charAt(Math.floor(Math.random() * maxPos));}return pwd;
}function startRequest(x) {//采用http模块向服务器发起一次get请求 http.get(x, function (res) {var html = ''; //用来存储请求网页的整个html内容res.setEncoding('utf-8'); //防止中文乱码//监听data事件,每次取一块数据res.on('data', function (chunk) {html += chunk;});//监听end事件,如果整个网页内容的html都获取完毕,就执行回调函数res.on('end', async function () {var $ = cheerio.load(html); //采用cheerio模块解析htmlvar List = []var box = $('.ch-res').children().find('.qy-mod-text') //相同等级的主模块var dianshiju = $("#dianshiju").find('.tl-layout__left').find('.main')//电视剧模块等使用cheerio获取内容var dianying = $("#dianying").find('.tl-layout__left').find('.main')var zongyi = $("#zongyi").find('.tl-layout__left').find('.main')var xpsdval = await xpsd()//新片速递找到了接口,所以直接调接口//动漫,儿童等请求接口都是一样的,参数不一样所以封装了同一个函数调用var cartoon = await typelist('rec_cartoon')var child = await typelist('rec_child')var series = await typelist('rec_series')//加载更多的是调用的接口,传参分页和页面大小就可以,我只需要两页所以就这样写了,如果需要更多可以使用for循环var page1 = await page(1)var page2 = await page(2)List.push(creatObj('电视剧', dianshiju, 'gethtml'))List.push(creatObj('电影', dianying, 'gethtml'))List.push(creatObj('综艺', zongyi, 'gethtml'))List.push(creatObj('新片速递', xpsdval))List.push(creatObj('动漫', cartoon))List.push(creatObj('儿童', child))List.push(creatObj('纪录片', series))List = List.concat(creatObj('page1', page1, 'page'))List = List.concat(creatObj('page2', page2, 'page'))// console.log(List);//这里就是获取好数据后保存下来的json文件代码fs.writeFile('iqiyi.json', JSON.stringify(List), 'utf8', function (error) {if (error) {console.log(error);return false;}console.log('写入成功');})});}).on('error', function (err) {console.log(err);});
}fetchPage(url); //主程序开始运行
最后来看看效果以及获取到的数据吧
nodejs爬虫 node + cheerio 爬取滚动加载页面相关推荐
- python爬虫动态加载页面_Python+Selenium爬取动态加载页面(2)
注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...
- 网络爬虫 | selenium 爬取动态加载信息
使用selenium实现动态渲染页面的爬取.selenium是浏览器自动测试框架,模拟浏览器,驱动浏览器执行特定的动作,并可获取浏览器当前呈现的页面的源代码,可见即可爬.该工具支持IE浏览器.Mozi ...
- python爬动态网页json_爬虫再探实战(四)———爬取动态加载页面——请求json...
还是上次的那个网站,就是它.现在尝试用另一种办法--直接请求json文件,来获取要抓取的信息. 第一步,检查元素,看图如下: 过滤出JS文件,并找出包含要抓取信息的js文件,之后就是构造request ...
- php 滑块 爬虫_phpspider爬虫框架如何爬取异步加载的数据?
我找到些资料希望对楼主有所帮助 什么是异步加载? 向网站进行一次请求,一次只传部分数据.如:有些网页不需要点击下一页,其内容也可以源源不断地加载. 如何发现异步加载? 1.打开浏览器,右键选择&quo ...
- 还在苦于Kindle的epub格式吗?python爬虫,一键爬取小说加txt转换epub。
还在苦于Kindle的epub格式吗?python爬虫,一键爬取小说加txt转换epub. 项目地址: https://github.com/Fruiticecake/dubuNovel/blob/m ...
- selenium爬取Ajax加载的网页(以微博为例)
Tip:我写了一篇直接构造请求获取微博数据的文章,不使用selenium,直接访问url获取到json数据,然后解析即可得到想要的数据的文章,请参考微博博主动态及相册的请求构造规律 ========= ...
- python爬取js加载的数据_JS动态加载数据不会爬?老司机教你两个方法爬取想要的数据...
学习Python的人绝大部分都是在用Python做爬虫,毕竟对于爬虫而言Python是不二选. 但是一般简单的静态页面网站还是很好爬取的,对于很多动态加载的网站就不知道怎么办了,今天小编就给大家介绍两 ...
- scrapy爬取动态网页_scrapy_splash 爬取 js 加载网页初体验
最近打算学习 scrapy_splash 来爬取 js 加载的动态网页 selenium 实在太慢了,不在迫不得已的情况下并不推荐使用 下面,直接开始吧 目标网站 JD 某商品 环境需求 已安装 do ...
- 用Python爬取动态加载的诸如百度的图片
用Python爬取动态加载的诸如百度的图片 使用原因 代码如下 模块介绍 selenium模块 lxml解析模块 requests模块 去除重复 开启多线程 效果如下 留言 使用原因 学习Python ...
最新文章
- linux+tasks进程,linux命令之进程管理命令(上)
- matlab中并行用不了,请教matlab在linux下的并行问题 - 程序语言 - 小木虫 - 学术 科研 互动社区...
- 卷积核一定可以提升网络性能吗?-分类0,2
- PHP 结合 Boostrap 结合 js 实现学生列表删除编辑以及搜索功能(完结)
- SpringBoot2 整合 AXIS 服务端和客户端
- 秒懂了微服务架构,看这本书就够了!
- Java Class的热替换 自定义ClassLoader加载.class
- CSS那些不大不小的事
- 数学与算法《TF-IDF》
- 【资源】编程珠玑I 源码
- Linux下安装python 2.7.13
- android zenmode 通知,【Android系统】Android M ZenMode(禅模式)分析(2)
- ADNI数据集相关概念整理
- mysql在子查询中使用自定义变量和条件语句实现函数效果的查询语句
- 不撞南墙不回头——深度优先搜索
- Web网页设计-盒子模型
- C# FTP操作(上传、下载等……)
- 协议和服务器有什么区别,服务期协议是什么,劳动合同与服务期协议有什么区别?...
- SQLZOO刷题笔记
- 电大学位计算机考试题库,电大学位英语跟考试题库一模一样.doc
热门文章
- 出售时间之前你要牢记的三条铁律(上)
- 电脑文件里哪里能用计算机,文件夹选项在哪找,计算机文件夹选项在哪里
- 【毛估估】由指数倒算自由流通股数
- TechSmith Camtasia Studio 9录屏提 示video codec open failed 错误
- 2021城阳一中高考成绩查询,2021年青岛高考状元是谁分数多少分,历年青岛高考状元名单...
- HDMI(一):TMDS
- mac安装autojump
- try...catch执行了catch后不知道怎么重新执行业务?看这个~
- SQLServer Delayed durability 延迟持久化
- 【103期】史上最全的数据库面试题,面试前刷一刷!