首页 > 解决方案 > 使用 Cheerio nodeJS 进行网页抓取

问题描述

我正在尝试抓取一个网页以尝试使用Cheerio的一些技能,但我无法做到。我正在使用 axios 发出 http请求

scrape.js

const cheerio = require('cheerio');
const axios = require('axios');

async function iniciar() {
    axios.get('https://www.idealo.es/precios/4102124/the-north-face-men-s-mcmurdo-parka-tnf-black.html').then( res => {
        var price = [];
        const $ = cheerio.load(res.data);

        $('span.oopStage-variantThumbnailsFromPrice').each( (index, element) => {
            const name = $(element).first().text()
            price.push(name)
        })
        console.log(price);
    })
}

module.exports = {
    iniciar
};

main.js

const scrape = require('./assets/scrape');
scrape.iniciar()

它总是返回一个空值。

<strong>
 <span class="oopStage-variantThumbnailsFromText">desde</span>
 <span class="oopStage-variantThumbnailsFromPrice">294,99&nbsp;€&lt;/span>
</strong>

任何想法。

标签: node.jscheerio

解决方案


这对您不起作用的原因是您所需页面生成的 html 是动态的,它是由 JavaScript 代码在客户端生成的。

我们仍然可以抓取数据,但我们必须使用Puppeteer之类的东西(Zombie.js 或其他无头浏览器也可以工作。)不过,我将在此示例中使用 Puppeteer。

我们加载您希望的页面,然后以与您之前相同的方式解析 html。

我还使用用户代理生成随机用户代理以避免验证码请求。

const puppeteer = require('puppeteer');
const cheerio = require('cheerio');
const userAgent = require('user-agents');

async function getDynamicPageHtml(url) {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.setUserAgent(userAgent.toString());

        await page.goto(url, { waitUntil: 'networkidle0' });
        const html = await page.evaluate(() => document.querySelector('*').outerHTML);

        await browser.close();
        return html;
    } catch (err) {
        console.error(err);
        return null;
    }
}

async function iniciar() {
    const html = await getDynamicPageHtml('https://www.idealo.es/precios/4102124/the-north-face-men-s-mcmurdo-parka-tnf-black.html');
    const $ = cheerio.load(html);
    const price = $('span.oopStage-variantThumbnailsFromPrice').map( (index, element) => {
        return $(element).first().text().trim();
    }).toArray();
    console.log("iniciar: price:", price);
    return price;  
}

module.exports = {
    iniciar
};

当我调用 iniciar 时,我得到以下输出:

iniciar: price: [ '294,99 €' ]

推荐阅读