- C20250069's blog
JS 爬虫
- 2023-3-9 22:24:49 @
本文介绍如何在网站中获取别的网站显示的内容(类似于源码)。
本文同时在洛谷和校内OJ发布。
涉及工具
- 合适的浏览器。(废话
- 支持
<iframe>
标签的浏览器和网页。(主要 - 理解 Javascript 与 HTML 的脑子。(可无
对于工具 1,基本所有浏览器都满足。
对于工具 2,基本所有浏览器都满足,但不是每个网页都支持 <iframe>
,比如说 luogu.com.cn
(与 bilibili
签订了协议),这意味着你不能在该网页上进行爬虫操作。
原理
利用 HTMLIframeElement.contentWindow
获取网页信息。
具体实现步骤
先给出整体代码,再分析。
let ie = document.createElement("iframe");
ie.src = "你的地址";
ie.width = ie.height = 0;
ie.style.position = "fixed";
ie.onload = () => {
// 处理源码
ie.contentWindow;
// ...
document.body.removeChild(ie);
}
document.body.appendChild(ie);
第一行,不用说了。
第二行,“你的地址”即想获取源码的地址,这个网站可以不支持 <iframe>
标签,但必须支持 <iframe>
引用(本文暂不介绍不支持引用的源码获得)。注意,假设你调用该代码时的网址为 https://some.website.com/114514
,则 luogu.com.cn
会被解析为 https://some.website.com/114514/luogu.com.cn
,而 https://luogu.com.cn
会被解析为 https://luogu.com.cn
。
第三行和第四行,为了就是使该 <iframe>
不会被看到(显示)。
第五行起的函数,即处理网页内容。下面列举了几个常用的值(令 iw = ie.contentWindow
)。
名称 | 用途(值) |
---|---|
iw |
src 网页内的 window 全局变量 |
iw.document |
src 网页内的 document 变量 |
iw.document.body |
src 网页内的 body 元素 |
iw.document.head |
src 网页内的 head 元素 |
同时,HTMLElement.innerHTML
为该元素内部的 html
源码。
第九行,删除该 <iframe>
,删除以减少冗余的内存消耗。
第十一行,运行爬虫。
运行实例
此处理在 Hydro OJ 上运行。
应用
显示题目发表者。(使用 Hydro OJ)
let table = document.getElementsByClassName("data-table hide-problem-tag")[1].rows;
for (let i = 0; i < table.length; i++)
{
let ie = document.createElement("iframe");
ie.src = table[i].children[3].children[1].href;
ie.width = ie.height = 0;
ie.style.position = "fixed";
ie.onload = () => {
let author = ie.contentWindow.document.getElementsByClassName("user-profile-link")[0];
author.parentNode.removeChild(author);
let li = document.createElement("li");
li.className = "problem__tag";
li.innerHTML = "<a class=\"problem__tag-link\" href=\"" + author.children[1].href + "\">" + author.children[1].innerText + "</a>";
if (table[i].children[3].children[2] == undefined)
{
table[i].children[3].appendChild(document.createElement("ul"));
table[i].children[3].children[2].className = "problem__tags";
}
table[i].children[3].children[2].appendChild(li);
console.log(i);
}
document.body.appendChild(ie);
}
实测,速度较慢。