Skip to content

示例:获取百度搜索结果

说明

由于百度不直接提供搜索接口,所以我们需要模拟操作。

核心流程:

  1. 构造搜索链接
  2. 访问后,获取页面的数据结果

注意事项

但是请注意,我们当前启动的页面,请不要再跳转到另一个链接,否则会导致当前页面断开和OPENUGC的链接,后续的操作就无法继续进行了。

解决方案

所以,我们采用另一种思路,将搜索链接通过iframe嵌入到当前页面,由于搜索链接和当前启动的页面链接是同一个域名,我们就可以在主页面对iframe页面进行数据获取等操作了。

解决方案:

  1. 构造搜索链接
  2. 通过iframe嵌入加载
  3. 通过js获取iframe的dom,筛选出搜索数据返回

示例代码

这段代码包含了多页面数据获取、数据超时失败处理等方案,值得参考学习

async (args) => {
let { keyword, count }= args;
count = count ? count : 5;
const baiduSearch = async(page = 1) => new Promise((RES, REJ) => {
console.log('baidusearch:', keyword, page)
// 超时处理
const timer = setTimeout(async () => {
console.log('超时了,重试中');
const result = await baiduSearch(page);
return RES(result);
}, 1000 * 30); // 30s
const url = `https://www.baidu.com/s?wd=${encodeURIComponent(keyword)}&pn=${page * 10}`;
const dom = document.createElement('iframe');
dom.style = 'display:none';
dom.src = url;
dom.onload = () => {
console.log('加载完成,开始解析数据')
clearTimeout(timer);
try {
const _result = Array.from(dom.contentDocument.querySelectorAll('.result')).map(dom => ({
title: dom.querySelector('h3').innerText.trim(),
desc: dom.querySelector('[data-module="abstract"]').innerText.trim(),
link: dom.getAttribute('mu').trim()
}));
dom.remove();
return RES(_result);
} catch(e) {
REJ(`解析数据失败:${e.message}`);
}
};
dom.onerror = REJ;
document.body.appendChild(dom);
});
const sleep = async(t = 1000) => new Promise(RES => setTimeout(RES, t));
return new Promise(async (RES, REJ) => {
let result = [];
let currentPage = 1;
while (count > result.length) {
let data;
try {
data = await baiduSearch(currentPage);
} catch(e) {
return RES(e.message);
}
result = result.concat(data);
if (result.length >= count) {
RES(result.slice(0, count));
break;
}
currentPage += 1;
await sleep();
}
});
}