【问题标题】:how access returned values from client side and display them如何从客户端访问返回值并显示它们
【发布时间】:2021-07-02 18:52:02
【问题描述】:

我正在尝试使用 puppeteer,我构建了一个简单的抓取工具,可以从 youtube 获取信息,它运行良好我试图添加的是在我的网页上显示带有 <p> 标签的抓取信息。有没有办法做到这一点?我被卡住的地方是我的nameavatarUrl 变量作为局部变量在我的抓取函数中,所以我怎样才能获取这些值并将它们插入我的<p> 标记中。对于我尝试过的粗略草图,我做了: document.getElementById('nameId')=name; 在导入我的 js 脚本(在 HTML 端)之后,但这不起作用,因为name 是一个局部变量,它不能在范围之外访问。任何帮助表示赞赏。提前致谢

const puppeteer = require('puppeteer');

async function scrapeChannel(url) {

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(url);

  const [el] = await page.$x('/html/body/ytd-app/div/ytd-page-manager/ytd-browse/div[3]/ytd-c4-tabbed-header-renderer/tp-yt-app-header-layout/div/tp-yt-app-header/div[2]/div[2]/div/div[1]/div/div[1]/ytd-channel-name/div/div/yt-formatted-string');
  const text = await el.getProperty('textContent');
  const name = await text.jsonValue();

  const [el2] = await page.$x('//*[@id="img"]');
  const src = await el2.getProperty('src');
  const avatarURL = await src.jsonValue();

  browser.close();
  console.log({
    name,
    avatarlURL
  })
  return {
    name,
    avatarURL
  }
}


scrapeChannel('https://www.youtube.com/channel/UCQOtt1RZbIbBqXhRa9-RB5g')

module.exports = {
  scrapeChannel,
}
<body onload="scrapeChannel()">

  <p id="nameId">'put the scraped name here'</p>
  <p id="avatarUrlId">'put the scraped avatar url here'</p>
  <!--
document.getElementById('nameId')=name;
document.getElementById('avatartUrlId')=avatarURL;
-->
</body>

【问题讨论】:

  • 所以你想在你的前端显示报废的数据?如果您编写了路由器代码,请向我们展示您的路由器代码?
  • 是的名称和头像 URL @ksa
  • 你有设置路由吗?
  • 抱歉我处理不了
  • 不,我没有设置任何路线@ksa

标签: javascript html puppeteer


【解决方案1】:

我在我的一个项目中使用了cheerio,这就是我在后端和前端所做的。

Node & Express JS 后端

为了从前端访问您的后端,您需要在后端设置路由。您的所有前端请求都被重定向到这些路由。欲了解更多信息,请阅读此Express Routes

例如 Route.js 代码

const router = require("express").Router();
const { callscrapeChannel } = require("../scrape-code/scrape");

router.route("/scrapedata").get(async (req, res) => {
  const Result = await callscrapeChannel();
  return res.json(Result);
});

module.exports = router;

scrapeChannel.js 文件

const puppeteer = require('puppeteer');

async function scrapeChannel(url) {

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(url);

  const [el] = await page.$x('/html/body/ytd-app/div/ytd-page-manager/ytd-browse/div[3]/ytd-c4-tabbed-header-renderer/tp-yt-app-header-layout/div/tp-yt-app-header/div[2]/div[2]/div/div[1]/div/div[1]/ytd-channel-name/div/div/yt-formatted-string');
  const text = await el.getProperty('textContent');
  const name = await text.jsonValue();

  const [el2] = await page.$x('//*[@id="img"]');
  const src = await el2.getProperty('src');
  const avatarURL = await src.jsonValue();

  browser.close();
  console.log({
    name,
    avatarURL
  })
  return {
    name,
    avatarURL
  }
}

async function callscrapeChannel() {
const data = await scrapeChannel('https://www.youtube.com/channel/UCQOtt1RZbIbBqXhRa9-RB5g')
return data
}


module.exports = {
 callscrapeChannel,
}


在您的 server.js 文件中

const express = require("express");
const cors = require("cors");
const scrapeRoute = require("./Routes/routes");
require("dotenv").config({ debug: process.env.DEBUG });
const port = process.env.PORT || 5000;
const app = express();
app.use(cors());
app.use(express.json());
app.use("/api", scrapeRoute);
app.listen(port, () => {
  console.log(`server is running on port: http://localhost:${port}`);
});

您需要的依赖项 (package.json)

"dependencies": {
    "axios": "^0.21.1",
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "cross-env": "^7.0.3",
    "dotenv": "^8.2.0",
    "esm": "^3.2.25",
    "express": "^4.17.1",
    "nodemon": "^2.0.7",
    "puppeteer": "^8.0.0"
  }

前端

在前端,我使用了fetch。您需要向后端发送获取请求。你所要做的就是



<html>
  <head>
  <script>
   async function callScrapeData(){
      await fetch(`http://localhost:5000/api/scrapedata`)
    .then((res) => { 
     return new Promise((resolve, reject) => {
       setTimeout(()=> {
        resolve(res.json())
       }, 1000)
     })
        
}).then((response) => {
  console.log(response)
document.getElementById("nameId").innerHTML = response.name
document.getElementById("avatartUrlId").innerHTML = response.avatarURL
}

)
    }

  </script>
  </head>
  <body>
    <div>
      <h1>scrape</h1>
      <p id="nameId"></p>
      <p id="avatartUrlId"></p>
      <button onclick="callScrapeData()">click</button>
    </div>
    </body>
    </html>


记住,我的后端服务器在端口 5000 上运行

输出

以上代码只是一个示例,我已对其进行了修改以适合您的问题。我希望这对你有所帮助。这很简单。如果您有任何问题,请告诉我。

注意:我假设您的后端中有一个 server.js 文件并且配置正确。

【讨论】:

  • 我收到一个错误identifier 'scrapeChannel' has already been declared@ksa
  • 后端?还是在前端?
  • 在后端@ksa
  • 我再次编辑了我的答案。不确定您是如何实现这些代码的。
  • 我基本上做了你所做的一切,除了用异步函数包装我的 await axios 并在页面加载时调用该函数,但我在 e.exports (isAxiosError.js:10) 收到错误 Uncaught (in promise) Error: Request failed with status code 404 ) 在 e.exports (isAxiosError.js:10) 在 XMLHttpRequest.l.onreadystatechange (isAxiosError.js:10) @ksa
猜你喜欢
  • 2010-11-06
  • 2015-01-31
  • 1970-01-01
  • 2021-04-22
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 2020-12-19
相关资源
最近更新 更多