node.js - 如何在没有 shell 访问权限的情况下安装 puppeteer 依赖项?
问题描述
我使用无头 Chrome 创建了一个网页抓取脚本。这是代码:
const puppeteer = require('puppeteer'),
PDFDocument = require('pdfkit'),
express = require('express');
app = express();
app.listen();
app.get('/', (req, res) => {
if (!req.query.url) {
res.send("URL not provided");
return;
}
work(req.query.url).then(data => {
if (data.status === 'ok') {
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename=${data.file_name}`);
data.pdf.pipe(res);
data.pdf.end();
return;
} else {
res.send(data.message);
}
});
});
async function work(url) {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
],
});
const page = await browser.newPage();
await page.setViewport({
width: 1920,
height: 1080
});
const nav = await page.goto(url);
if (nav._status === 404) return { status: 'error', message: 'Page not found' };
const total_height = await page.evaluate(() => {
element = document.querySelector('.document_scroller');
let height = element.scrollHeight;
element.scrollTop = height;
return height;
});
await page.setViewport({
width: 1920,
height: total_height
});
const num_pages = await page.evaluate(() => {
return document.querySelectorAll(".outer_page.only_ie6_border").length;
});
//Get JSON data
const json = await page.evaluate(() => {
script_tags = document.getElementsByTagName("script");
for (let script of script_tags) {
json_index = script.innerText.indexOf("new Scribd.EmbedsShow(");
if (json_index !== -1) return script.innerText.substring(json_index).match(/\{.*\}/)[0];
}
});
const data = JSON.parse(json);
const name = `${data.document.title}.pdf`;
const doc = new PDFDocument({ autoFirstPage: false });
for (let i = 1; i <= num_pages; i++) {
await page.waitForSelector(`#outer_page_${i} img`);
await page.waitForFunction(`document.querySelector("#outer_page_${i} img").hasAttribute("src")`);
await page.waitForFunction(`document.querySelector("#outer_page_${i} img").complete`);
const slide = await page.$(`#outer_page_${i}`);
const image = await slide.screenshot({ encoding: "base64" });
const dimensions = await slide.boundingBox();
doc.addPage({
size: [dimensions.width, dimensions.height],
margins: { top: 0, bottom: 0, left: 0, right: 0 }
});
doc.image("data:image/png;base64," + image);
}
await browser.close();
return { status: 'ok', pdf: doc, file_name: name };
}
它在本地运行良好。另外,我已经使用 puppeteer buildpack 在 Heroku 上对此进行了测试,它工作正常。
现在我想使用带有 CPanel 而不是 Heroku 的共享主机。我在 CPanel 中创建了一个 NodeJS 应用程序并设置了所有内容。我已经测试过该脚本可以运行。
但是,在实际测试期间它失败了,我在 CPanel 的日志中收到了这个错误消息:
App 171986 output: /home/myapp/nodevenv/node/12/lib/node_modules/puppeteer/.local-chromium/linux-901912/chrome-linux/chrome: error while loading shared libraries: libatk-bridge-2.0.so.0: cannot open shared object file: No such file or directory
很明显,缺少一些 Chrome 依赖项。我的问题是,在没有 shell 或 root 访问权限的情况下,我应该如何以及在哪里安装 CPanel 中缺少的依赖项?
解决方案
推荐阅读
- javascript - 未捕获的 TypeError:jQuery(...).popover 不是函数
- python - 显示一个 np.array 更像他们在数学中所做的那样
- flutter - 颤振getx包不起作用,显示错误
- python-3.x - 如何在 Bamboo 服务器中运行 python 脚本?
- laravel-livewire - 在自定义路径中创建组件后未找到 Livewire 组件
- svg-animate - 在 SMIL 中,为同一 GROUP 中的所有 CIRCLES 和 LINES 的 STROKE-WIDTH 设置动画
- comma - 检查oracle中不同分隔符的字符串
- python - 如何找到最受欢迎和最不受欢迎的产品?
- python - 我对 python for 循环 if 语句和多个 for 循环有疑问
- python - YouTube 没有从我的 FFmpeg 流向 RTMP 服务器接收任何数据