上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
12下一页
返回列表 发新帖

关于html文本转DOM

[复制链接]
  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2021-9-11 21:21:46 | 显示全部楼层 | 阅读模式

    当我们用ajax获取数据时,有时返回的是一个页面,获取的response是一段html文本,如果我们想获得某些元素的数据要怎么做呢?可能你第一反应是做正则,但这么一大段文本,正则其实非常难写,写出来也很难看,有没有更优雅的办法呢?答案是转换为DOM(页面的document就是一个DOM),然后就可以用querySelector等方法来操作。如何将string转换为DOM?你可能想到利用innerHTML,先创建一个html元素,然后令其innerHTML = string即可。jquery中也可以直接$(string)来实现转换,其本质上也是通过innerHTML实现的,不过由于jquery创建的元素类型为div,会导致转换后的head和body不见了,两部分元素挤到了一起。

    innerHTML的思路看似美好,实际存在严重的性能问题:不管你有没有将元素添加到页面中,innerHTML都会预加载其中的图片,这在多数情况下是好事(大部分图片最终都会被添加到页面中),但在我们的脚本里却是坏事。为了测试这一现象,你可以在随便打开一个页面,在控制台输入这行代码:

    document.createElement('html').innerHTML = '<img src="https://bbs.tampermonkey.net.cn/favicon.ico">'

    然后切换到Network标签观察一下,可以看到一张favicon.ico的图片被加载进来了。想象一下有这样一个脚本,从多个链接中读取html,每个都取一点数据,实现一个爬虫类的效果。这种需求并不少见,但如果用innerHTML实现,想想我们会加载多少毫无意义的图片,性能方面简直就是一场灾难。

    有没有更好的转换方法?不需要借助第三方库,原生js就可以实现:new DOMParser().parseFromString(),接收2个参数,第1个是你要转换的字符串,第2个是mime类型,形如“text/html”、“text/xml”等等(更多细节请参阅这里)。他相比innerHTML不会去加载图片,在脚本中使用性能优势明显。如果你熟悉XMLHttpRequest,可能知道xhr的responseType可以设置为document,从而直接得到DOM,这本质上也是DOMParser操作,xhr会根据响应头的Content-Type来设置mimeType。注意这2种类型并不完全相同,Content-Type除了包含mimeType,还有charset编码信息等内容(Content-Type的介绍可以看这里)。

    在GM_xmlhttpRequest中,也可以设定responseType为document,但是据我测试,至少在部分版本的Tampermonkey中,GM_xmlhttpRequest是直接令mimeType等于响应头的Content-Type,前面提到两种type不一样,当Content-Type中含有charset等字段时,转换就会失败,控制台报TypeError错误(关于这个bug的讨论可以看这里这里)。其实XMLHttpRequest提供了一个overrideMimeType方法,用于覆盖响应头的Content-Type,GM_xmlhttpRequest也提供了,但实际上该属性没有正确生效。Tampermonkey在后续版本中似乎已经修复了这个bug,但考虑到你的用户不一定会保持更新,如果你是个脚本开发者,出于兼容性考虑,我不建议使用GM_xmlhttpRequest的document方式,应该改用text获取文本,再自己做DOMParser转换。

    gm.png

    已有2人评分好评 油猫币 贡献 理由
    懒男孩 + 1 + 2 + 1 ggnb!
    李恒道 + 1 + 1 + 1 ggnb!

    查看全部评分 总评分:好评 +2  油猫币 +3  贡献 +2 

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2021-9-11 21:25:02 | 显示全部楼层
    学到了,大佬严谨
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-7-5 00:02
  • 签到天数: 124 天

    [LV.7]常住居民III

    5

    主题

    168

    回帖

    927

    积分

    版主

    积分
    927

    荣誉开发者油中2周年

    发表于 2021-9-11 22:18:46 | 显示全部楼层
    get 了!!!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-6-21 00:00
  • 签到天数: 202 天

    [LV.7]常住居民III

    11

    主题

    196

    回帖

    255

    积分

    高级工程师

    积分
    255

    油中2周年

    发表于 2021-9-11 22:37:42 | 显示全部楼层
    np!!!!!学到了
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 13:37
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4189

    回帖

    4056

    积分

    管理员

    积分
    4056

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2021-9-12 09:09:37 | 显示全部楼层
    学习了,脚本猫实现的时候注意一下
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-7-30 00:00
  • 签到天数: 122 天

    [LV.7]常住居民III

    29

    主题

    601

    回帖

    542

    积分

    专家

    积分
    542

    油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2021-9-12 13:22:56 | 显示全部楼层
    哥哥是 一群小母牛排队上一头小公牛呀,牛逼何其多一个接一个
    原来不经意间的小细节竟有大学问!请继续吧
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2021-9-16 10:23:11 | 显示全部楼层
    可以,学到了,解决了我的疑惑~
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2021-9-16 11:26:07 | 显示全部楼层
    jiabing 发表于 2021-9-16 10:23
    可以,学到了,解决了我的疑惑~

    哥哥来了!哥哥牛逼!
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-7-16 15:40
  • 签到天数: 276 天

    [LV.8]以坛为家I

    115

    主题

    460

    回帖

    997

    积分

    荣誉开发者

    积分
    997

    荣誉开发者油中2周年卓越贡献生态建设者油中3周年

    发表于 2022-6-19 13:52:13 | 显示全部楼层
    大佬太牛逼了
    接脚本定制
    I frequently record, because want to leave something.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-6-21 11:19
  • 签到天数: 1 天

    [LV.1]初来乍到

    0

    主题

    1

    回帖

    4

    积分

    助理工程师

    积分
    4
    发表于 2022-6-21 11:29:35 | 显示全部楼层
    牛!学习到了
    回复

    使用道具 举报

    发表回复

    本版积分规则

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