By default Pyppeteer opens a new browser for every screenshot, on my setup, this increases the screenshot time by 100% compared to having the browser open.
Therefore, my question is: How would I keep Chrome/Pyppeteer browser open (globally) and just use the open browser to take screenshots instead of opening a new browser for every screenshot?
We have a Flask GET endpoint with parameters:
targetUrl
--> The page Chrome will take a screenshot from
intervalInside
--> How many screenshots to take without closing the browser
intervalOutside
--> How many screenshots to take while closing the browser for every screenshot
Here is my current code, I am not even sure if this is possible without having to use threads. Any ideas?
Example: http://127.0.0.1:5000/?targetUrl=https://google.com&intervalInside=1&intervalOutside=1
from asyncio import new_event_loop
from traceback import format_exc
from time import time
from flask import Flask
from flask import request
from pyppeteer import launch
loop = new_event_loop()
app = Flask(__name__)
# Change the chromium path to fit your needs
# If you are on a MAC you can run
# brew install chromium
# chromeiumPath = "/usr/bin/chromium-browser"
chromeiumPath = "/opt/homebrew/bin/chromium"
async def takeScreenshotPyP(targetUrl, intervalInside):
try:
print(f"Generating screenshot from targetUrl: {targetUrl}")
browser = await launch(
args=[
"--no-sandbox",
"--single-process",
"--disable-dev-shm-usage",
"--disable-gpu",
"--no-zygote",
],
userDataDir="/tmp",
autoClose=False,
headless=True,
ignoreHTTPSErrors=True,
executablePath=chromeiumPath,
logLevel="ERROR",
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False
)
for _ in range(intervalInside):
page = await browser.newPage()
await page.goto(targetUrl)
await page.screenshot({"fullPage": True, "path": f"screen_{round(time() * 1000)}.jpeg", "type": "jpeg"})
await browser.close()
except Exception:
print(f"Error taking screenshot: {format_exc()}")
@app.route("/", methods=["GET"])
def takeScreenshot():
if request.method == "GET":
requestArgs = request.args.to_dict()
targetUrl = requestArgs.get("targetUrl")
intervalInside = requestArgs.get("intervalInside")
intervalOutside = requestArgs.get("intervalOutside")
try:
intervalInside = int(intervalInside)
except Exception:
intervalInside = 1
try:
intervalOutside = int(intervalOutside)
except Exception:
intervalOutside = 1
if targetUrl:
startTime = time()
for _ in range(intervalOutside):
loop.run_until_complete(takeScreenshotPyP(targetUrl, intervalInside))
print(f"Taking the screenshot took: {time() - startTime}")
return "Screenshot taken and saved to file!"
return "Bad request", 401
if __name__ == "__main__":
app.run(debug=True)