首页 > 解决方案 > Puppeteer 和 express 无法使用 REST API 加载新数据

问题描述

我正在使用 puppeteer 抓取内容会定期更改的页面,并使用 express 在 rest api 中呈现数据。如果我打开 headless chrome 来查看浏览器中显示的内容,新data的就在那里,但数据没有显示在get()and中http://localhost:3005/api-weather。普通浏览器只显示原始数据。

const express = require('express');
const server = new express();
const cors = require('cors');
const morgan = require('morgan');
const puppeteer = require('puppeteer');

server.use(morgan('combined'));
server.use(
    cors({
        allowHeaders: ['sessionId', 'Content-Type'],
        exposedHeaders: ['sessionId'],
        origin: '*',
        methods: 'GET, HEAD, PUT, PATCH, POST, DELETE',
        preflightContinue: false
    })
);

const WEATHER_URL = 'https://forecast.weather.gov/MapClick.php?lat=40.793588904953985&lon=-73.95738513173298';
const hazard_url2 = `file://C:/Users/xdevtran/Documents/vshome/wc_api/weather-forecast-nohazard.html`;

(async () => {
    try {
        const browser = await puppeteer.launch({ headless: true });
        const page = await browser.newPage();

        await page.setRequestInterception(true);
        page.on("request", request => {
            console.log(request.url());
            request.continue();
        });


        await page.goto(hazard_url2, { timeout: 0, waitUntil: 'networkidle0' });
        hazard = {
            "HazardTitle": "stub",
            "Hazardhref": "stub"
        }

        let forecast = await page.evaluate(() => {

            try {
                let forecasts = document.querySelectorAll("#detailed-forecast-body.panel-body")[0].children;

                let weather = [];
                for (var i = 0, element; element = forecasts[i]; i++) {

                    period = element.querySelector("div.forecast-label").textContent;
                    forecast = element.querySelector("div.forecast-text").textContent;

                    weather.push(
                        {
                            period,
                            forecast
                        }
                    )
                }

                return weather;
            } catch (err) {
                console.log('error in evaluate: ', err);
                res.end();
            }
        }).catch(err => {
            console.log('err.message :', err.message);
        });


        weather = forecast;

        server.get('/api-weather', (req, res) => {
            try {

                res.end(JSON.stringify(weather, null, '  '));
                console.log(weather);
            } catch (err) {
                console.log('failure: ', err);
                res.sendStatus(500);
                res.end();
                return;
            }
        });
    } catch (err) {
        console.log('caught error :', err);
    }
    browser.close();
})();


server.listen(3005, () => {
    console.log('http://localhost:3005/api-weather');
});

我尝试了几种解决方案WaitUntilWaitFor.thensleep但似乎没有任何效果。

我想知道它是否与express get()有关?我使用res.end()而不是res.send()is 因为当我使用 .json 时 json 看起来更好res.end()。我真的不知道区别。

我也愿意使用这个重新加载解决方案。但我收到错误并没有使用它。我也试过waitForNavigation(),但我也不知道它是如何工作的。

也许我使用了错误的搜索词来找到解决方案。谁能指出我正确的方向?谢谢你。

标签: restexpresspuppeteer

解决方案


推荐阅读