目前在学习 JS,主要目的是写一个油猴脚本,我的理解是油猴中写的 JS 脚本可以外挂在需要执行的网页当中。
目前我的需求是,先获取网页当中的 href 超链接(目前已经实现)
然后通过油猴的“GM_xmlhttpRequest”去访问这个超链接,并返回源码(这一步也已经实现)
剩下的就是解析源码了,但是我也需要获取源码中的节点嘛,那我本来获取 href 超链接可以使用 document.getElementsByClassName 的方式去获取,但现在返回回来的源码是一个 String 类型的数据,他没法使用类似 getElementsByClassName 的方法去定位,所以我来问问有没有什么方法可以实现让 String 数据继承,如果没有的话,我就要想办法用正则去实现了。。。
我看了其他人写的代码,基本上都用到了一些库可以解析,比如 request,Cheerio 啥的,但是我琢磨了下发现都似乎无法在油猴上实现导入这些库。
如果各位大佬有更好的方案也请指教。。
1
Rache1 2021-06-07 21:50:38 +08:00 2
var el = document.createElement('div');
el.innerHTML = <返回的源码字符串> 然后 el.getElementsByClassName 这些方法就可以用了 |
2
tyx1703 2021-06-07 21:50:48 +08:00 1
1. 首先利用 `document.createElement` 创建一个顶级节点 el,然后 `el.innerHTML = source`, 最后用 `el.getElementsByClassName`
2. 利用 jQuery |
3
iNaru 2021-06-07 21:52:21 +08:00 1
GM_xmlhttpRequest({
responseType: "document" }) 或者使用 DOMParser |
4
zhuzhuaini OP @faqqcn 大佬好 前面两步都好了 但是最后用方法的时候会提示 el.getElementById is not a function...
|
5
zhuzhuaini OP @faqqcn 对了 我返回回来的源码 中文全部变成了 一个黑框框 中间是个问号�� 这种是怎么回事 感觉像是编码问题 但是 GM_xmlhttpRequest 似乎没有给我太多的选择让我去返回编码
|
6
tyx1703 2021-06-07 22:20:23 +08:00 1
@zhuzhuaini getElementById 只能通过 document 调用,可以用 el.querySelector 代替。
|
7
zhuzhuaini OP @tyx1703 好的 你知道为什么 GM_xmlhttpRequest 获取回来的源码中文部分是乱码么。。
|
8
muzuiget 2021-06-08 05:53:18 +08:00 1
用 DOMParser 就行了啊。
|
9
tyx1703 2021-06-08 08:19:36 +08:00 via iPhone 1
@zhuzhuaini 抱歉,这个不了解
|
11
duan602728596 2021-06-08 09:22:26 +08:00 1
原生的选择上面已经说了,用 DOMParser 。
用库解析的话就可以考虑 jsdom 、cheerio 、linkedom |
12
Rache1 2021-06-08 09:27:22 +08:00 1
@zhuzhuaini 黑框一般都是中文乱码了,这个可以试着添加 header (Accept-Charset) 来请求服务器发回指定的编码的数据,也可以自行转换编码。
|
13
zhuzhuaini OP |
14
Rhilip 2021-06-08 09:37:54 +08:00 1
上面说 jsdom 、cheerio 、linkedom 都是瞎说。
油猴脚本运行环境是浏览器,而不是 Node,所以方法就: 1. L3 所说的,在 GM_xmlhttpRequest 时直接指定返回类型为 document,让浏览器 xhr 将其直接解析为 Document 最为方便;或是用 DOMParser,这样你可以拿到 string 后做一些修改再解析 2. L2 所说的,用 jQuery 生成一个对象。我认为 jQuery 在 userscript 中还是很有用的。 3. L1 所说的,直接创建一个 document.createElement('div') ,然后修改 innerHTML 。但最不建议的也是这种方法,因为 用 GM_xmlhttpRequest 通常拿到的是完整的网页源代码 |
15
zhuzhuaini OP @faqqcn 尝试了添加 header:
headers: { 'Accept': 'text/html; charset=UTF-8', }, 其中 UTF-8 和 GB2312 我都试了 均无效,感觉这服务器不听我的 哈哈哈 |
16
zhuzhuaini OP @Rhilip 感谢回复,是的,楼上几个方案我都试了,最后发现还是 L3 的来的最简单直接
|
17
zhuzhuaini OP |
18
muzuiget 2021-06-08 09:48:41 +08:00 1
@zhuzhuaini 中文编码用 TextDecoder 转换一下就行了,不要用 GM_xmlhttpRequest,直接用 fetch 函数,拿到 ArrayBuffer 然后传给 TextDecoder 按 GBK 解码,得到 JS 字符串,然后再用 DOMParser 。
|
19
Rhilip 2021-06-08 11:09:07 +08:00 1
@muzuiget 应该是涉及到跨域了,所以不能用 fetch,只能用 GM_xmlhttpRequest 。
其实 GM_xmlhttpRequest 也支持设置 responseType 为 arraybuffer |
20
Rhilip 2021-06-08 11:24:54 +08:00
@zhuzhuaini 关于添加请求头这个肯定没用,服务器不响应 utf-8 的就没用。
有对应测试网址吗? 因为我感觉如果设置 responseType 为 document,编码这个问题应该是浏览器帮忙解决了的。 |
21
zhuzhuaini OP @Rhilip 有的 网址是 http://www.dedecms.com/
我的脚本代码是 GM_xmlhttpRequest({ url: 'http://www.dedecms.com/', onload: function(res){ var resp = res.response console.log(resp) }}) 我目前是测试 所以我随便找了个网页(百度首页),把脚本通过油猴挂载到百度里 ,但是控制台输出的源码就是中文会是乱码 |
22
zhuzhuaini OP @Rhilip 即时我设置 responseType 为 document 代码如下
GM_xmlhttpRequest({ url: '和谐', responseType: "document", onload: function(res){ var resp = res.response console.log(resp) }}) 问题依旧 |
23
duan602728596 2021-06-08 12:40:33 +08:00 1
其实 jsdom 、cheerio 、linkedom 是可以在浏览器中使用的,只不过没提供浏览器能使用版本而已。
我现在在浏览器中处理 html 就是用的 DOMparser 和 cheerio (因为 DOMparser 不能在 webworker 的环境中使用)。 不过看来 LZ 也不一定会用 webpack 和 rollup,还是用 DOMparser 吧。 |
24
Rache1 2021-06-08 12:43:29 +08:00 1
@zhuzhuaini 😂 这个是取决于服务器的实现,服务器没有实现这一块的话,也没办法,只有自己转了
|
25
Rache1 2021-06-08 12:45:31 +08:00 1
@Rhilip 😂 我看文档里面写的是 「 responseType one of arraybuffer, blob, json 」,不过好奇为啥 document 也可以用(没有尝试)
|
27
mopig 2021-06-08 13:15:48 +08:00 1
加上 overrideMimeType: 'text/html;charset=gb2312' 就行了 😁
|
28
zhuzhuaini OP @mopig 秒啊! 可以封贴了
|
29
zhuzhuaini OP 感谢楼上的各位帮助 不胜感激!
|