提问人:A. L 提问时间:10/27/2017 最后编辑:A. L 更新时间:2/16/2023 访问量:27219
Puppeteer - 如何设置下载位置
puppeteer - how to set download location
问:
我能够使用 puppeteer 成功下载文件,但它只是将其保存到我的 /Downloads 文件夹中。我一直在四处寻找,在 api 或论坛中找不到任何可以设置此位置的内容。
我的下载基本上只是去链接:
await page.goto(url);
答:
更新的 Puppeteer 版本(~2022 年 6 月):
正如@Daniel在这里提到的,您必须自己创建 CDP 会话:
const client = await page.target().createCDPSession()
await client.send('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath: './myAwesomeDownloadFolder',
})
原始答案
这是在最新的 Puppeteer v0.13 中设置下载路径的方法。
await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: './myAwesomeDownloadFolder'});
该行为是实验性的,以后可能会被删除、修改或更改。
Pst,您可以尝试此处列出的更多技巧,风险自负:)。
评论
._client
我意识到这是一个旧线程,但是在寻找如何设置 Puppeteer 默认下载位置时,我首先弹出了这个线程。 我能够使用以下代码设置下载位置,
let customChrome = path.resolve(__dirname, './customChrome')
let prefs = fs.readFileSync(customChrome+'/Default/Preferences');
let obj = JSON.parse(prefs);
obj.savefile.default_directory = path.resolve(__dirname, './downloads');
obj.download.default_directory = path.resolve(__dirname, './downloads');
fs.writeFileSync(customChrome+'/Default/Preferences', JSON.stringify(obj));
const browser = await puppeteer.launch({
userDataDir:customChrome,
headless: false,
args:['--disable-features=site-per-process','--no-sandbox']
});
这将在进程开始之前设置文件的默认下载目录。从本质上讲,Puppeteer 每次运行时都会创建一个自定义配置文件,我们可以覆盖该配置文件并定义下载目录。
首次运行上述代码时,您必须将 fs.readFile 注释掉为 fs.writeFile,因为 UserDirDirectory 在首次启动 Chrome 时不存在。
然后,所有与配置文件相关的数据都存储在 customChrome/Default 文件夹中。如何将 userDataDir 配置文件文件夹传递给 Puppeteer
在较新版本的 Puppeteer 中(我使用的是 v14.1),接受的答案不再有效:
await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: './myAwesomeDownloadFolder'});
> TypeError: page._client.send is not a function
相反,我必须显式创建一个新的 CDPSession:
const client = await page.target().createCDPSession()
await client.send('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath: './myAwesomeDownloadFolder',
})
评论
fileChooser
headless=false
Something went wrong.
downloadPath: "F:\\download\\puppeteer"
所有给定的解决方案在较新版本的 puppeteer 中都不适合我15.5.0
与插件一起使用就成功了。puppeteer-extra
puppeteer-extra-plugin-user-preferences
// make sure puppeteer-extra & puppeteer-extra-plugin-user-preferences are installed
const UserPreferencesPlugin = require("puppeteer-extra-plugin-user-preferences");
const downloadImageDirectoryPath = process.cwd()
puppeteer.use(
UserPreferencesPlugin({
userPrefs: {
download: {
prompt_for_download: false,
open_pdf_in_system_reader: true,
default_directory: downloadImageDirectoryPath,
},
plugins: {
always_open_pdf_externally: true,
},
},
})
);
2022 年 7 月 30 日更新: 已进行更新,并且此功能也已从软件包的先前版本中删除,如果您在 2022 年 6 月 10 日之前下载了该软件包,它应该可以工作。对我来说就是这样,但令人费解的是,为什么以前的版本也被更改了......
评论
Muhammad Uzair 的回答解决了我设置 Chromium 用户首选项以强制下载 PDF 文件的类似问题,但我遇到了设置问题,因为我使用的是 Puppeteer、Jest 和 Jest-Puppeteer,其中 Jest-Puppeteer 在幕后处理初始设置。
Macil 的这篇 Github 帖子有助于如何在文件中应用 puppeteer-extra-plugin-user-preferences 插件。jest-puppeteer.config.js
例如,这是我的文件:jest-puppeteer.config.js
const puppeteer = require('puppeteer-extra');
const UserPreferencesPlugin = require('puppeteer-extra-plugin-user-preferences');
const userPreferenceOptions = {
userPrefs: {
plugins: {
always_open_pdf_externally: true,
},
download: {
open_pdf_in_system_reader: false,
prompt_for_download: false,
},
}
};
puppeteer.use(UserPreferencesPlugin(userPreferenceOptions));
require.cache[require.resolve('puppeteer')] = require.cache[require.resolve('puppeteer-extra')];
module.exports = {
launch: {
// https://github.com/puppeteer/puppeteer/blob/v13.3.2/docs/api.md#puppeteerlaunchoptions
headless: true, // opens a browser instance
slowMo: 25, // millis to slow each step
devtools: false, // auto opens the devtools in the browser
defaultViewport: {
width: 1820,
height: 980,
deviceScaleFactor: 1,
isMobile: false,
isLandscape: true,
},
product: "chrome", // can also specify firefox
browserContext: 'incognito',
args: [
// Chromium browser arguments: https://peter.sh/experiments/chromium-command-line-switches/
'--ignore-certificate-errors',
'--no-sandbox',
'--disable-setuid-sandbox',
'--window-size=1920,1080',
],
},
};
最后,我在安装了 chrome 的 docker 容器中运行该程序
FROM node:18-slim
# ------------------------------------------
# install extension
# ------------------------------------------
RUN apt-get update -y && apt-get install -y \
# chromium \
# libnss3 lsb-release xdg-utils wget \
wget gnupg \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# ------------------------------------------
# set global config
# ------------------------------------------
ENV TZ Asia/Hong_Kong
# ------------------------------------------
# change the work directory
# ------------------------------------------
COPY source /root/source
WORKDIR /root/source
# ------------------------------------------
# upgrade npm
# ------------------------------------------
RUN npm install npm -g
RUN npm upgrade
# install node packages
RUN if test -e package-lock.json ; then npm ci ; else npm i ; fi
RUN npm run build
ENTRYPOINT ["npm", "run"]
CMD ["start"]
和
用作下载文件的客户端
(
编号: https://github.com/puppeteer/puppeteer/issues/1478#issuecomment-358826932 https://pptr.dev/api/puppeteer.cdpsessionawait page.target().createCDPSession()
)
const downloadPath = `[YOU OWN DOWNLOAD PATH]`
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
executablePath: '/usr/bin/google-chrome-stable'
})
const page = await browser.newPage()
const client = await page.target().createCDPSession()
await client.send('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath
})
评论