You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Selenium谷歌图片爬虫多查询返回相同图片src?

问题描述

我在Express服务器上搭建了谷歌图片爬虫,接收查询数组后本应返回每个查询对应首条图片的src值,但传入数组时会多次返回第一个查询的src结果。单查询场景运行正常,试过sleep、until等方法仍无效。另外想知道能否在后端通过并发方式提速,之前在客户端用Promise.all()实现时返回数组异常。

附现有代码:

let queryArr = ['cat', 'dog', 'cheeta', 'boy', 'girl', 'lion']

let driver = undefined;
const startSelenium = async () => {
  const options = new Options();
  options.addArguments('--headless')
  options.addArguments('--no-sandbox')
  options.addArguments('--incognito')
  driver = await new Builder().forBrowser('chrome').setChromeOptions(options).build();
}

const Scrape = async (queryArr) => {

  if (!driver) {
    await startSelenium();
  }

  try {
    let imgSources = [];
    for (const query of queryArr) {
      const url = `https://www.google.com/search?site=&tbm=isch&source=hp&biw=1873&bih=990&q=${query}`;
      await driver.get(url);
      const img = await driver.findElement(By.className('Q4LuWd'));
      const imgSrc = await img.getAttribute('src');
      imgSources.push(imgSrc);
    }
    return imgSources;
  } catch (e) {
    console.log(`Scrape() error: \n${e}`);
  }
};

解决方案

一、修复重复返回src的问题

问题核心是谷歌图片搜索的DOM加载机制:页面跳转后,旧页面的DOM元素可能仍留在内存中,findElement会直接拿到缓存的旧元素,而非当前页面的新元素。需要添加显式等待确保获取当前页面的有效元素,同时对查询参数做URL编码避免异常。

修改后代码:

// 确保导入until模块
const { Builder, Options, By, until } = require('selenium-webdriver');

let driver = undefined;
const startSelenium = async () => {
  const options = new Options();
  options.addArguments('--headless')
  options.addArguments('--no-sandbox')
  options.addArguments('--incognito')
  driver = await new Builder().forBrowser('chrome').setChromeOptions(options).build();
}

const Scrape = async (queryArr) => {
  if (!driver) {
    await startSelenium();
  }

  try {
    let imgSources = [];
    for (const query of queryArr) {
      // 对查询参数做URL编码,避免特殊字符破坏URL结构
      const encodedQuery = encodeURIComponent(query);
      const url = `https://www.google.com/search?site=&tbm=isch&source=hp&biw=1873&bih=990&q=${encodedQuery}`;
      await driver.get(url);
      
      // 显式等待元素被定位到且可见,超时时间10秒
      const img = await driver.wait(until.elementLocated(By.className('Q4LuWd')), 10000);
      await driver.wait(until.elementIsVisible(img), 10000);
      
      const imgSrc = await img.getAttribute('src');
      imgSources.push(imgSrc);
    }
    return imgSources;
  } catch (e) {
    console.log(`Scrape() error: \n${e}`);
  }
};

二、后端实现并发提速

单个Selenium Driver实例无法真正并发(同一时间只能处理一个页面),可以创建多个Driver实例,通过Promise.all并行处理多个爬取任务:

const { Builder, Options, By, until } = require('selenium-webdriver');

// 单个查询的独立爬取函数
const scrapeSingleQuery = async (query) => {
  const options = new Options();
  options.addArguments('--headless')
  options.addArguments('--no-sandbox')
  options.addArguments('--incognito');
  
  const driver = await new Builder().forBrowser('chrome').setChromeOptions(options).build();
  
  try {
    const encodedQuery = encodeURIComponent(query);
    const url = `https://www.google.com/search?site=&tbm=isch&source=hp&biw=1873&bih=990&q=${encodedQuery}`;
    await driver.get(url);
    
    const img = await driver.wait(until.elementLocated(By.className('Q4LuWd')), 10000);
    await driver.wait(until.elementIsVisible(img), 10000);
    
    return await img.getAttribute('src');
  } catch (e) {
    console.log(`Scrape ${query} error: \n${e}`);
    return null;
  } finally {
    // 无论成功失败,确保关闭Driver释放资源
    await driver.quit();
  }
};

// 批量并发爬取函数
const Scrape = async (queryArr) => {
  // 限制并发数,避免触发谷歌反爬(建议3-5个以内)
  const batchSize = 3;
  let results = [];
  
  // 分批处理查询数组
  for (let i = 0; i < queryArr.length; i += batchSize) {
    const batch = queryArr.slice(i, i + batchSize);
    const batchResults = await Promise.all(batch.map(query => scrapeSingleQuery(query)));
    results = [...results, ...batchResults];
  }
  
  // 过滤爬取失败的null值
  return results.filter(src => src !== null);
};

内容的提问来源于stack exchange,提问作者Jeff_V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:55:02