上一章 讲解了聚BT浏览器扩展自定义网站中,HTTP请求类型为“GET-缺省”的例子,这一章继续讲解与GET类型相关的几种类型。
- GET-自定义(GET_CUSTOM)
- GET类型的新开标签页(NEWTAB),也即HTTP请求类型为GET,但以新开标签页方式打开。
- GET类型的新开标签页-iframe(NEWTAB_IFRAME),也即HTTP请求类型为GET,但以新开标签页方式打开,新开的标签页包含有iframe
可能有些同学会有疑问,聚BT浏览器扩展的HTTP请求类型不是分为 GET、GET_CUSTOM以及NEWTAB、NEWTAB_IFRAME、POST5种HTTP请求类型吗?怎么又搞出一个GET类型的新开标签页、GET类型的新开标签页-iframe?
其实在《聚BT浏览器扩展自定义网站从入门到精通2-HTTP请求类型NEWTAB、NEWTAB_IFRAME》提到过,NEWTAB和NEWTAB_IFRAME对GET、POST两种类型都会存在。由于这章是讨论GET类型,因此只讲述GET类型下的NEWTAB、NEWTAB_IFRAME,POST类型下的NEWTAB、NEWTAB_IFRAME在后面讲解。
GET-自定义(GET_CUSTOM)
聚BT浏览器扩展缺省提供的seacher的底层封装代码为:
1 2 3 4 5 6 7 8 9 | async function defaultSearcher(url, keyword) { try { let response = await httpGet(url); return response.body; } catch (err) { console.info( "searcher.js err: " + JSON.stringify(err, Object.getOwnPropertyNames(err), 2)); return null ; } } |
再次强调一下,在自定义界面对应的“网站搜索代码”为:
1 2 3 4 5 6 7 | try { let response = await httpGet(url); return response.body; } catch (err) { console.info( "searcher.js err: " + JSON.stringify(err, Object.getOwnPropertyNames(err), 2)); return null ; } |
可以看出,输入参数就是:
url(也即自定义界面的“网站搜索地址”):请求网站的搜索url,例如:https://dmhy.anoneko.com/topics/list?keyword=searchkeyword
keyword:搜索关键词。
然后用httpGet请求搜索url,返回搜索结果给parser。
httpGet为聚BT浏览器扩展底层对XMLHTTPREQUEST的简单封装,后面会做详细讲解。
因此对于GET_CUSTOM,可以在此模板基础上,按照需求修改。
例如:缺省的模板,对请求url中的keyword的编码是使用encodeURIComponent 以UTF-8编码,对一些采用GBK/GB2312编码的网站就不适用了。
以阳光电影 https://www.ygdy8.com 为例,其网站采用了GB2312编码,采用GET_CUSTOM。
对应的“网站搜索地址”为:http://s.ygdy8.com/plus/so1.php?typeid=1&keyword=searchkeyword
对应的“网站搜索代码”为:
1 2 3 4 5 6 7 8 9 10 11 12 13 | try { let utf8Keyword = encodeURIComponent(keyword); let gbkKeyword = GBK.URI.encodeURI(keyword); url = url.replace(utf8Keyword, gbkKeyword); let response = await httpGet(url, "arraybuffer" ); let dataView = new DataView(response.body); let decoder = new TextDecoder( "GBK" ); let gbkResponse = decoder.decode(dataView); return gbkResponse; } catch (err) { console.info( "searcher.js err: " + JSON.stringify(err, Object.getOwnPropertyNames(err), 2)); return null ; } |
以上代码核心逻辑是:
a、将传入的keyword用GBK编码,替换缺省的UTF-8编码的keyword
b、以arraybuffer类型请求http://s.ygdy8.com/plus/so1.php?typeid=1&keyword=searchkeyword
c、将httpGet的请求结果以GBK编码解码
d、返回UTF-8编码给parser(Javascript内部都以UTF-8编码)
GET类型的新开标签页(NEWTAB)
seacher为GET类型的新开标签页的使用场景相对较少,目前聚BT浏览器扩展支持的几百个网站中,只有一个使用了此种类型。
以 https://www.cnki.net 为例,由于cnki的页面搜索请求交互较为繁琐,对部分字段还采用了JavaScript加密,如果采用GET_CUSTOM方式,要分析整个请求报文及相关JavaScript代码,极为麻烦。
简单分析一下请求报文,可以发现cnki搜索请求符合GET类型的新开标签页。
对应的网站搜索地址为:https://kns.cnki.net/kns8/defaultresult/index
对应的“网站搜索代码”为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | if (document.getElementById( "txt_search" )) { let element = document.getElementById( "txt_search" ); element.value = keyword; var handler = setInterval( function () { element = document.getElementById( "txt_search" ); //console.debug("parserNewTab.js cnkiSearcher value1 is: " + element.value); if (element.value == keyword) { //console.debug("parserNewTab.js cnkiSearcher value2 is: " + keyword); clearInterval(handler); document.querySelector( "input.search-btn" ).click(); setTimeout( function () {}, 1000); } else { cnkiSearcher(keyword); } }, 1000); } else { total++; if (total < 7) { cnkiSearcher(url, keyword); } } |
核心思路:
a、以NEWTAB方式打开 https://kns.cnki.net/kns8/defaultresult/index
b、等待界面装载完成(递归循环调用7次)
c、在界面上将搜索输入框设置为对应的keyword
d、模拟搜索操作
e、将搜索结果返回给parser
对应的“网站解析代码”(parser)为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | const elements = document.querySelectorAll( "td.name a" ); let hrefs = []; for (let element of elements) { let href = element.getAttribute( "href" ); let match = href.match(/FileName=(.*)&DbName=(.*)&DbCode=(.*)&/); if (match) { let filename = match[1]; let dbname = match[2]; let dbcode = match[3]; href = "https://kns.cnki.net/kcms/detail/detail.aspx?filename=" + filename + "&dbname=" + dbname + "&dbcode=" + dbcode; let text = element.innerText; let desc = keyword; console.debug( "parser.js mikuclubParser href is: " + href + ", text is:" + text); if (href && text) { hrefs.push({ link: href, linkText: text, desc: desc, source: source, keyword: keyword, url: url, type: "scholar" }); } } } return hrefs; |
与GET类型和GET_CUSTOM不同,NEWTAB和NEWTAB_IFRAME都在自定义界面都多了一个必填字段:页面CSS选择代码。
此字段用于判断页面是否完成装载,一般可以与parser中的搜索结果记录的CSS Selector即可。
对cnki,页面CSS选择代码,填写:td.name a
对应cnki网站解析代码中的:
对应的“网站解析代码”(parser)的CSS Selector为:
1 | const elements = document.querySelectorAll( "td.name a" ); |
GET类型的新开标签页-iframe(NEWTAB_IFRAME)
对GET类型的新开标签页-iframe(NEWTAB_IFRAME),以网易云音乐为例,
网站搜索地址为:https://music.163.com/#/search/m/?s=searchkeyword&type=1
对应的searcher可以采用系统缺省的GET,也即“网站搜索代码”保持为空,或者用缺省搜索代码:
1 2 3 4 5 6 7 8 | try { let response = await httpGet(url); //console.debug("searcher.js er httpGet response :" + response); return response.body; } catch (err) { console.info( "searcher.js err: " + JSON.stringify(err, Object.getOwnPropertyNames(err), 2)); return null ; } |
对应的parser为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; //console.debug("parser.js music163Parser href is: " + href + ", text is:" + text); if (href && text) { hrefs.push({ link: href, linkText: text, desc: desc, source: source, keyword: keyword, url: url, type: "music" }); } } } return hrefs; |
与GET类型自定义相关的几种类型讲解完成,下一章讲解POST类型的自定义例子。