【问题标题】:Write puppeteer json into html table in html and save it without jQuery将 puppeteer json 写入 html 中的 html 表中并在没有 jQuery 的情况下保存
【发布时间】:2019-10-07 01:22:42
【问题描述】:

我正在将网站上的标题和图像收集成人类可读的格式。

我使用fs.writeFile,选项是:

  1. 另存为 html(在本地打开)或者,
  2. 通过 nodemailer 将其发送到电子邮件。

无论哪种方式,我都需要 html 中表格格式的信息。 顶行 = 标题、价格、图片(显示,而非链接)。 列 = 项目列表。

我在一部分中添加了将 JSON 转换为 html 表的部分,但它搞砸了。现在脚本没有运行。错误是文档未定义(以表格形式)。

另外,如果有任何方法可以在不维护服务器的情况下每天自动将列表发送到电子邮件,也请告诉我。

const puppeteer = require('puppeteer');
const fs = require('fs');

/* this gets the json data, all working ok */
async function newCam() {
   const browser = await puppeteer.launch({ headless: false });
   let page = await browser.newPage();
   await page.goto('https://sg.carousell.com/search/products/?query=camera', { waitUntil: 'networkidle2' });
   let results = []; 
   let elements = await page.$$('div.U-U');
   for (let element of elements) {
      let listTitle  = await element.$eval('div.U-m', node => node.innerText.trim());
      let listImg    = await element.$eval('.U-p img', img => img.src);
      let listPrice  = await element.$eval('div.U-k :nth-child(1)', node => node.innerText.trim());
      results.push({ 
         'Title': listTitle,
         'Img':   listImg,
         'Px':    listPrice 
      });
   }
   await browser.close();
   return results;


   /* format json into table and feed into fs below */
      // get header keys
      var col = [];
      for (var i = 0; i < results.length; i++) {
         for (var key in results[i]) {
               if (col.indexOf(key) === -1) { col.push(key); }
         }
      }

      // create table 
      var table = document.createElement("table");
      var tr = table.insertRow(-1);                   // insert header row.
      for (var k = 0; k < col.length; k++) {
         var th = document.createElement("th");      // fill header
         th.innerHTML = col[k];
         tr.appendChild(th);
      }
      // add json data as rows
      for (var a = 0; a < results.length; a++) {
         tr = table.insertRow(-1);
         for (var f = 0; f < col.length; f++) {
               var tabCell = tr.insertCell(-1);
               tabCell.innerHTML = results[a][col[f]];
         }
      }

   /* save to html on local drive with fs */ 
   fs.writeFile('/data.html', table, (err) => {
      if (err) throw err;
   });
}
newCam();

【问题讨论】:

    标签: javascript html node.js puppeteer


    【解决方案1】:

    为什么您的代码不起作用

    您正在尝试在 Node.js 环境中使用 DOM。 Node.js 在服务器端执行 JavaScript。因此没有您可以访问的 DOM 变量(例如 windowdocument)。因此,您会收到错误 document is not defined

    有关该主题的更多信息,您可能需要查看问题"Why doesn't Node.js have a native DOM?"

    表创建

    如果您想创建 HTML 表格的标记,您可以使用字符串连接并简单地将表格合并在一起,或者使用 jsdom 之类的东西在服务器端模拟 DOM。

    由于您的情况似乎很简单,我会选择第一个选项。

    这里有一些相当简单的代码来为表格创建 HTML 标记。您可以将其放入您的代码中,而不是“创建表”代码中,它会生成一个表,其中每个值在 col 中都有一列。

    function escapeHtml(str) { // for security reasons escape "<" (you could even improve this)
        return str.replace(/</g, '&lt;');
    }
    
    const htmlTable = '<table>'
        + `\n <tr>${col.map(c => '<th>' + escapeHtml(c) + '</th>')}</tr>`
        + results // generate rows, use map function to map values to trs/tds
            .map(row => ('\n <tr>' +
                col.map(c => `\n  <td>${escapeHtml(row[c])}</td>`).join('')
            + '\n</tr>')).join('')
        + '\n</table>';
    
    fs.writeFile('/data.html', htmlTable, (err) => {
        // ...
    });
    

    当然,这段代码是一个让您入门的相当简单的示例。

    通过邮件发送文档

    除了将 HTML 保存在本地,您还可以使用 nodemailer 直接通过邮件发送它。这是一个帮助您入门的代码示例,但您可能需要查看nodemailer website 以了解更多信息。

    await transporter.sendMail({
        /* ... */
        html: 'Full HTML document.... ' + htmlTable + ' ...'
    });
    

    【讨论】:

    • 谢谢托马斯,感谢您的回答。我尝试了它并得到了这个错误。 Error: WebSocket is not open: readyState 3 (CLOSED) 后跟 (node:839) UnhandledPromiseRejectionWarning: ReferenceError: col is not defined 参考 col.map。我在 Node.js 上的非 DOM 术语上得到了你的案例。 col 应该可以工作。哦,什么是 html 表格代码的术语,我想搜索并阅读它。谢谢!
    • @Thinkerer 使用full code thrown together 创建了一个要点。 “html 表格代码的术语”是什么意思?它只是合并在一起的 HTML 代码;)
    • 感谢@Thomas 它有效。我的意思是我在哪里可以阅读更多关于自定义表格的信息?喜欢显示图像(来自 url,并允许超链接到 url),勾勒表格,加宽第二列?它与通常的 html 不同。
    • @Thinkerer 这只是普通的 HTML ;) 例如,您可以编写 &lt;table style=".."&gt; 来应用 CSS。我只是将所有 HTML 字符串连接在一起。
    猜你喜欢
    • 2011-06-20
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2022-10-07
    • 1970-01-01
    • 2013-01-06
    相关资源
    最近更新 更多