【问题标题】:Extracting table value from an URL with Node JS使用 Node JS 从 URL 中提取表值
【发布时间】:2019-11-11 11:40:50
【问题描述】:

我对 Node JS 和 express 还很陌生,但我正在尝试构建一个提供静态文件的网站。经过一些研究,我发现带有 Express 的 NodeJS 对此非常有用。 到目前为止,我设法提供了一些位于我的服务器上的静态 html 文件,但现在我想做其他事情: 我有一个 html 页面的 URL,在那个 html 页面中,有一个包含一些信息的表格。

我想从中提取特定的几个值,并且 1) 将其作为 JSON 保存在文件中,2) 将这些值写入 html 页面。我尝试过使用 jQuery,但到目前为止我一直没有成功。

这是我目前所拥有的:

1.node 应用程序在端口 8081 上运行,我将使用 NGINX 反向代理从任何地方进一步访问它(我已经安装了 nginx 并且它可以工作)

2.当我使用正确的 URI 时,我可以获取 URL 并将其作为 HTML 提供。

3.我看到该表没有 ID,只有与之关联的“详细信息”类。另外,我只对获取这些行感兴趣:

<div class='group'>
<table class='details'>
<tr>
<th>Status:</th>
<td>
With editors
</td>
</tr>

据我目前所见,如果表有 ID,jQuery 可以正常工作。

这是我在app.js中的代码


var express = require('express');
var app = express();
var request = require('request');
const path = require('path');

var content;

app.use('/', function(req, res, next) {
  var status = 'It works';
  console.log('This is very %s', status);
  //console.log(content);
  next();
});

request(
  {
    uri:
      'https://authors.aps.org/Submissions/status?utf8=%E2%9C%93&accode=CH10674&author=Poenaru&commit=Submit'
  },
  function(error, response, body) {
    content = body;
  }
);

app.get('/', function(req, res) {
  console.log('Got a GET request for the homepage');
  res.sendFile(path.join(__dirname, '/', 'index.html'));
});

app.get('/url', function(req, res) {
  console.log('You requested table data!!!');

TO DO:   SHOW ONLY THE THE VALUES OF THAT TABLE INSTEAD OF THE WHOLE HTML PAGE

  res.send(content);
});

var server = app.listen(8081, function() {
  var host = server.address().address;
  var port = server.address().port;
  console.log('Node-App listening at http://%s:%s', host, port);
});

基本上,该 URL 的 HTML 内容保存到 content 变量中,现在我想只保存其中的表格,并且只将保存的部分输出到新的 html 页面。

有什么想法吗? 提前谢谢你:)

【问题讨论】:

  • 您可以使用 jsdom npm 库从服务器端的 html 中提取内容,或者如果您确信内容中的 html 格式不会发生太大变化,您可以使用字符串操作来获取您想要的 jsdom 内容很重

标签: javascript html node.js express web-scraping


【解决方案1】:

好的,所以我遇到了这个名为 cheerio 的包,它基本上允许人们在服务器上使用 jQuery。有了来自该特定 URL 的 html 代码,我可以在该表中搜索我需要的元素。 Cheerio 非常简单,通过这段代码我得到了我需要的结果:

var cheerio = require('cheerio');
request(
  'https://authors.aps.org/Submissions/status?utf8=%E2%9C%93&accode=CH10674&author=Poenaru&commit=Submit',
  (error, res, html) => {
    if (!error && res.statusCode === 200) {
      const $ = cheerio.load(html);
      const details = $('.details');
      const articleInfo = details.find('th').eq(0);
      const articleStatus = details
        .find('th')
        .next()
        .eq(0);
      //console.log(details.html());
      console.log(articleInfo.html());
      console.log(articleStatus.html());
    }
  }
);

感谢@O.Jones 和@avcS 引导我访问jsdonhtml-node-parser。在不久的将来我一定会和他们一起玩:)

干杯!

【讨论】:

    【解决方案2】:

    您的任务称为“抓取”。您想从某个不是您创建的网页中抓取特定数据块,然后将其作为您自己网页的一部分返回。

    您已经注意到抓取的问题:您抓取的页面通常无法通过独特的id 清晰地识别您想要的数据。所以你必须使用一些猜测来找到它。 @AvcS 指出了一个名为 jsdom 的服务器端 npm 库,您可以将其用于此目的。

    请注意:尽管浏览器和 nodejs 都使用 Javascript,但它们仍然是非常不同的环境。浏览器 Javascript 有很多内置的 API 来访问网页的文档对象模型 (DOM)。但是 nodejs 没有这些 API。如果您尝试将 jQuery 加载到 node.js 中,它将无法正常工作,因为它依赖于浏览器 DOM API。 jsdom 包为您提供了其中的一些 DOM API。

    一旦您抓取了要抓取的网页,这样的代码可能会帮助您获得所需的内容。

    const jsdom = require("jsdom");
    const { JSDOM } = jsdom;
    ...
    const page = new JSDOM(page_in_text_string).window;
    

    然后您可以使用 DOM API 的子集在您的页面中找到您想要的元素。在您的示例中,您正在使用选择器 div.class table.group 查找元素。您正在寻找 div.class 元素。

    你可以做这样的事情来找到你需要的东西:

    const desiredTbl = page.document.querySelector("div.class table.group");
    const desiredDiv = desiredTbl ? desiredTbl.parentNode : null;
    const result = desiredDiv ? desiredDiv.textContent : null;
    

    最后这样做:

    page.close();
    

    您的问题是您想要文档中的某些。 HTML 文档没有行,它们有元素。如果您只想提取部分元素(表格的一部分而不是整个内容),则需要使用一些文本字符串代码。只是说说而已

    另外,我还没有调试过这些。这是留给你的。

    有一个更小更快的库来做类似的事情,叫做node-html-parser。如果性能很重要,您可能需要那个。

    【讨论】:

      猜你喜欢
      • 2019-08-25
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2020-01-25
      • 2017-12-09
      相关资源
      最近更新 更多