在《聚BT浏览器扩展自定义网站从入门到精通1-HTTP请求类型GET、GET_CUSTOM》中介绍了聚BT浏览器扩展自定义网站的GET、GET_CUSTOM两种HTTP请求类型,这篇重点介绍新标签页(NEWTAB)、新标签页-iframe(NEWTAB_IFRAME)两种类型。
为何搞出NEWTAB)、NEWTAB_IFRAME)两种类型?
这两种类型的典型使用场景:
1、网站使用了AJAX请求,实际的搜索结果是异步加载,例如腾讯音乐、虾米等。
2、网站对HTTP 请求做了加密、特殊编码处理,例如music.163.com、知网CNKI等。
这两种类型场景,都涉及多次HTTP请求-响应交互,而XMLHTTPREQUEST只能处理单一的请求->响应交互,要处理以上复杂场景,只能采用分析多次请求报文和页面源文件代码,极为繁琐,对应网站一改版,只能重新调整,方法很难通用。此种方案对普通用户门槛过高(对程序猿也是痛苦的事),因此对页面请求过于复杂的网站,抛弃直接使用XMLHTTPREQUEST的方案。
由于chrome 扩展中不能像Headless Chrome那样,给出一个URL,等页面所有内容装载完后(包括AJAX、CSS、Javascript文件)再解析。Chrome也不允许像Firefox那样的隐藏tab功能(tabs.hide)。于是new tab/popup window成为唯一选择。相对于popup window,new tab体验上相对好些,因此针对以上两种场景的网站,采用新标签页(NEWTAB)的方案。
由于有些网站,页面包含了iframe,在通过 chrome.tabs.sendMessage发送消息给页面时候,所有的iframe都会接收到请求,为区分对应的iframe,因此将NEWTAB分为:新标签页(NEWTAB)、新标签页-iframe(NEWTAB_IFRAME)两种类型。
简单地说,新标签页(NEWTAB)、新标签页-iframe(NEWTAB_IFRAME)的区别在于:
新标签页(NEWTAB)适用于页面无iframe的场景。
新标签页-iframe(NEWTAB_IFRAME)适用于页面有iframe的场景。
自定义站点界面与NEWTAB、NEWTAB_IFRAME相关的重点设置项
在用户新增/修改自定义站点界面中,与新标签页(NEWTAB)、新标签页-iframe(NEWTAB_IFRAME)相关的重点设置项主要包括:
1、HTTP请求类型
2、页面CSS选择代码
3、网站搜索代码(searcher)
4、网站解析代码(parser)
页面CSS选择代码
由于用对应的搜索URL作为目标地址,新打开标签页搜索,需要判断页面是否完成装载。聚BT浏览器扩展会使用“页面CSS选择代码”的值作为判断依据,轮询标签页装载情况。
为避免页面装载不成功情况(例如网站down掉),聚BT浏览器会等待10秒(轮询频次为1秒,轮询10次),失败则返回。
页面CSS选择代码遵循标准的 CSS Selector。常用的CSS Selector及实际例子,后面文档会以案例形式说明。
NEWTAB、NEWTAB_IFRAME适用的HTTP 请求类型
大部分情况下,NEWTAB、NEWTAB_IFRAME都为GET类型,也即在请求URL包含了搜索关键词。
个别网站为POST,也即在URL没有包含任何搜索关键词,需要打开标签页后以POST类型提交搜索请求。
网站搜索代码(searcher)
由于NEWTAB、NEWTAB_IFRAME 中需要自定义searcher的网站较少,这里暂不讲解,等入门后,再举例子说明NEWTAB、NEWTAB_IFRAME 自定义searcher的用法。
对大部分网站,直接保持此输入项为空。
网站解析代码(parser)
parser与GET、GET_CUSTOM在整体处理逻辑上没有差别,但仍然有一些差异。
以music.163.com的parser为例
function music163Parser(url, source, keyword) {
const elements = document.querySelectorAll("div.item div.sn div.text a:nth-child(1)");
let hrefs = [];
for (let element of elements) {
let href = element.getAttribute("href");
if (href) {
href = relativeUrlToAbsolute(href, url);
let text = element.innerText;
let desc = keyword;
if (href && text) {
hrefs.push({ link: href, linkText: text, desc: desc, source: source, keyword: keyword, url: url, type: "music" });
}
}
}
return hrefs;
}
对照一下动漫花园的例子
function dmhyParser(content, url, source, keyword) {
let myDocument = documentFactory(content);
const elements = myDocument.querySelectorAll("tr td.title a");
let hrefs = [];
for (let element of elements) {
let href = element.getAttribute("href");
if (href) {
href = relativeUrlToAbsolute(href, url);
let text = element.innerText;
let desc = keyword;
if (href && text) {
hrefs.push({ link: href, linkText: text, desc: desc, source: source, keyword: keyword, url: url, type: "acg" });
}
}
}
return hrefs;
}
最大差别在于:对document的获得上。
NEWTAB、NEWTAB_IFRAME直接用document
而在GET/GET_CUSTOM中,是
let myDocument = documentFactory(content);
const elements = myDocument.querySelectorAll("tr td.title a");
也即在GET/GET_CUSTOM中,用searcher的搜索结果content构建自己的document,以使用CSS Selector。而在NEWTAB、NEWTAB_IFRAME直接使用了当前window的document。
再次强调一下,在用户自定义界面,在自定义界面的”网站解析代码“字段,不需要输入函数名,只需要输入函数体部分,也即:
const elements = document.querySelectorAll("div.item div.sn div.text a:nth-child(1)");
let hrefs = [];
for (let element of elements) {
let href = element.getAttribute("href");
if (href) {
href = relativeUrlToAbsolute(href, url);
let text = element.innerText;
let desc = keyword;
if (href && text) {
hrefs.push({ link: href, linkText: text, desc: desc, source: source, keyword: keyword, url: url, type: "music" });
}
}
}
return hrefs;
这一讲先到这儿,下一讲继续讲解网站请求类型POST。