如何将Discord机器人的图片搜索源从Dogpile替换为Google
Google图片爬取适配调整方案
原逻辑无法直接切换到Google的原因
基于Dogpile的爬取逻辑依赖无强反爬的静态HTML结构、固定DOM选择器,直接把请求地址换成Google就失效,核心原因是Google图片搜索存在多层反爬机制:
- 不符合真实浏览器特征的请求会被直接拦截,返回人机验证页面,不会输出正常的搜索结果HTML
- Google图片页的DOM结构和Dogpile完全不同,原来针对Dogpile写的
.image a.link选择器根本匹配不到元素 - 页面里的高分辨率原图链接做了加密混淆,没有直接嵌在常规a标签的href属性里,照搬原来的解析逻辑拿不到有效URL
具体代码调整
核心改动点
- 把写死的
example image关键词替换成从用户消息里动态提取的实际搜索词,对关键词做URL编码,避免中文、特殊字符导致请求格式错误 - 补全完整的浏览器请求头,替换原来过于简略的
"User-Agent": "Chrome"配置,降低被反爬识别的概率 - 替换请求地址为Google图片搜索的专用路径,附加
tbm=isch参数直接拉取图片结果页 - 替换匹配元素的选择器,过滤掉无效的占位图、品牌logo,只提取可直接访问的http格式图片地址
- 保留原有的随机选图、频道消息发送逻辑,不需要改动这部分代码
调整后的对应函数代码:
function image(message){ // 从用户输入中截取实际搜索关键词,跳过命令本身的参数 const searchQuery = message.content.substring(PREFIX.length).split(" ").slice(1).join(" "); if(!searchQuery) { return message.channel.send("请输入要搜索的图片关键词"); } var options = { // 对搜索词做URL编码,拼接Google图片搜索地址 url: `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}&tbm=isch`, method: "GET", headers: { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", // 替换为真实桌面Chrome的完整User-Agent,不要写简化的"Chrome" "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" } }; request(options, function(error, response, responseBody) { if (error) { return message.channel.send("图片搜索请求失败,请稍后重试"); } $ = cheerio.load(responseBody); // 筛选有效图片地址:只取http开头的网络图片,过滤base64占位图、Google logo var linkNodes = $("img").filter((i, el) => { const src = $(el).attr("src"); return src && src.startsWith("http") && !src.includes("google.com/logos"); }); var urls = new Array(linkNodes.length).fill(0).map((v, i) => linkNodes.eq(i).attr("src")); if (!urls.length) { return message.channel.send("没有获取到匹配的图片结果"); } // 随机选图发送到频道 message.channel.send(urls[Math.floor(Math.random() * urls.length)]); }); }
常见踩坑修复
- 调整请求头后如果还是收到人机验证拦截,可以在配置里补充有效浏览器会话的Cookie字段;注意不要把敏感Cookie硬编码到公开仓库的代码中,避免账号泄露
- 不要尝试抓取页面源码中加密的高分辨率原图链接,这类链接带临时时效参数,访问时大概率失效;优先抓取页面直接加载的缩略图地址,稳定性更高
- 如果搜索结果为空,先打印返回的responseBody内容确认是否被反爬拦截,不要静默返回不做提示
内容的提问来源于stack exchange,提问作者DumBot
相关产品推荐
相关产品推荐

