Кукловод не отображает полную диаграмму SVG - PullRequest
0 голосов
/ 07 апреля 2019

Я использую этот код в Try Puppeteer:

const browser = await puppeteer.launch();

const page = await browser.newPage();
await page.goto('https://www.barchart.com/futures/quotes/ESM19/interactive-chart/fullscreen');

const linkHandlers = await page.$x("//li[contains(text(), '1D')]");

if (linkHandlers.length > 0) {
  await linkHandlers[0].click();
} else {
  throw new Error("Link not found");
}

await page.$eval('input[name="fieldInput"]', el => el.value = '1');

console.log(await page.content())
// const text = page.evaluate(() => document.querySelector('rect'))
// text.then((r) => {console.log(r[0])})

await page.screenshot({path: 'screenshot.png'});

await browser.close();

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

Также page.content() дает HTML, который полностью отличается от того, который я вижу при проверке элемента в Chrome.

1 Ответ

2 голосов
/ 07 апреля 2019

Задача

Вы не ожидаете разрешения запроса при изменении ввода. Поскольку изменение вызовет запрос, вы должны использовать page.waitForResponse, чтобы дождаться загрузки данных.

Кроме того, это приложение Angular, которое, похоже, не понравится, если вы просто измените значение поля с помощью el.value = '1'. Вместо этого вам нужно попытаться вести себя более как человек (и нажать клавишу Backspace и ввести значение ввода).

Решение

Сначала вы получите дескриптор элемента (input[name="fieldInput") из документа. Затем вы фокусируете элемент, удаляете значение внутри, нажимая клавишу Backspace. После этого вы вводите желаемое значение ввода.

Поле ввода теперь имеет правильное значение, теперь нам нужно вызвать событие blur , вызвав blur() для элемента. Параллельно мы ожидаем завершения запроса к серверу. После завершения запроса мы должны дать странице несколько миллисекунд для визуализации данных.

Все вместе, полученный код выглядит так:

const browser = await puppeteer.launch();

const page = await browser.newPage();
await page.goto('https://www.barchart.com/futures/quotes/ESM19/interactive-chart/fullscreen');

// wait until the element appears
const linkHandler = await page.waitForXPath("//li[contains(text(), '1D')]");
await linkHandler.click();

// get the input field, focus it, remove what's inside, then type the value
const elementHandle = await page.$('input[name="fieldInput"]');
await elementHandle.focus();
await elementHandle.press('Backspace');
await elementHandle.type('1');

// trigger the blur event and wait for the response from the server
await Promise.all([
    page.waitForResponse(response => response.url().includes('https://www.barchart.com/proxies/timeseries/queryminutes.ashx')),
    page.evaluate(el => el.blur(), elementHandle)
]);

// give the page a few milliseconds to render the diagram
await page.waitFor(100);

await page.screenshot({path: 'screenshot.png'});
await browser.close();

Улучшение кода

Я также удалил функцию page.$x и заменил ее функцией page.waitForXPath. Это гарантирует, что ваши сценарии ждут, пока страница загрузится, и элемент, на который вы хотите нажать, доступен, прежде чем сценарий продолжится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...