Предварительное исследование кукловода

внешний интерфейс Chrome React.js Puppeteer

puppeteer 是一个Chrome官方出品的headless Chrome node库。它提供了一系列的API, 可以在无UI的情况下调用Chrome的功能, 适用于爬虫、自动化处理等各种场景

Согласно описанию на официальном сайте, кукольник имеет следующие функции:

  • Создание скриншотов страниц и PDF-файлов
  • Автоматизируйте отправку форм, тестирование пользовательского интерфейса, ввод с клавиатуры и многое другое.
  • Создайте современную автоматизированную тестовую среду. Используя новейшие функции JavaScript и браузера, тесты можно запускать непосредственно в последней версии Chrome.
  • Захватите временную шкалу вашего сайта, чтобы помочь диагностировать проблемы с производительностью.
  • Сканирование страниц SPA и предварительный рендеринг (например, «SSR»)

Ниже будут объяснены функции кукловода.

1. Инициализировать проект

Примечание. Здесь мы будем использовать новые возможности es6/7, поэтому используйте typescript для компиляции кода.

npm install puppeteer typescript @types/puppeteer

tsconfig.json настроен следующим образом:

{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "es6", "dom"
    ],
    "types": [
      "node"
    ],
    "outDir": "./dist/",
    "sourceMap": true,
    "module": "commonjs",
    "watch": true,
    "moduleResolution": "node",
    "isolatedModules": false,
    "experimentalDecorators": true,
    "declaration": true,
    "suppressImplicitAnyIndexErrors": true
  },
  "include": [
    "./examples/**/*",
  ]
}

Модуль puppeteer предоставляет метод для запуска экземпляра Chromium.

import * as puppeteer from 'puppeteer'

(async () => {
  await puppeteer.launch()
})()

Приведенный выше код создает экземпляр браузера с помощью метода запуска puppeteer, который может получать некоторые элементы конфигурации. Наиболее часто используются:

  • headless [boolean]: запускать ли браузер в безголовом режиме
  • slowMo [число]: замедлить работу кукловода. Это позволяет легко увидеть, что происходит
  • args[Array[string]]: дополнительные аргументы для передачи экземпляру браузера.

2. Создайте скриншот страницы

Здесь мы беремexample.com/Например

(async () => {
  const browser = await puppeteer.launch(); //生成browser实例
  const page = await browser.newPage();     //解析一个新的页面。页面是在默认浏览器上下文创建的
  await page.goto("https://example.com/");  //跳转到 https://example.com/
  await page.screenshot({                   //生成图片
    path: 'example.png'
  })
})()

Здесь следует отметить, что по умолчанию скриншот скриншота для открытия содержимого видимой области веб-страницы.Если вы хотите получить полный скриншот прокручиваемой страницы, вам необходимо добавитьfullPage: true

воплощать в жизньnode dist/screenshot.js, вы можете сгенерировать example.png в корневом каталоге

puppeteer по умолчанию устанавливает размер страницы 800 * 600, который можно установить с помощьюpage.setViewport()изменить размер страницы.

Мало того, кукольник может имитировать мобильный телефон.

import * as puppeteer from "puppeteer";
import * as devices from "puppeteer/DeviceDescriptors";
const iPhone = devices["iPhone 6"];

(async () => {
  const browser = await puppeteer.launch({
    headless: false
  });
  const page = await browser.newPage();
  await page.emulate(iPhone);
  await page.goto("https://baidu.com/");
  await browser.close();
})();

3. Создать PDF-файл

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("https://example.com/");
  await page.pdf({
    displayHeaderFooter: true,
    path: 'example.pdf',
    format: 'A4',
    headerTemplate: '<b style="font-size: 30px">Hello world<b/>',
    footerTemplate: '<b style="font-size: 30px">Some text</b>',
    margin: {
      top: "100px",
      bottom: "200px",
      right: "30px",
      left: "30px",
    }
  });
  await browser.close();
})()

воплощать в жизньnode dist/pdf.jsВот и все.

4. Автоматизируйте отправку форм, ввод

Здесь мы имитируем вход в гитхаб, чтобы лучше видеть весь процесс, мы используемheadless: falseЧтобы отключить безголовый режим, взгляните на весь процесс входа в систему.

(async () => {
  const browser = await puppeteer.launch({
    headless: false
  });
  const page = await browser.newPage();
  await page.goto("https://github.com/login");
  await page.waitFor(1000)   //延迟1秒输入
  await page.type("#login_field", "账号"); //立即输入
  await page.type("#password", "密码", {
    delay: 100
  }) //模拟用户输入
  await page.click("input[type=submit]"); //点击登录按钮
})()

воплощать в жизньnode dist/login.js

gif

5. Отслеживание временной шкалы сайта

Может быть очень удобно использоватьtracking.startиtracking.stopСоздайте файл трассировки, который можно открыть в chrome devtools.

(async () => {
  const broswer = await puppeteer.launch();
  const page = await broswer.newPage();
  await page.tracing.start({
    path: "trace.json"
  });
  await page.goto("https://example.com/");
  await page.tracing.stop();
  broswer.close();
})();

воплощать в жизньnode dist/trace.jsБудет сгенерирован файл trace.json, затем мы открываем chrome devtools -> Performance и перетаскиваем файл прямо в него. Эта функция позволяет нам анализировать производительность веб-сайта, а затем оптимизировать производительность.

6. Краулер и SSR

Большинство событий теперь используют реагирование, Vue, угловые для создания сайте SPA, в SPA много преимуществ, что быстро, модульная, компонентная и производительность. Тем не менее, его недостатки все еще очень очевидны, прежде всего, первая проблема рендеринга экрана, а затем SEO, недружественные рептилии.

отpreview.pro.Anta.design/#/приборная панель…Например, мы щелкаем правой кнопкой мыши, просматриваем исходный код и обнаруживаем, что его тело содержит только<div id="root"></div>, если вы хотите поднять рейтинг продаж магазина и сохранить его в базе данных для анализа данных (как показано ниже)

В настоящее время, если мы сканируем традиционным поисковым роботом, мы не можем получить содержимое веб-страницы.

например питон

# -*- coding : UTF-8 -*-
from bs4 import BeautifulSoup
import urllib2


def spider():
    html = urllib2.urlopen('https://preview.pro.ant.design/#')
    html = html.read()
    soup = BeautifulSoup(html, 'lxml')
    print(soup.prettify())


if __name__ == '__main__':
    spider()

воплощать в жизньpython py/index.py, результат следующий:

python spider
В теле нет DOM, связанного со страницей, поэтому мы не можем сканировать содержимое страницы SPA через python.

nodejs

import axios from "axios";

(async () => {
  const res = await axios.get("https://preview.pro.ant.design/#");
  console.log(res.data);
})();

воплощать в жизньnode dist/node-spider.js, чтобы получить тот же результат, что и в приведенном выше примере.

node spider

puppeteer

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("https://preview.pro.ant.design/#");
  console.log(await page.content());
})();

воплощать в жизньnode dist/spider.js, получите следующее:

puppeteer spider
На этом этапе мы можем быть удивлены, обнаружив, что можем захватить все узлы dom страницы. На этом этапе мы можем сохранить его для SSR или просканировать нужный контент.

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("https://preview.pro.ant.design/#");
  const RANK = ".rankingList___11Ilg li";
  await page.waitForSelector(RANK);
  const res = await page.evaluate(() => {
    const getText = (v, selector) => {
      return v.querySelector(selector) && v.querySelector(selector).innerText;
    };
    const salesRank = Array.from(
      document.querySelectorAll(".rankingList___11Ilg li")
    );
    const data = [];
    salesRank.map(v => {
      const obj = {
        rank: getText(v, "span:nth-child(1)"),
        address: getText(v, "span:nth-child(2)"),
        sales: getText(v, "span:nth-child(3)")
      };
      data.push(obj);
    });
    return {
      data
    };
  });
  console.log(res);
  await browser.close();
})();

воплощать в жизньnode dist/spider.js, получите следующее:

puppeteer spider

На данный момент мы использовали puppeteer, чтобы получить нужные нам данные.

На данный момент мы реализовали основные функции puppeteer.Пример кода этой статьи можно найти вgithubполучено на.

Ссылаться на