使用Node.js来运行Selenium驱动Chrome浏览器

首先

Selenium是一个用于Web应用程序的UI测试工具,也可以用作动态网站的爬虫工具。本文将介绍如何在Node.js中运行Selenium。

文件(英文版)

运用方式

Windows系统的预先准备工作

安装

npm i selenium-webdriver

谷歌浏览器驱动程序的下载

ChromeDriver是Chrome浏览器的WebDriver。
https://sites.google.com/a/chromium.org/chromedriver/downloads
将ChromeDriver放置在与执行文件相同的路径下。

基本操作 – Basic operations
基础操作 – Fundamental operations
基本操控 – Basic manipulation
基础手法 – Fundamental techniques
基本运作 – Basic functioning

导入库

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

在这里定义经常使用的Builder、By和until。

设定(适用于Chrome)

const capabilities = webdriver.Capabilities.chrome();
capabilities.set('chromeOptions', {
    args: [
        '--headless',
        '--no-sandbox',
        '--disable-gpu',
        `--window-size=1980,1200`
        // other chrome options
    ]
});

谷歌浏览器选项

打开浏览器

const driver = await new Builder().withCapabilities(capabilities).build();
// ブラウザを終了する
driver.quit();

由于返回值基本上是Promise,因此可以使用async/await。

页面转移

await driver.get('https://www.youtube.com/');

特定要素


// タグ名で特定
let el1 = await driver.findElement(By.tagName('hoge'));
let el2 = await driver.findElement({ tagName: 'hoge' });

// idで特定
let el1 = await driver.findElement(By.id('foo'));
let el2 = await driver.findElement({ id: 'foo' });

// classで特定
let el1 = await driver.findElement(By.className('bar'));
let el2 = await driver.findElement({ className: 'bar' });

// cssセレクタで特定
let el1 = await driver.findElement(By.css('#foo'));
let el2 = await driver.findElement({ css: '#foo' });

// 複数要素の特定
let els1 = await driver.findElements(By.css('.bar'));
let els2 = await driver.findElements({ css: '.bar' });

获取属性的要素


let el = await driver.findElement(By.css('#foo'));

// テキストを取得
let text = await el.getText();
// ↑だとなぜか動かない場合はこちら
let innerHTML = await el.getAttribute('innerHTML');

// その他属性の取得
let href = await el.getAttribute('href');

应用编程

等待处理

/**
 * xxx:関数名
 * timeout:タイムアウト時間(ミリ秒)
 */
await driver.wait(until.xxx(), timeout);

要素的出现

// 要素の出現を待つ
await driver.wait(until.elementLocated(By.id('foo')), 10000);
await driver.wait(until.elementsLocated(By.className('bar')), 10000);

网址条件

// 完全一致
await driver.wait(until.urlIs('xxx'), 10000);

// 部分一致
await driver.wait(until.urlContains('xxx'), 10000);

// 正規表現
await driver.wait(until.urlMatches(/xxx/), 10000);

标题要求 (Chinese translation)

// 完全一致
await driver.wait(until.titleIs('xxx'), 10000);

// 部分一致
await driver.wait(until.titleContains('xxx'), 10000);

// 正規表現
await driver.wait(until.titleMatches(/xxx/), 10000);

特定的文本条件

let el = await driver.findElement(By.css('#foo'));

// 完全一致
await driver.wait(until.elementTextIs(el, 'xxx'), 10000);

// 部分一致
await driver.wait(until.elementTextContains(el, 'xxx'), 10000);

// 正規表現
await driver.wait(until.elementTextMatches(el, /xxx/), 10000);

要素的状态 de

let el = await driver.findElement(By.css('#foo'));

// enabled
await driver.wait(until.elementIsEnabled(el), 10000);

// disabled
await driver.wait(until.elementIsDisabled(el), 10000);

// selected
await driver.wait(until.elementIsSelected(el), 10000);

// not selected
await driver.wait(until.elementIsNotSelected(el), 10000);

// visible
await driver.wait(until.elementIsVisible(el), 10000);

// not visible
await driver.wait(until.elementIsNotVisible(el), 10000);

截取屏幕截图

// スクリーンショット画像をbase64でエンコードしたもの
let base64 = await driver.takeScreenshot();

// bufferに変換
let buffer = Buffer.from(base64, 'base64');

样本

拍摄Youtube截图的示例

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

const capabilities = webdriver.Capabilities.chrome();
capabilities.set('chromeOptions', {
    args: [
        '--headless',
        '--no-sandbox',
        '--disable-gpu',
        `--window-size=1980,1200`
    ]
});

// awaitを使うので、asyncで囲む
(async () => {

    // ブラウザ立ち上げ
    const driver = await new Builder().withCapabilities(capabilities).build();

    // Youtubeへ移動
    await driver.get('https://www.youtube.com/');

    // 検索ボックスが表示されるまで待つ
    await driver.wait(until.elementLocated(By.id('search')), 10000);

    let base64 = await driver.takeScreenshot();
    let buffer = Buffer.from(base64, 'base64');

    // bufferを保存
    await promisify(fs.writeFile)('screenshot.jpg', buffer);

    // ブラウザ終了
    driver.quit();

})();
广告
将在 10 秒后关闭
bannerAds