在html中将puppeteerjson写入htmltable中,不用jQuery保存
Write puppeteer json into html table in html and save it without jQuery
我正在从网站上收集标题和图像并将其转换为 human-readable 格式。
我使用 fs.writeFile
,选项是:
- 另存为html(在本地打开)或
- 通过 nodemailer 将其发送到电子邮件。
无论哪种方式,我都需要 html 中 table 格式的信息。
顶行 = 标题、价格、图像(显示,而不是 link)。
列 = 项目列表。
我添加了一部分以将 JSON 转换为 html table 但它搞砸了。现在脚本没有 运行。错误是文档未定义(在 table 格式中)。
另外,如果有任何方法可以在不维护服务器的情况下每天 auto-send 将列表发送到电子邮件,也请告诉我。
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 在 server-side 上执行 JavaScript。所以没有 DOM 个变量(如 window
或 document
)可以访问。因此,您收到错误 document is not defined
.
有关该主题的更多信息,您可能需要查看问题 "Why doesn't Node.js have a native DOM?"
Table创作
如果你想创建 HTML table 的标记,你可以使用字符串连接并简单地将 table 合并在一起,或者使用类似 jsdom 在 server-side.
上模拟 DOM
鉴于你的情况似乎很简单,我会选择第一个选项。
这里有一些相当简单的代码来为 table 创建 HTML 标记。您可以将它放入您的代码而不是您的 "create table" 代码中,它将生成一个 table,其中每个值在 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 website 以获取更多信息。
await transporter.sendMail({
/* ... */
html: 'Full HTML document.... ' + htmlTable + ' ...'
});
我正在从网站上收集标题和图像并将其转换为 human-readable 格式。
我使用 fs.writeFile
,选项是:
- 另存为html(在本地打开)或
- 通过 nodemailer 将其发送到电子邮件。
无论哪种方式,我都需要 html 中 table 格式的信息。 顶行 = 标题、价格、图像(显示,而不是 link)。 列 = 项目列表。
我添加了一部分以将 JSON 转换为 html table 但它搞砸了。现在脚本没有 运行。错误是文档未定义(在 table 格式中)。
另外,如果有任何方法可以在不维护服务器的情况下每天 auto-send 将列表发送到电子邮件,也请告诉我。
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 在 server-side 上执行 JavaScript。所以没有 DOM 个变量(如 window
或 document
)可以访问。因此,您收到错误 document is not defined
.
有关该主题的更多信息,您可能需要查看问题 "Why doesn't Node.js have a native DOM?"
Table创作
如果你想创建 HTML table 的标记,你可以使用字符串连接并简单地将 table 合并在一起,或者使用类似 jsdom 在 server-side.
上模拟 DOM鉴于你的情况似乎很简单,我会选择第一个选项。
这里有一些相当简单的代码来为 table 创建 HTML 标记。您可以将它放入您的代码而不是您的 "create table" 代码中,它将生成一个 table,其中每个值在 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 website 以获取更多信息。
await transporter.sendMail({
/* ... */
html: 'Full HTML document.... ' + htmlTable + ' ...'
});