From 9ab7ab1371f84ad3336a7d34f806fb015a890068 Mon Sep 17 00:00:00 2001 From: ngosang Date: Sat, 24 Sep 2022 16:18:36 +0200 Subject: [PATCH] Add browser headless mode for Linux --- Dockerfile | 3 +-- docker/entrypoint.sh | 6 ------ requirements.txt | 1 + src/flaresolverr.py | 1 + src/utils.py | 23 ++++++++++++++++++++--- 5 files changed, 23 insertions(+), 11 deletions(-) delete mode 100644 docker/entrypoint.sh diff --git a/Dockerfile b/Dockerfile index e84dd81..82f3639 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,12 +31,11 @@ RUN pip install -r requirements.txt \ USER flaresolverr COPY src . -COPY docker/entrypoint.sh . COPY package.json ../ EXPOSE 8191 -CMD ["/bin/sh", "/app/entrypoint.sh"] +CMD ["/usr/local/bin/python", "-u", "/app/flaresolverr.py"] # docker build -t flaresolverr:3.0.0.beta1 . # docker run -p 8191:8191 flaresolverr:3.0.0.beta1 diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh deleted file mode 100644 index 22f773f..0000000 --- a/docker/entrypoint.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - - -export DISPLAY=99 -#echo "Listening on :$DISPLAY" - -xvfb-run -s "-screen 0 1920x1080x24" python -u /app/flaresolverr.py diff --git a/requirements.txt b/requirements.txt index 03e048c..bb15839 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ waitress==2.1.2 selenium==4.4.3 undetected-chromedriver==3.1.5.post4 func-timeout==4.3.5 +xvfbwrapper==0.2.9 diff --git a/src/flaresolverr.py b/src/flaresolverr.py index 73a0ce2..603aae1 100644 --- a/src/flaresolverr.py +++ b/src/flaresolverr.py @@ -63,6 +63,7 @@ if __name__ == "__main__": # validate configuration log_level = os.environ.get('LOG_LEVEL', 'info').upper() log_html = utils.get_config_log_html() + headless = utils.get_config_headless() server_host = os.environ.get('HOST', '0.0.0.0') server_port = int(os.environ.get('PORT', 8191)) diff --git a/src/utils.py b/src/utils.py index 9ba1f7e..e8f2c12 100644 --- a/src/utils.py +++ b/src/utils.py @@ -8,12 +8,17 @@ import undetected_chromedriver as uc FLARESOLVERR_VERSION = None CHROME_MAJOR_VERSION = None USER_AGENT = None +XVFB_DISPLAY = None def get_config_log_html() -> bool: return os.environ.get('LOG_HTML', 'false').lower() == 'true' +def get_config_headless() -> bool: + return os.environ.get('HEADLESS', 'true').lower() == 'true' + + def get_flaresolverr_version() -> str: global FLARESOLVERR_VERSION if FLARESOLVERR_VERSION is not None: @@ -32,11 +37,15 @@ def get_webdriver() -> WebDriver: options = uc.ChromeOptions() options.add_argument('--no-sandbox') options.add_argument('--window-size=1920,1080') - # todo: this param shows a warning in chrome headfull + # todo: this param shows a warning in chrome head-full options.add_argument('--disable-setuid-sandbox') options.add_argument('--disable-dev-shm-usage') - # note: headless mode is detected - # options.headless = True + + # note: headless mode is detected (options.headless = True) + # we launch the browser in head-full mode with the window hidden + if get_config_headless(): + if os.name != 'nt': # not in windows + start_xvfb_display() # if we are inside the Docker container, we avoid downloading the driver driver_exe_path = None @@ -93,6 +102,14 @@ def get_user_agent(driver=None) -> str: driver.quit() +def start_xvfb_display(): + global XVFB_DISPLAY + if XVFB_DISPLAY is None: + from xvfbwrapper import Xvfb + XVFB_DISPLAY = Xvfb() + XVFB_DISPLAY.start() + + def object_to_dict(_object): json_dict = json.loads(json.dumps(_object, default=lambda o: o.__dict__)) # remove hidden fields