ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 4330|回复: 47

[原创] JSA爬虫新玩法-更少的代码,更快的速度,更便捷的选择

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-1-4 15:34 | 显示全部楼层 |阅读模式
本帖最后由 wodewan 于 2024-1-4 15:51 编辑

      ,有点标题党了,JSA的网络请求出来有段时间了,一直想写点这方面的帖子,一直没动力,直到昨天回复了一个相关的帖子,来了兴趣,这里做点小总结,供有兴趣的坛友参考,水平有限,欢迎回帖补充和指正。

目标网站:本论坛,JSA版块
目标内容:所有主题列表
包含方法:fetch异步获取数据,Promise并发请求,Css选择器进行html解析

一. 更少的代码(fetch异步
     首先,说明一点JSA这次出的网络请求的函数有两个,XMLHttpRequest和fetch,XMLHttpRequest有点老了,fetch写法更简单,同时支持异步请求,本贴以fetch为例。

     语法:fetch(url, options);
    参数1:url,看名字就知道,传入目标网站的地址即可
    参数2:options,这是一个可选参数,使用对象{}形式传入,可设置请求方式,header等
    返回值:promise,至于什么是promise,包括后面用到的async,await这些语法,可自行了解,本贴就不说了。
    那我们就用这个fetch来试试获取一下网页源码:,有2种写法:

      image.jpg
     代码是不是很简单,简单说明一下,fetch函数在接受到一个url地址后,会以异步的方式发送请求,并返回一个promise,而这个promise的resolve值是一个response对象,对象中有很多属性,一般情况下,我们需要获取的数据就是一个文本,所以response对象有一个text的方法用于获取文本属性,这个方法的返回值也是一个promise,第2种.then(回调函数)这样的写法,回调一层套一层是不是有点晕,建议使用第1种async+await,这样更接近同步的方式,代码更简洁,后续代码将使用第一种写法。
     也许你会说,简单是简单,但如果需要配置一些请求参数怎么办呢?个人习惯是只要能获取到数据尽量使用默认配置即可,当然上面是Get请求,如果是Post请求或网站有验证的那必须得有第二参数,以下代码为POST请求的常规写法,然后fetch(url,options)即可:      
  1. const options = {
  2.     method: "POST",
  3.     headers: {
  4.        "Content-Type": "application/json",
  5.        "User-Agent": "省略。。。。",
  6.     },
  7.     body: JSON.stringify(data)
  8. };
复制代码
至此,基础部分已完成,接下来说说并发和Css选择器。

二. 更快的速度(Promise并发
      先看这样一个需求,网页有很多页(就比如JSA板块的帖子),并没有API接口可以获取到所有数据,如果要获取所有页的内容按顺序返回,一般情况下我们可以使用循环的方式,依次请求网页并获得数据,这种方式会这样运行:第一个网页处理完成后再处理第二个网页,第二个网页处理完成后再处理第三个网页,以此类推。有没有一种方法可以让这些任务并行处理呢?当然有,而且有很多,这里介绍原生Promise.all的用法。

     语法:Promise.all(iterable)
     参数:一个可迭代对象,如果不知道什么是可迭代对象,就先把理解为数组就行。
     返回值:还是一个promise
1.gif
用法很简单,我们可以将for循环中的数据,放入一个数组中,作为promise.all的参数传入,但这个数组中的所有promise都已经完成后,就会返回一个promise。代码这里就不贴了,最后附件中将包含所有本贴中的示例,看一下两者的对比,这也是本文一开始提到的那个帖子的例子。

三、更便捷的选择(Css选择器
         肯定有人会问JSA中都没有DOM对象,哪里来的什么Css选择器,确实如此,但我们可以使用第三方库来实现我们的需求,但J问题又来了,SA不能导包,怎么用?这个也没错,但不能导包不代表不能用第三方库,每个库的导出方式不同,使用方式也不同,我们可以把不能在JSA中的使用的第三方库变成JSA能用的,比如这次用开源的cheerio库(附件已包含转换过的cheerio库),顺便贴一下附件的模块说明。
         image.png


      简单介绍一下这个cheerio库的使用方法,基本使用知道这4个函数就可以了,详细信息可参考官网:
      1.  load函数: 使用cheerio.load("网页源码"),赋值给一个变量,一般都是$符号,和jquery写法一样。

      2.  $("元素的路径"):和css的选择器一样的用法,这样就可以获取到一个dom对象。
      3.  each():遍历对象。
      4. text():获取文本。

     第二点的例子在最后处理返回的网页的字符串时,使用了slice来截取了一部分,当然这只是一个示例,另外使用正则也是一种方式,但CSS选择器提供了更好的元素选择方式,比如现在的需求是要选取当前页面中所有帖子的标题,使用选择器只要简单的一句就可以获取到,看一下效果
       image.jpg


      是不是很简单,但肯定有朋友会说,选择器是简单,但那一长串table#threadlisttableid > tbody a.s不会写,其实这个也不是写的,而是复制的,至于到哪复制怎么复制,方法有很多,说个使用浏览器开发者工具的大概流程:浏览器-F12 》》开发者工具 》》左上角小箭头在网页中选择对应元素,当然具体得细节和技巧可以自行搜索,这里不过多介绍。

      四、关于附件
      附件打开或退出时,不要保存文件,保存后大部分代码将消失,留个悬念,有兴趣可以找找为什么,切记!!!!

      五、两点说明
      1. 虽然帖子花了差不多2个多小时整理编辑,写到这里算是差不多了, 如果你看到了这里,感谢你的耐心,希望对你有点帮助。
      2. 另外,写这个帖子的目的是对JSA中的fetch,promise以及async,await以及第三方库的使用的一个可行性验证,难免有错,还请指正。
      最后祝各位坛友,2024,到成功!

JSA网络请求.rar

100.69 KB, 下载次数: 152

评分

10

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-4 16:21 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
感谢分享,请问cheerio的js是怎么生成的,我这里用的browserify,有没有更方便或直接的办法,多谢

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-4 16:25 | 显示全部楼层
wanghan519 发表于 2024-1-4 16:21
感谢分享,请问cheerio的js是怎么生成的,我这里用的browserify,有没有更方便或直接的办法,多谢

差不多,我用的webpack。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-4 19:25 | 显示全部楼层
感谢wodewan大佬的教程!

提醒一下,要进行如下图设置,否则出错:
无标题.png

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-4 19:38 来自手机 | 显示全部楼层
本帖最后由 一江春水1688 于 2024-1-4 19:40 编辑

wodewan大佬,附件中的xlsm文档果然不能保存,会丢失大部分代码,为什么呀?

TA的精华主题

TA的得分主题

发表于 2024-1-4 20:40 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
带佬,有适合jsa的webpack打包教程嘛

TA的精华主题

TA的得分主题

发表于 2024-1-5 17:02 | 显示全部楼层
借人气说一下,浏览器f12,网络标签里,要选复制为Nodejs fetch,而不是选复制为fetch,前者可以直接在js宏里用,后者有referrer的问题,只能在浏览器里用。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-8 07:03 | 显示全部楼层
大佬,是不是&#x在xml里解析出错,把&#分开比如,`xxx&`+`#xxx`这样写就不会保存后丢失了

评分

3

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-8 08:05 | 显示全部楼层
wanghan519 发表于 2024-1-8 07:03
大佬,是不是&#x在xml里解析出错,把&#分开比如,`xxx&`+`#xxx`这样写就不会保存后丢失了

,哈哈,厉害厉害,确实是这个原因,WPS会把JS代码以xml的格式保存在JDEData.bin文件下,果然是高手,这种小细节都能发现。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-10 12:04 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
大佬,jsa里面怎么发送formdata数据呢
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-21 18:27 , Processed in 0.047529 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表