Sparticuz / chromium

Chromium (x86-64) for Serverless Platforms
MIT License
846 stars 57 forks source link

[BUG] Executable path does not exist #258

Open eduardodgdebem opened 2 months ago

eduardodgdebem commented 2 months ago

Environment

I'm not sure if I'm doing something wrong but very time a try to run puppeteer with "@sparticuz/chromium" on vercel with nodejs18.x it throws "The input directory "/var/task/.next/server/app/api/trpc/bin" does not exist." but locally it throws the same error.

Steps to Reproduce

I just created a nextjs app with trpc and tried to run the following code on vercel

import puppeteer from "puppeteer-core";
import chromium from "@sparticuz/chromium";
import type { HTTPResponse, Page, Handler } from "puppeteer-core";
import { sleep } from "~/helper";

const imgExtensionRegex = /\.(png|jpeg|jpg)$/i;

const scrollToBottomSlowly = async (page: Page) => {
  const scrollHeight = await page.evaluate(() => document.body.scrollHeight);
  const viewportHeight = await page.evaluate(() => window.innerHeight);

  let currentPosition = 0;
  while (currentPosition < scrollHeight) {
    await page.evaluate(() => {
      window.scrollBy(0, window.innerHeight / 10);
    });
    currentPosition += viewportHeight / 10;
    await sleep(5);
  }
};

export const scraper = async (url: string) => {
  if (!url?.length) throw Error("No URL for the download");

  const browser = await puppeteer.launch({
    args: chromium.args,
    defaultViewport: chromium.defaultViewport,
    executablePath: await chromium.executablePath(),
    headless: chromium.headless,
  });
  const page = await browser.newPage();

  const filesMap = new Map<string, string>();

  const downloadOnResponse = (res: HTTPResponse) => {
    const url = res.url();
    if (
      res.request().resourceType() === "image" &&
      imgExtensionRegex.test(url)
    ) {
      res
        .buffer()
        .then((file) => {
          const fileName = url.split("/").pop();
          const base64 = Buffer.from(file).toString("base64");
          if (fileName) filesMap.set(fileName, base64);
        })
        .catch(console.error);
    }
  };

  page.on("response", downloadOnResponse as Handler);

  await page.goto(url);
  await page.waitForNetworkIdle();
  await scrollToBottomSlowly(page);
  await browser.close();
  const sortedFilesMap = new Map(
    [...filesMap.entries()].sort((a, b) => {
      const aNum = +a[0].split(".")[0]!;
      const bNum = +b[0].split(".")[0]!;
      if (!isNaN(aNum) && !isNaN(bNum)) {
        return aNum - bNum;
      }
      return a[0].localeCompare(b[0]);
    }),
  );
  return sortedFilesMap;
};
Sparticuz commented 2 months ago

You'll need to specify the location of the brotli files.