聚BT浏览器扩展自定义网站从入门到精通5-HTTP请求类型为“GET-自定义” 和GET类型的NEWTAB/NEWTAB_IFRAME

jubt 2020-11-11 1485

上一章 讲解了聚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类型的自定义例子。


最新回复 (0)
返回
发新帖