使用网络抓取工具 JavaScript 在标签外获取价值

问题描述 投票:0回答:2

我正在尝试创建一个分为两类的刮板。一个是后端,它将从网站上删除一个值并将其返回给另一个调用类,现在将在其中打印它。我的问题是在获取标签外定义的值时遇到困难。 IE。

<div class="temp">13</div>

到目前为止,这是我的后端,如果我想添加更多在将来使用它的类,它会在 get 函数中获取一个 url

const PORT = 8000
const axios = require('axios')
const cheerio = require('cheerio')
const express = require('express')
const app = express()
const cors = require('cors')
const url = require("url");
app.use(cors())

app.get('/temp/:url1', (req, res) => {
    axios(url1)
        .then(response => {
            const html = response.data
            const $ = cheerio.load(html)
            const value = []
            
            *stuck here*
          
        }).catch(err => console.log(err))

})

app.listen(PORT, () => console.log(`server running on PORT ${PORT}`))

这是我的第一个应用程序。它只是调用 fetch 并打印值

url1 = 'https://www.walmart.com/ip/Hind-Boys-Active-Shirts-Shorts-and-Jogger-Pants-8-Piece-Outfit-Set-Sizes-4-16/952146762?athcpid=952146762&athpgid=AthenaHomepageDesktop__gm__-1.0&athcgid=null&athznid=SeasonalCampaigns_d396fb61-c3c0-46db-a4d9-aaf34191b39f_items&athieid=null&athstid=CS020&athguid=kZNrXnatcjxcgUvbKkvbwYMT4bwAapwfOaos&athancid=null&athena=true&athbdg=L1400'
//(in this instance, the value I'm attempting to get is the "Now 24.99" portion)
fetch('http://localhost:8000/temp/' + url1)
    .then(response => {return response.json()})
    .then(data => {
        console.log(data)
    })
    .catch(err => console.log(err))

为了使这里更容易是 url 中的 HTML

<span itemprop="price" aria-hidden="false">Now $24.97</span>
javascript node.js cheerio
2个回答
0
投票

我在这里看到两个选项:

  • 服务器解析页面并返回价格给客户端
  • 服务器将HTML响应传递给客户端,客户端负责解析

如果

/temp
(或
/bids
)路由应该处理任意 URL,则第二个选项更有意义。但是如果与客户的合同是它们都是同一种 URL,那么您可以(并且可能应该)在服务器上进行抓取:

const axios = require("axios");
const cheerio = require("cheerio");
const app = require("express")();

const ua =
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";

app.get("/bids", (req, res) => {
  axios
    .get(req.query.url, {headers: {"User-Agent": ua}})
    .then(({data: html}) => {
      const $ = cheerio.load(html);
      res.json({price: $("[itemprop='price']").text().trim()});
    })
    .catch(err => res.status(400).json({error: "Bad request"}));
});

app.listen(8000, () => console.log("listening on port 8000"));

注意事项:

  • 您可以使用
    req.query
    并传递像
    ?url=https://www.example.com
    这样的查询字符串。
    req.params
    似乎被
    /bids/https://www.example.com
    这样的路径搞糊涂了。这是可能的,但也许?您还可以接受带有 URL 的 POST JSON 负载。
  • 我正在使用用户代理字符串来(帮助)避免阻塞。
  • [itemprop="price"]
    是我为您的元素使用的 CSS 选择器。
  • 我在处理错误方面并没有做太多,但这很重要。

一般提示:尝试分解和最小化您的问题。获取服务器的 URL、发出请求和解析 HTML 是完全不同的步骤。如果您还没有验证您的 URL 参数是否正确通过,如果您正在为一个甚至不起作用的请求选择一个元素,您可能会感到困惑。


-1
投票

如果我理解正确的话,你想从你从抓取的网页中获取的一些 HTML 中获取特定的文本。您可以将抓取的 HTML 文本转换为 HTML 元素,然后使用

.querySelector()
查找感兴趣的元素。

这个例子从具有属性

itemprop="price"
的跨度中获取价格:

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();
  return div;
}

const html = '<body><div>Stuff</div><span itemprop="price" aria-hidden="false">Now $24.97</span></body>';
let elem = createElementFromHTML(html);
let price = elem.querySelector('span[itemprop="price"]').innerHTML;
console.log('elem:', elem.innerHTML);
console.log('price:', price);

输出:

elem: <div>Stuff</div><span itemprop="price" aria-hidden="false">Now $24.97</span>
price: Now $24.97
© www.soinside.com 2019 - 2024. All rights reserved.