javascript - 将 puppeteer json 写入 html 中的 html 表中并在没有 jQuery 的情况下保存
问题描述
我将网站上的标题和图像收集成人类可读的格式。
我使用fs.writeFile
和选项是:
- 另存为 html(在本地打开)或者,
- 让它通过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();
解决方案
为什么您的代码不起作用
您正在尝试在 Node.js 环境中使用 DOM。Node.js 在服务器端执行 JavaScript。因此没有您可以访问的 DOM 变量(如window
or document
)。因此你得到了错误document is not defined
。
有关该主题的更多信息,您可能需要查看“为什么 Node.js 没有本机 DOM?”这个问题。
表创建
如果您想创建 HTML 表格的标记,您可以使用字符串连接并将表格简单地合并在一起,或者使用jsdom 之类的东西在服务器端模拟 DOM。
由于您的情况似乎很简单,我会选择第一个选项。
这里有一些相当简单的代码来为表格创建 HTML 标记。您可以将它放入您的代码而不是“创建表”代码中,它会生成一个表,其中每个值对应一列col
。
function escapeHtml(str) { // for security reasons escape "<" (you could even improve this)
return str.replace(/</g, '<');
}
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 网站以获取更多信息。
await transporter.sendMail({
/* ... */
html: 'Full HTML document.... ' + htmlTable + ' ...'
});
推荐阅读
- javascript - 使用 OR ( | ) 时的正则表达式非捕获组
- python - 在 Dart 中,Python 的 try...catch...else 最惯用的替代方法是什么?
- php - 如何正确配置 Guzzle 以从其他服务器下载 zip 文件
- migration - 语法错误或访问冲突:1075 表定义不正确;只能有一个自动列,并且必须将其定义为键
- php - 登录用户的电子邮件确认,Behat 测试
- stream - 如何在 Rust 中将 Stream 转换为 RepeatedField?
- c - 为什么 scanf 无法正确读取输入?
- c++ - 在多个测试中创建和保持状态
- vb.net - 沃森助手和 vb.net
- php - 我的视图考勤表没有从数据库中提取表