🔍 百度搜索插件开发实战
🧠 技术实现思路
核心挑战
🛑 百度搜索限制:
- 无公开API接口
- 直接跳转会导致连接中断
- 跨域数据获取限制
创新解决方案
💡 iframe沙箱技术:
- 保持主页面连接稳定
- 通过同源iframe加载目标内容
- 主页面操控iframe DOM提取数据
⚠️ 关键注意事项
-
连接保持:
- 禁止页面跳转
- 维持OPENUGC通信链路
-
异常处理:
- 网络超时重试机制
- DOM解析容错设计
- 内存泄漏防护
🛠️ 优化版代码实现
async (args) => { // 参数标准化处理 const { keyword, count = 5 } = args; const MAX_RETRY = 3;
// 核心搜索函数 const baiduSearch = async (page = 1, retryCount = 0) => { return new Promise(async (resolve, reject) => { // 超时控制(25秒) const timeout = setTimeout(() => { iframe.remove(); retryCount < MAX_RETRY ? resolve(baiduSearch(page, retryCount + 1)) : reject('请求超时'); }, 25000);
// iframe构建 const iframe = document.createElement('iframe'); iframe.style = 'position:absolute;width:0;height:0;border:none'; iframe.src = `https://www.baidu.com/s?wd=${encodeURIComponent(keyword)}&pn=${(page-1)*10}`;
// 成功回调 iframe.onload = () => { clearTimeout(timeout); try { const results = Array.from(iframe.contentDocument.querySelectorAll('.result')) .slice(0, count) .map(item => ({ title: item.querySelector('h3')?.innerText.trim() || '无标题', desc: item.querySelector('[data-module="abstract"]')?.innerText.trim() || '无描述', link: item.getAttribute('mu')?.trim() || '#' })); iframe.remove(); resolve(results); } catch (error) { reject(`解析错误: ${error.message}`); } };
// 错误处理 iframe.onerror = () => { clearTimeout(timeout); reject('iframe加载失败'); };
document.body.appendChild(iframe); }); };
// 分页采集逻辑 try { let finalResults = []; for (let page = 1; finalResults.length < count; page++) { const pageResults = await baiduSearch(page); finalResults = [...finalResults, ...pageResults];
// 结果达标立即返回 if (finalResults.length >= count) { return finalResults.slice(0, count); }
// 请求间隔(防封禁) await new Promise(resolve => setTimeout(resolve, 1000)); } return finalResults; } catch (error) { return { error: error.toString() }; }}
🎯 优化亮点
-
健壮性提升:
- 增加最大重试次数限制
- 完善错误边界处理
- 内存泄漏防护
-
性能优化:
- 精确控制超时时间
- 智能分页加载
- 合理请求间隔
-
代码可读性:
- 模块化功能拆分
- 清晰的错误处理链
- 完善的代码注释
💡 专业建议:实际开发中建议添加请求指纹伪装和IP轮询机制,避免被目标网站封禁。