Основная проблема здесь в том, что вы получаете содержимое файла в виде простого текста, что было бы неплохо, если бы вы хотели простой текстовый файл, но вам нужно написать файл Excel, поэтому вам понадобится blob или arrayBuffer, оба из которых не может быть возвращено методом page.evaluate
. См. https://github.com/puppeteer/puppeteer/issues/3722
Таким образом, вам не нужно извлекать файлы Excel с помощью функции page.evaluate
от puppeteer, вы можете получить их напрямую с узла с помощью модуля https
после получения все ссылки, а затем передавать содержимое в файлы, что проще в этом случае, а также меньше кода. Вам понадобятся эти модификации
Сначала потребуется модуль https
const https = require('https');
Затем закройте кукловода после получения ссылок, поскольку он нам больше не нужен
.get();
await page.close();
await browser.close();
Вызовите функцию здесь, при циклическом пересылке по ссылкам
for (let val of listings) {
const downloadUrl = val.URL;
const Filename = val.Filename;
console.log(val);
var file = await getFile(downloadUrl, Filename);
}
Наконец, вам нужно создать функцию для чтения / записи файла вне вашего основного блока кода
function getFile(downloadUrl, Filename) {
var data = '';
var writeStream = fs.createWriteStream(Filename);
var req = https.get(downloadUrl, function(res) {
res.pipe(writeStream);
res.on('end', () => {
console.log('No more data in response.');
});
});
req.end();
}
Полный фрагмент
const puppeteer = require('puppeteer');
const cheerio = require("cheerio");
const fs = require("fs");
const https = require('https');
(async () => {
const browser = await puppeteer.launch({
args: ["--no-sandbox"],
headless: false,
slowMo: 30,
});
const page = await browser.newPage();
await page.goto(
"https://file-examples.com/index.php/sample-documents-download/sample-xls-download/"
);
const content = await page.content();
const $ = cheerio.load(content);
const listings = $("#table-files > tbody > tr:has(a)")
.map((index, element) => {
const URL = $(element).find("a").attr("href");
const Filename = $(element).find("a").attr("href").split("/").pop();
//.replace(/^.*[\\\/]/g, "");
const name = $(element)
.find("td:nth-child(1)")
.text()
.trim()
.replace("\n", "");
return {
Filename,
URL,
};
})
.get();
await page.close();
await browser.close();
for (let val of listings) {
const downloadUrl = val.URL;
const Filename = val.Filename;
console.log(val);
//call the function with each link and filename
var file = await getFile(downloadUrl, Filename);
}
})();
//send request and stream the response to a file
function getFile(downloadUrl, Filename) {
var writeStream = fs.createWriteStream(Filename);
var req = https.get(downloadUrl, function(res) {
res.pipe(writeStream);
res.on('end', () => {
console.log('No more data in response.');
});
});
req.end();
}
РЕДАКТИРОВАТЬ Увидев свой комментарий, вы можете отправлять куки, изменив запрос на получение, подобный этому, но помните о той же политике домена для куки
function getFile(downloadUrl, Filename) {
var url = new URL(downloadUrl)
var options = {
hostname: url.hostname,
path: url.pathname,
method: 'GET',
headers: {
'Cookie': 'myCookie=myvalue'
}
};
var writeStream = fs.createWriteStream(Filename);
var req = https.request(options, function(res) {
res.pipe(writeStream);
res.on('end', () => {
console.log('No more data in response.');
});
});
req.end();
}