Как внедрить локальный скрипт с инструкциями require на страницу Puppeteer - PullRequest
1 голос
/ 07 мая 2019

Я использую Puppeteer для сканирования веб-страницы.Я хотел бы проанализировать URL на странице, между прочим.Я понял, что могу вывести функциональность из page.evaluate, но это не главный вопрос.Вопрос в том, как внедрить произвольный скрипт на страницу, чтобы вы могли использовать переменные / функции из скрипта в пределах page.evaluate.

В моем случае я использую lil-uri ,У меня есть в основном это:

var puppeteer = require('puppeteer')
var URL = require('lil-uri')

puppeteer.launch().then(browser => {
  browser.newPage().then(page => {
    page.goto('https://foo.com').catch(onerror).then(() => {
      page.evaluate(fetchLinks).catch(onerror)
    })
  })
  // })
})

function onerror(err) {
  console.log('ERRR', err)
}

function fetchLinks() {
  var linkEls = document.querySelectorAll('a')
  var links = []

  for (var i = 0, n = linkEls.length; i < n; i++) {
    var el = linkEls[i]

    // PARSE URL
    var url = parseUrl(el.getAttribute('href'))

    links.push(url)
  }

  return links

  function parseUrl(href) {
    // REF THE URL LIBRARY
    var url = URL(href)
    var url2 = url.path()
    var query = []
    var q = url.query()
    if (Object.keys(q).length) {
      // query.push(...)
    }
    if (query.length) {
      url2 += '?' + query.join('&')
    }
    return url2
  }
}

Это не работает, потому что require('lil-uri') находится в области действия скрипта Node.js, в то время как он действительно используется в контексте page.evaluate.

Вопрос в том, как правильно включить на странице функции parseUrl и URL, чтобы их можно было использовать в контексте page.evaluate.

Также, как вы можетевидите, я поместил функцию parseUrl в функцию fetchLinks, что не идеально, потому что я не могу повторно использовать ее между другими функциями, которые я оцениваю на странице.Я хотел бы иметь возможность сделать что-то вроде window.parseUrl = parseUrl в контексте page.evaluate, но я тоже не был уверен, как это сделать.Хотите знать, можно ли показать, как сделать эти две вещи:

  1. Как загрузить локальный внешний скрипт на страницу кукловода.
  2. Как загрузить функции в окно страницы кукловода.

1 Ответ

1 голос
/ 07 мая 2019

Вы можете использовать page.exposeFunction для предоставления функции из среды Node.js самой странице.Чтобы процитировать документы:

Метод добавляет функцию с именем name к объекту window страницы.При вызове функция выполняет puppeteerFunction в файле node.js и возвращает Обещание, которое преобразуется в возвращаемое значение puppeteerFunction.

Пример кода

Код ниже покажет вашу функцию parseUrl на странице.Затем вы можете вызвать функцию через window.parseUrl из page.evaluate.

const puppeteer = require('puppeteer');

function parseUrl(href) {
    // ...
    return '...';
}

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.exposeFunction('parseUrl', href => parseUrl(href));

    await page.evaluate(async () => {
        const url = 'http://...';
        const parsedUrl = await window.parseUrl(url);
    });
    await browser.close();
})();

Sidenote относительно разбора URL

Это не имеет прямого отношенияна ваш вопрос, но вам не обязательно нужно разбирать URL-адрес внутри среды Node.js.Для этого есть JavaScript API URL, который позволяет вам анализировать URL-адреса внутри самого браузера следующим образом:

const url = new URL('http://www.example.org/path123');
console.log(url.pathname); // will print: /path123

В зависимости от вашего варианта использования вам может даже не понадобитьсявыставить функцию, как вы можете сделать это внутри самого браузера.

...