Запуск цикла в экземпляре Puppeteer

Только приступив к работе с Puppeteer, я могу запустить браузер, перейти по URL-адресу, выполнить несколько действий, а затем закрыть браузер. Однако я хочу проверить, смогу ли я сделать это, - это открыть браузер и выполнить цикл действий в одном сеансе.

У меня есть объект JSON с URL-адресами, которые я хочу посетить, поэтому хочу перебрать его

// teams.js
module.exports = {
  premier_league: [
    { team_name: "Team 1", url: "https://url-of-site/team_1"},
    { team_name: "Team 2", url: "https://url-of-site/team_2"}
  ]
}

Мой сценарий запуска кукловода выглядит следующим образом

// index.js
const TEAM = require('./teams');
const puppeteer = require('puppeteer');

(async () => {
  // Initialise Browser
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.setViewport({
    width: 1280,
    height: 800
  });
  await page.goto('login page');

  await page.click('login_box');
  await page.keyboard.type('username');

  await page.click('login_password');
  await page.keyboard.type('password');

  await page.click('login_button');
  await page.waitForNavigation();

  // Go To Team URL
  await page.goto('Team URL')

  await browser.close();
})();

Итак, чтобы перебрать мой объект JSON, я могу использовать

Object.keys(TEAM['premier_league']).forEach(function(key) {

  // Output url of each team
  console.log(TEAM['premier_league'][key]['url'])

});

Если я завершу свой переход по URL-адресу своим циклом, page больше не будет доступен

// index.js
const TEAM = require('./teams');
const puppeteer = require('puppeteer');

(async () => {
  // Initialise Browser
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.setViewport({
    width: 1280,
    height: 800
  });
  await page.goto('login page');

  await page.click('login_box');
  await page.keyboard.type('username');

  await page.click('login_password');
  await page.keyboard.type('password');

  await page.click('login_button');
  await page.waitForNavigation();

  Object.keys(TEAM['premier_league']).forEach(function(key) {

    // Go To Team URL
    await page.goto(TEAM['premier_league'][key]['url'])

  });

  await browser.close();
})();

Фактическая ошибка

await page.goto(TEAM[args][key]['url'])
    ^^^^

SyntaxError: Unexpected identifier

person Richlewis    schedule 06.02.2018    source источник


Ответы (1)


Ваша Object.keys функция обратного вызова также должна использовать async, чтобы использовать ожидание внутри. Попробуйте изменить, как показано ниже

Object.keys(TEAM['premier_league']).forEach( async function(key) {

    // Go To Team URL
    await page.goto(TEAM['premier_league'][key]['url'])

});

Надеюсь, это поможет

person yue you    schedule 06.02.2018
comment
ах, хорошо, большое спасибо, хорошие новости заключаются в том, что я могу выйти из urls, но что касается посещения фактического URL, я получаю Unhandled promise rejection (rejection id: 1): Error: Protocol error (Page.navigate): Target closed. - person Richlewis; 07.02.2018
comment
Поместите вашу асинхронную функцию в закрытие try catch и проверьте ошибку. Кажется, ваша page.goto () по какой-то причине не работает - person yue you; 07.02.2018
comment
Я бы не стал использовать .forEach с async, он не будет ожидать полного цикла Object.keys, поэтому выполнение кода будет продолжено. Для последовательного async / await проще использовать for (const ... of ...) {// await stuff} - person Lukáš Křivka; 31.12.2019