示例:获取百度搜索结果
说明
由于百度不直接提供搜索接口,所以我们需要模拟操作。
核心流程:
- 构造搜索链接
- 访问后,获取页面的数据结果
注意事项
但是请注意,我们当前启动的页面,请不要再跳转到另一个链接,否则会导致当前页面断开和OPENUGC的链接,后续的操作就无法继续进行了。
解决方案
所以,我们采用另一种思路,将搜索链接通过iframe
嵌入到当前页面,由于搜索链接和当前启动的页面链接是同一个域名,我们就可以在主页面对iframe
页面进行数据获取等操作了。
解决方案:
- 构造搜索链接
- 通过iframe嵌入加载
- 通过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(); } });}