使用Puppeteer爬取数据可打印但无法赋值给HTML元素如何解决?
问题根因
- 第一,也是最核心的问题:Puppeteer是Node.js服务端运行的库,完全不支持在浏览器环境中直接执行。浏览器端的JavaScript没有
require模块加载能力,也没有权限启动本地浏览器进程,你直接把调用Puppeteer的JS文件引入HTML在浏览器跑,代码从const puppeteer = require('puppeteer')这一步就已经报错终止执行了,自然不会有后续赋值DOM的操作。 - 第二,你写的
sleep方法是同步阻塞实现,会卡住Node.js的事件循环,导致后续页面元素获取逻辑异常,正确的等待写法应该是await new Promise(resolve => setTimeout(resolve, 1000)),或者直接用Puppeteer自带的waitForXPath等等待方法,避免元素还没渲染就开始查找。 - 第三,就算你不用Puppeteer,直接在前端请求第三方网站接口也会被浏览器的同源策略(CORS)拦截,无法正常拿到返回数据。
正确实现方案
你需要拆分前后端逻辑:
- 服务端用Node.js运行Puppeteer的爬虫逻辑,写一个简单的HTTP接口(用Express、Koa都可以),爬虫拿到结果后通过接口返回。
- 前端页面通过
fetch或者XMLHttpRequest调用你自己写的后端接口,拿到返回结果后再赋值给对应的HTML元素。
简单示例代码
后端接口示例(Node.js)
const express = require('express') const puppeteer = require('puppeteer') const app = express() // 允许前端跨域调用,开发环境可以加,生产环境按需配置 app.use(require('cors')()) app.get('/scrape', async (req, res) => { const browser = await puppeteer.launch() const page = await browser.newPage() await page.goto('https://www.purpleair.com/sensorlist?key=HIGZAD9XGVDEMVVZ&show=37253') // 等待目标元素渲染 await page.waitForXPath('//*[@id="resultTable"]/tbody/tr[1]/td[2]/div/div[1]/font[1]') const [el] = await page.$x('//*[@id="resultTable"]/tbody/tr[1]/td[2]/div/div[1]/font[1]') const txt = await el.getProperty('innerHTML') const rawTxt = await txt.jsonValue() await browser.close() res.send(rawTxt) }) app.listen(3000, () => console.log('服务运行在 http://localhost:3000'))
前端代码修改
// purpleAir.js 里删掉所有Puppeteer相关逻辑,只保留请求逻辑 async function runScript() { const result = await fetch('http://localhost:3000/scrape').then(res => res.text()) document.getElementById("p1").innerHTML = result }
内容的提问来源于stack exchange,提问作者jasonalan
相关产品推荐
相关产品推荐

