如何上传图片缓冲区到任何网站与木偶



以下是我所知道的操作:

  • 从imgur之类的地方下载图像,将其捕获为缓冲区,保存到磁盘
  • 使用elementHandle.uploadFile(路径(将图像从磁盘写入页面

但是,此解决方案仅适用于我的本地计算机。我希望在云中运行puppeteer,这意味着我将无法访问带有文件路径的静态磁盘。因此,我想做的是省略磁盘作为中间人。一旦我把图像作为缓冲区,我就想直接把这个缓冲区上传到输入中。我认为elementHandle.uploadFile(path(的源代码将是一个很好的起点,因为我几乎只是想剥离一层抽象。然而,我在木偶师的github 中找不到它

以下是基本步骤:

  1. 使用Base64对数据进行编码
  2. page.evaluate将其传递到导线上
  3. 将其解码为Uint8Array
  4. 使用File构造函数包装数组
  5. 将文件放在DataTransfer对象中以创建FileList

文件输入

在您的情况下,需要将ElementHandle传递给有问题的input[type="file"]元素,以便设置其files属性。

await page.evaluate(
async (encodedImage: string, mimeType: string, fileInput: Element) => {
const rawImageString = atob(encodedImage)
const rawImageBytes = new Array(rawImageString.length)
for (let i = 0; i < rawImageString.length; i++) {
rawImageBytes[i] = rawImageString.charCodeAt(i)
}
const image = new File([new Uint8Array(rawImageBytes)], '', {
type: mimeType,
})
const dataTransfer = new DataTransfer()
dataTransfer.items.add(image)

fileInput.files = dataTransfer.files
fileInput.dispatchEvent(new Event('change', { bubbles: true }))
},
encodedImage,
mimeType,
fileInput
)

拖放

在我的情况下,我想模拟一个drop事件。

await page.evaluate(
async (encodedImage: string, mimeType: string, dropArea: Element) => {
const rawImageString = atob(encodedImage)
const rawImageBytes = new Array(rawImageString.length)
for (let i = 0; i < rawImageString.length; i++) {
rawImageBytes[i] = rawImageString.charCodeAt(i)
}
const image = new File([new Uint8Array(rawImageBytes)], '', {
type: mimeType,
})
const dataTransfer = new DataTransfer()
dataTransfer.items.add(image)
dropArea.dispatchEvent(new DragEvent('dragenter', { dataTransfer }))
dropArea.dispatchEvent(new DragEvent('drop', { dataTransfer }))
},
encodedImage,
mimeType,
dropArea
)
const downloadImgFromUrl = async (url, dest) => {
// Create an empty file where we can save data
const file = fs.createWriteStream(dest);
// Using Promises so that we can use the ASYNC AWAIT syntax
await new Promise((resolve, reject) => {
request({
uri: url,
gzip: true,
}).pipe(file).on('finish', async () => {
console.log(`Image downloaded from Storage`);
resolve();
}).on('error', (error) => {
reject(error);
});
}).catch((error) => {
console.log(`Image download from URL failed: ${error}`);
});
}
await page.waitForTimeout(1000)
const [filechooser] = await Promise.all([
page.waitForFileChooser(),
page.focus("#attach_file_photo"),
page.click('#attach_file_photo')
])
await downloadImgFromUrl(imgUrl, path.join(os.tmpdir(),'uploadimg.png'))
await filechooser.accept([path.join(os.tmpdir(), 'uploadimg.png')])

相关内容

最新更新