[Nodejs] Puppeteer\ クローラーの練習

ここに画像の説明を挿入

人形遣い

ドキュメント: puppeteer.js 中国語ドキュメント|puppeteerjs 中国語 Web サイト|puppeteer クローラー チュートリアル

Puppeteer 自体は Node 6.4 以降に依存していますが、非常に使いやすい async/await については Node 7.6 以降を使用することをお勧めします。また、ヘッドレス Chrome 自体は、サーバーが依存するライブラリのバージョンに対する要件が比較的高いです。centos サーバーの依存関係は比較的安定しており、v6 でヘッドレス Chrome を使用するのは困難です。依存バージョンをアップグレードすると、サーバーにさまざまな問題が発生する可能性があります。 (ssh を使用できないことを含みますが、これに限定されません)、上位バージョンのサーバーを使用するのが最善です。

Puppeteer は npm パッケージであるため、インストールは非常に簡単です。

pnpm i puppeteer-core

puppeteer会自动安装一个谷歌浏览器的安装包,所以选择core版,但是得指定启动路径

使用法と例

Puppeteer は他のフレームワークと似ており、Browser インスタンスを操作することでブラウザを操作し、それに応じて応答します。

const puppeteer = require('puppeteer');

(async () => {
    
    
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://rennaiqian.com');
  await page.screenshot({
    
    path: 'example.png'});
  await page.pdf({
    
    path: 'example.pdf', format: 'A4'});
  await browser.close();
})();

上記のコードは、puppeteer の起動メソッドを通じてブラウザ インスタンスを生成します。ブラウザに対応して、起動メソッドは設定項目を渡すことができます。ローカル デバッグ中に {headless: false} を渡してヘッドレス モードをオフにする方が便利です。

const browser = await puppeteer.launch({
    
    headless:false})

browser.newPageこのメソッドは、新しいタブを開いてタブのインスタンス ページを返すことができ、ページ上のさまざまなメソッドを通じてページ上で一般的な操作を実行できます。上記のコードは、スクリーンショットと PDF の印刷操作を実行します。

非常に強力な方法は、page.evaluate(pageFunction, ...args)ページに関数を挿入できるため、無限の可能性があります。

const puppeteer = require('puppeteer');

(async () => {
    
    
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://rennaiqian.com');

  // Get the "viewport" of the page, as reported by the page.
  const dimensions = await page.evaluate(() => {
    
    
    return {
    
    
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    };
  });

  console.log('Dimensions:', dimensions);
  await browser.close();
})();

外部変数はevaluateメソッド内で直接使用することはできず、パラメータとして渡す必要があり、実行結果を取得するにはreturnも必要であることに注意してください。1 か月以上前からオープンソース プロジェクトとして現在活発に活動しているため、使用する際は自分で API を見つけてパラメータや使用方法が正しいか確認することができます。

デバッグスキル

① インターフェースなしモードをオフにします。ブラウザーで表示されるコンテンツを表示すると便利な場合があります。フルブラウザは次のコマンドで起動できます。

const browser = await puppeteer.launch({
    
    headless: false})

② 速度を遅くします。slowMo オプションは、指定されたミリ秒単位で Puppeteer の動作を遅くします。何が起こっているかを確認する別の方法は次のとおりです。

const browser = await puppeteer.launch({
    
    
  headless:false,
  slowMo:250
});

③ コンソール イベントをリッスンして、コンソールの出力をキャプチャします。これは、page.evaluate でコードをデバッグするときにも便利です。

page.on('console', msg => console.log('PAGE LOG:', ...msg.args));
await page.evaluate(() => console.log(`url is ${
      
      location.href}`));

爬虫類の練習

多くの Web ページは、page.emulate(options) を通じてシミュレートできるユーザー エージェントを通じてデバイスを判断します。オプションには2つの設定項目があり、1つはuserAgent、もう1つはビューポートで、幅(width)、高さ(height)、画面のスケーリング(deviceScaleFactor)、モバイルかどうか(isMobile)、タッチイベントの有無(hasTouch)を設定できます。 )。

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];

puppeteer.launch().then(async browser => {
    
    
  const page = await browser.newPage();
  await page.emulate(iPhone);
  await page.goto('https://www.example.com');
  // other actions...
  await browser.close();
});

上記のコードは、特定の Web サイトにアクセスする iPhone6 をシミュレートします。デバイスは、puppeteer に組み込まれているいくつかの一般的なデバイスのシミュレーション パラメーターです。

多くの Web ページではログインが必要です。解決策は 2 つあります。

让puppeteer去输入账号密码 常用方法:点击可以使用page.click(selector[, options])方法,也可以选择聚焦page.focus(selector)。 输入可以使用page.type(selector, text[, options])输入指定的字符串,还可以在options中设置delay缓慢输入更像真人一些。也可以使用keyboard.down(key[, options])来一个字符一个字符的输入。 如果是通过cookie判断登录状态的可以通过page.setCookie(...cookies),想要维持cookie可以定时访问。
ヒント: 一部の Web サイトではコードをスキャンする必要がありますが、同じドメイン名の他の Web ページがログインしている場合は、ログインできる Web ページにログインを試み、Cookie を使用してアクセスしてコード スキャンをスキップできます。

簡単な例

const puppeteer = require('puppeteer');

(async () => {
    
    
  const browser = await puppeteer.launch({
    
    headless: false});
  const page = await browser.newPage();
  await page.goto('https://baidu.com');
  await page.type('#kw', 'puppeteer', {
    
    delay: 100});
  page.click('#su')
  await page.waitFor(1000);
  const targetLink = await page.evaluate(() => {
    
    
    return [...document.querySelectorAll('.result a')].filter(item => {
    
    
      return item.innerText && item.innerText.includes('Puppeteer的入门和实践')
    }).toString()
  });
  await page.goto(targetLink);
  await page.waitFor(1000);
  browser.close();
})()

ここに画像の説明を挿入

多要素処理

const puppeteer = require('puppeteer-core');

(async function () {
    
    
  //puppeteer.launch实例开启浏览器,
  //可以传入一个options对象,可以配置为无界面浏览器,也可以配置为有界面浏览器
  //无界面浏览器性能更高更快,有界面一般用于调试开式

  let options = {
    
    
    //设置视窗的宽高
    defaultViewport: {
    
    
      width: 1400,
      height: 800,
    },
    //设置为有界面,如果为true,即为无界面
    // headless: false,
    args: ['--window-size=1400,700'],
    //指定浏览器路径
    executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
  };
  let browser = await puppeteer.launch(options);
  //打开新页面
  let page = await browser.newPage();
  //访问页面
  await page.goto('https://www.jd.com/');
  //截屏
  //   await page.screenshot({ path: 'example.png', fullPage: true });
  //获取页面内容
  // page.$eval相当于querySelector,然后在对这个元素进行dom操作
  // page.$$eval相当于querySelectorAll,然后在对这个元素进行dom操作
  let input = await page.$('#key');
  await input.type('手机');
  await page.keyboard.press('Enter');
  await page.waitForSelector('.gl-warp>.gl-item:last-child');
  const lis = await page.$$eval('.gl-warp>.gl-item', els =>
    //这个el就是获取到的对象
    //这里可以使用dom操作
    // console.log(el);
    els.map(item => item.innerText)
  );
  //这个lis就是上面回调函数的返回值
  console.log(lis);

  //关闭浏览器
  await browser.close();
})();

要素をクリックしてテキストを入力します

const puppeteer = require('puppeteer-core');
(async function () {
    
    
  let options = {
    
    
    defaultViewport: {
    
    
      width: 1400,
      height: 800,
    },
    headless: false,
    args: ['--window-size=1400,700'],
    executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
  };
  let browser = await puppeteer.launch(options);
  let page = await browser.newPage();
  await page.goto('https://www.ygdy8.com/index.html');
  //获取页面内容
  //  page.$相当于querySelector
  //  page.$$相当于querySelectorAll
  //这些返回的是一个elementHandle对象
  const input = await page.$('input[name="keyword"]'); // 定位输入框
  /*  1
  input.focus()
  page.keyboard.type("电影") */
  //2
  await input.type('电影');

  /* 1  
 elementHandle.click()
  const search = await page.$('input[name="Submit"]'); // 定位搜索按钮
  await search.click();  // 点击 */
  //2
  await page.click('input[name="Submit"]');
})();

要素のテキスト値を取得する

const puppeteer = require('puppeteer-core');
(async function () {
    
    
  let options = {
    
    
    defaultViewport: {
    
    
      width: 1400,
      height: 700,
    },
    args: ['--window-size=1400,700'],
    headless: false,
    executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
  };
  let browser = await puppeteer.launch(options);
  let page = await browser.newPage();
  await page.goto('https://www.baidu.com/');
  let input = await page.waitForSelector('#kw');
  await input.type('hello world');
  let btn = await page.$('#su');
  btn.click();
  /* 等待指定的选择器匹配的元素出现在页面中,如果调用此方法时已经有匹配的元素,
  那么此方法立即返回。如果指定的选择器在超时时间后扔不出现,此方法会报错。 
  返回: <Promise<ElementHandle>>*/
  await page.waitForSelector('div#content_left > div.result-op.c-container.xpath-log');
  let text = await page.$eval(
    'div#content_left > div.result-op.c-container.xpath-log',
    el => el.innerText
  );
  console.log(text);
})();

jsメソッドを処理する

const puppeteer = require('puppeteer-core');
(async function () {
    
    
  let options = {
    
    
    defaultViewport: {
    
    
      width: 1400,
      height: 700,
    },
    args: ['--window-size=1400,700'],
    // headless: false,
    executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
  };
  let browser = await puppeteer.launch(options);
  let page = await browser.newPage();
  await page.goto('https://www.baidu.com/');
  let input = await page.waitForSelector('#kw');
  await input.type('hello world');
  let btn = await page.$('#su');
  btn.click();
  await page.waitForSelector('div#content_left > div.result-op.c-container.xpath-log');
  //里面可以直接写js代码
  let text = await page.evaluate(() => {
    
    
    let div = document.querySelector('div#content_left > div.result-op.c-container.xpath-log');
    return div.innerText;
  });
  console.log(text);
})();

おすすめ

転載: blog.csdn.net/weixin_43094619/article/details/131919923