Maksym Moros
Maksym Moros

Reputation: 529

Puppeteer: Element.hover() doesn't exist

I am using puppeteer to scrape some images off a site along with some other data. To change images I need to hover over a list item. I keep coming across documentation around .hover() but have had no success. However, .click() works perfectly for another part of my scrape.

const pptr = require('puppeteer');

async function scrapeProduct(productID) {
    const browser = await pptr.launch();
    const page = await browser.newPage();
    await page.goto(`https://someplace.com`);
    let scrapeData = await page.evaluate(async () => {
        let productMap = [];

        //scrape other data...

        const imageItems = document.querySelectorAll('ul[class="images-view-list"] > li > div');
        for (let image of imageItems) {
            await image.hover();
            productMap.push({
                'Image Src': document.querySelector('div[class="image-view-magnifier-wrap"] > img').getAttribute('src'),
            });
        }
        return productMap;
    });
    await browser.close();
    return scrapeData;
}

I've seen solutions where you evaluate a page with executing the hover prior. This is inconvenient as I collect many other data points and would like to keep my solution clean in one evaluate request. Am I understanding .hover() incorrectly?

Upvotes: 4

Views: 7595

Answers (1)

Tom
Tom

Reputation: 1507

You're mixing up Puppeteer functions with evaluated functions that execute in the DOM context. If you want to use Puppeteer hover, then you need to use image references from page.$$ query:

let productMap = [];
const page = await browser.newPage();
await page.goto(`https://someplace.com`);
//get a collection of Puppeteer element handles
const imageItems = await page.$$('ul[class="images-view-list"] > li > div');
for (let image of imageItems) {
    //hover on each element handle
    await image.hover();
    //use elementHandle getProperty method to get the current src
    productMap.push({'Image Src': await (await image.getProperty('src')).jsonValue()});
}

If you need to do it in the page.evaluate function, you will need to mimic the hover by using normal DOM mouse events.

The reason the click() method appears to work is that it is available in both contexts, as a native DOM method and a Puppeteer element handle method.

Upvotes: 6

Related Questions