Скребок для изображений JS

#javascript #image #web-scraping #puppeteer #href

Вопрос:

Я думал, что создание базового скребка для изображений будет забавным проектом. Приведенный ниже код работает в консоли на веб-сайте, но я не знаю, как заставить его работать с моего app.js.

 var anchors = document.getElementsByTagName('a');
var hrefs = [];
for(var i=0; i < anchors.length; i  ){ 
var src = anchors[i].href;
  if(src.endsWith(".jpeg")) {
    hrefs.push(anchors[i].href);
}} console.log(hrefs); 

Я думал, что использовать кукольника-хорошая идея, но мои знания слишком ограничены, чтобы определить, правильно это или нет. Это мой код кукловода:

 const puppeteer = require("puppeteer");

async function scrape(url) {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(url);

    var anchors = await page.evaluate(() => document.getElementsByTagName('a'));   
    
    var hrefs = [];
    for(var i=0; i < anchors.length; i  ){ var img = anchors[i].href;
      if(img.endsWith(".jpeg")) {
        hrefs.push(anchors[i].href);
    }} console.log({hrefs}, {img});
    
    browser.close();
} 

Я понимаю, что последняя часть кода неверна, но я не могу найти четкого ответа на то, что нужно написать вместо этого.

Спасибо, что уделили мне время.

Ответ №1:

page.evaluate() может передавать только сериализуемые значения (примерно те значения, которые может обрабатывать JSON). Поскольку document.getElementsByTagName() возвращает коллекцию элементов DOM, которые не являются сериализуемыми (они содержат методы и циклические ссылки), каждый элемент в коллекции заменяется пустым объектом. Вам нужно вернуть либо сериализуемое значение (например, массив текстов или href атрибутов), либо использовать что-то вроде page.$$(selector) and ElementHandle API.

Веб-API не определен вне функции .evaluate() аргумента, поэтому вам необходимо поместить всю часть веб-API в .evaluate() функцию аргумента и вернуть из нее сериализуемые данные.

 const puppeteer = require("puppeteer");

async function scrape(url) {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(url);

    const data = await page.evaluate(() => {
        const anchors = document.getElementsByTagName('a');
        const hrefs = [];
        for (let i = 0; i < anchors.length; i  ) {
            const img = anchors[i].href;
            if (img.endsWith(".jpeg")) {
                hrefs.push(img);
            }
        }
        return hrefs;
    });
    console.log(data);

    await browser.close();
}