JS `Selenium` `WebDriver` 自动化反检测与规避策略

各位观众老爷们,大家好!今天咱们来聊聊一个有点意思的话题:用 JS Selenium WebDriver 搞自动化的时候,怎么躲过那些“火眼金睛”的反爬虫机制。说白了,就是教你“偷偷摸摸”地让你的爬虫更像真人用户,让网站觉得你不是个机器人。

记住,这里讲的都是技术探讨,目的在于学习和研究,千万别干坏事儿啊!

第一部分:为什么会被检测到?(知己知彼,方能百战不殆)

要躲避检测,首先得知道人家是怎么发现你的。网站的反爬虫策略五花八门,但归根结底,都是通过分析你的行为特征来判断你是不是个机器人。常见的特征有:

  1. WebDriver 指纹: Selenium 默认会留下一些痕迹,比如 window.navigator.webdriver 属性为 true
  2. 请求头: 默认的请求头可能缺少一些正常浏览器才有的字段,或者 User-Agent 太明显。
  3. 行为模式: 机器人操作往往过于规律,比如速度太快、点击过于精准等等。
  4. JS 环境: 缺少一些浏览器特有的 API 或者变量。
  5. IP 地址: 大量请求来自同一个 IP,容易被识别为爬虫。
  6. 验证码: 经常遇到验证码,说明你已经被盯上了。

第二部分:磨皮美颜,伪装成人类(反检测的核心技巧)

知道了敌人的套路,接下来就是想办法把自己伪装成一个正常的用户。

1. 干掉 WebDriver 指纹:

这是最基本的操作,也是最容易实现的。

// 注入 JS 代码,修改 navigator.webdriver 属性
async function removeWebDriverFlag(driver) {
  await driver.executeScript(`
    Object.defineProperty(navigator, 'webdriver', {
      get: () => false,
    });
  `);
}

// 使用示例 (假设你已经有了 webdriver 实例)
// const { Builder, Browser } = require('selenium-webdriver');
// const driver = await new Builder().forBrowser(Browser.CHROME).build();
// await removeWebDriverFlag(driver);

// 或者直接设置 ChromeOptions
const { Builder, Browser, Capabilities, ChromeOptions } = require('selenium-webdriver');
const chromeOptions = new ChromeOptions();
chromeOptions.excludeSwitches(['enable-automation']); // 禁用 'Chrome is being controlled by automated test software' 提示
chromeOptions.addArguments(['--disable-blink-features=AutomationControlled']); // 禁用 AutomationControlled 特性

const capabilities = Capabilities.chrome().set(ChromeOptions.capabilityKey, chromeOptions);
const driver = await new Builder().withCapabilities(capabilities).forBrowser(Browser.CHROME).build();

await driver.executeScript(`
  Object.defineProperty(navigator, 'webdriver', {
    get: () => false,
  });
`);

解释一下:

  • Object.defineProperty 是 JavaScript 中一个强大的方法,可以用来修改对象的属性。
  • 这里我们把 navigator.webdriver 属性的 get 方法重写了,让它始终返回 false

2. 完善请求头:

用真实的 User-Agent 和其他请求头信息。

const { Builder, Browser, Capabilities } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

// 随机 User-Agent (你可以维护一个 User-Agent 列表)
const userAgents = [
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15',
  // 更多 User-Agent...
];

const randomUserAgent = userAgents[Math.floor(Math.random() * userAgents.length)];

const chromeOptions = new chrome.Options();
chromeOptions.addArguments(`--user-agent=${randomUserAgent}`);

const capabilities = Capabilities.chrome().set(chrome.Options.capabilityKey, chromeOptions);
const driver = await new Builder().withCapabilities(capabilities).forBrowser(Browser.CHROME).build();

3. 模拟人类行为:

这是个技术活,需要你动脑筋,根据网站的特点来设计。

  • 随机延迟: 在操作之间添加随机的延迟,模拟人类思考的时间。
async function randomDelay(min, max) {
  const delay = Math.floor(Math.random() * (max - min + 1)) + min;
  await new Promise(resolve => setTimeout(resolve, delay));
}

// 使用示例
// await driver.findElement(By.id('username')).sendKeys('your_username');
// await randomDelay(500, 1500); // 延迟 500-1500 毫秒
// await driver.findElement(By.id('password')).sendKeys('your_password');
// await randomDelay(1000, 2000);
// await driver.findElement(By.id('login')).click();
  • 鼠标移动: 模拟鼠标移动轨迹,不要直接“瞬移”。这需要用到一些高级的技巧,比如贝塞尔曲线。
  • 滚动页面: 模拟人类浏览网页时会滚动页面的行为。
  • 随机点击: 不要总是点击固定的元素,可以随机点击页面上的链接或者按钮。
  • 输入速度: 模拟人类输入的速度,不要一下子把所有内容都输入进去。

4. 解决 JS 环境问题:

有些网站会检测你的浏览器是否缺少某些 JS API 或者变量。可以通过注入 JS 代码来模拟这些 API。

// 注入 JS 代码,模拟 missingMethod 方法
async function injectMissingMethod(driver) {
  await driver.executeScript(`
    if (typeof window.missingMethod === 'undefined') {
      window.missingMethod = function() {
        // 模拟 missingMethod 的行为
        console.log('missingMethod called');
        return 'fake_result';
      };
    }
  `);
}

// 使用示例
// await injectMissingMethod(driver);

5. 更换 IP 地址:

如果你的 IP 地址被封了,那就只能换一个了。

  • 代理 IP: 使用代理 IP 是最常见的方法。你可以购买代理 IP,或者自己搭建代理服务器。
  • Tor 浏览器: Tor 浏览器可以隐藏你的真实 IP 地址,但是速度比较慢。

6. Cookie 管理:

  • 保存 Cookie: 模拟用户登录状态,避免频繁登录。
  • 清理 Cookie: 定期清理 Cookie,避免被网站追踪。

7. Headless 模式的优化:

如果你使用的是 Headless 模式,需要注意以下几点:

  • 设置 Viewport: 设置合适的 Viewport 大小,模拟真实用户的屏幕分辨率。
await driver.manage().window().setRect({ width: 1920, height: 1080 });
  • 禁用 Headless 检测: 有些网站会检测你是否使用了 Headless 模式,可以通过一些技巧来禁用这种检测。

第三部分:实战演练(代码示例)

下面我们来一个简单的示例,演示如何使用 Selenium WebDriver 伪装成人类。

const { Builder, Browser, By, Key, until, Capabilities, ChromeOptions } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

async function runBot() {
  // 1. 设置 ChromeOptions
  const chromeOptions = new ChromeOptions();
  chromeOptions.addArguments(['--disable-blink-features=AutomationControlled']); // 禁用 AutomationControlled 特性
  chromeOptions.addArguments(['--lang=zh-CN,zh,en']); // 设置语言
  chromeOptions.excludeSwitches(['enable-automation']); // 禁用 'Chrome is being controlled by automated test software' 提示

  // 2. 随机 User-Agent
  const userAgents = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
  ];
  const randomUserAgent = userAgents[Math.floor(Math.random() * userAgents.length)];
  chromeOptions.addArguments(`--user-agent=${randomUserAgent}`);

  // 3. 设置 Capabilities
  const capabilities = Capabilities.chrome().set(chrome.Options.capabilityKey, chromeOptions);

  // 4. 创建 WebDriver 实例
  const driver = await new Builder().withCapabilities(capabilities).forBrowser(Browser.CHROME).build();

  try {
    // 5. 设置 Viewport
    await driver.manage().window().setRect({ width: 1920, height: 1080 });

    // 6. 注入 JS 代码,干掉 WebDriver 指纹
    await driver.executeScript(`
      Object.defineProperty(navigator, 'webdriver', {
        get: () => false,
      });
    `);

    // 7. 访问目标网站
    await driver.get('https://www.example.com');

    // 8. 模拟人类行为 (随机延迟)
    async function randomDelay(min, max) {
      const delay = Math.floor(Math.random() * (max - min + 1)) + min;
      await new Promise(resolve => setTimeout(resolve, delay));
    }

    // 示例:点击页面上的一个链接
    const linkElement = await driver.findElement(By.css('a')); // 假设页面上有一个 <a> 标签
    await randomDelay(500, 1500);
    await linkElement.click();

    // 等待页面加载
    await driver.wait(until.titleContains('Example'), 10000);

    // 输出当前页面的标题
    console.log('Page title:', await driver.getTitle());

  } finally {
    // 9. 关闭浏览器
    await driver.quit();
  }
}

runBot();

第四部分:高级技巧(进阶之路)

  • 机器学习: 使用机器学习算法来分析用户行为,生成更真实的模拟数据。
  • 浏览器扩展: 开发浏览器扩展,拦截和修改 WebDriver 的行为。
  • 分布式爬虫: 使用分布式爬虫,分散请求,降低被封 IP 的风险。
  • 验证码识别: 使用图像识别技术来自动识别验证码。

第五部分:总结与注意事项

反爬虫和反反爬虫是一个永无止境的猫鼠游戏。网站的反爬虫技术会不断升级,你也需要不断学习和改进你的反检测策略。

  • 合法合规: 务必遵守网站的 robots.txt 协议和相关法律法规。
  • 控制频率: 不要过于频繁地请求网站,以免给网站造成压力。
  • 持续学习: 关注最新的反爬虫技术,不断学习和改进你的策略。
  • 灵活应对: 根据网站的特点,灵活调整你的反检测策略。
  • 道德底线: 不要利用爬虫技术进行非法活动。

希望今天的讲座对大家有所帮助!记住,技术是把双刃剑,要用好它,造福社会,而不是危害他人。 咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注