From 05bb7d4c9d7df7e065e795c24eb93f4ac8afcb1f Mon Sep 17 00:00:00 2001 From: MCG-pok Date: Tue, 16 Jul 2024 17:04:32 +0200 Subject: [PATCH 1/5] Access iframe in closed shadow root + click on checkbox from iframe body --- src/flaresolverr_service.py | 46 +++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/flaresolverr_service.py b/src/flaresolverr_service.py index cfc2088..5ccd9ad 100644 --- a/src/flaresolverr_service.py +++ b/src/flaresolverr_service.py @@ -219,6 +219,20 @@ def _cmd_sessions_destroy(req: V1RequestBase) -> V1ResponseBase: "message": "The session has been removed." }) +def _init_driver(driver): + try: + driver.execute_cdp_cmd('Page.enable', {}) + driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', { + 'source': """ + Element.prototype._as = Element.prototype.attachShadow; + Element.prototype.attachShadow = function (params) { + return this._as({mode: "open"}) + }; + """ + }) + except Exception as e: + logging.debug("Driver init exception: %s", repr(e)) + def _resolve_challenge(req: V1RequestBase, method: str) -> ChallengeResolutionT: timeout = int(req.maxTimeout) / 1000 @@ -239,6 +253,7 @@ def _resolve_challenge(req: V1RequestBase, method: str) -> ChallengeResolutionT: else: driver = utils.get_webdriver(req.proxy) logging.debug('New instance of webdriver has been created to perform the request') + _init_driver(driver) return func_timeout(timeout, _evil_logic, (req, driver, method)) except FunctionTimedOut: raise Exception(f'Error solving the challenge. Timeout after {timeout} seconds.') @@ -252,23 +267,34 @@ def _resolve_challenge(req: V1RequestBase, method: str) -> ChallengeResolutionT: logging.debug('A used instance of webdriver has been destroyed') +def get_shadowed_iframe(driver: WebDriver, css_selector: str): + logging.debug("Getting ShadowRoot by selector: %s", css_selector) + shadow_element = driver.execute_script(""" + return document.querySelector(arguments[0]).shadowRoot.firstChild; + """, css_selector) + if shadow_element: + logging.debug("iframe found") + else: + logging.debug("iframe not found") + return shadow_element + + def click_verify(driver: WebDriver): try: logging.debug("Try to find the Cloudflare verify checkbox...") - iframe = driver.find_element(By.XPATH, "//iframe[starts-with(@id, 'cf-chl-widget-')]") + iframe = get_shadowed_iframe(driver, "div.cf-turnstile-wrapper") driver.switch_to.frame(iframe) - checkbox = driver.find_element( - by=By.XPATH, - value='//*[@id="content"]/div/div/label/input', - ) - if checkbox: + iframe_body = driver.execute_script(""" + return document.querySelector('body'); + """) + if iframe_body: actions = ActionChains(driver) - actions.move_to_element_with_offset(checkbox, 5, 7) - actions.click(checkbox) + actions.move_to_element_with_offset(iframe_body, 10, 10) + actions.click(iframe_body) actions.perform() logging.debug("Cloudflare verify checkbox found and clicked!") - except Exception: - logging.debug("Cloudflare verify checkbox not found on the page.") + except Exception as e: + logging.debug("Cloudflare verify checkbox not found on the page. %s", repr(e)) finally: driver.switch_to.default_content() From f5b3ad96fd06162d04ff93273c8ecde6d25cc535 Mon Sep 17 00:00:00 2001 From: MCG-pok Date: Fri, 19 Jul 2024 02:25:29 +0200 Subject: [PATCH 2/5] add js click on iframe_body --- src/flaresolverr_service.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/flaresolverr_service.py b/src/flaresolverr_service.py index 5ccd9ad..e6f040c 100644 --- a/src/flaresolverr_service.py +++ b/src/flaresolverr_service.py @@ -288,11 +288,12 @@ def click_verify(driver: WebDriver): return document.querySelector('body'); """) if iframe_body: + iframe_body.click() actions = ActionChains(driver) actions.move_to_element_with_offset(iframe_body, 10, 10) actions.click(iframe_body) actions.perform() - logging.debug("Cloudflare verify checkbox found and clicked!") + logging.debug("Attempted to click on iframe body") except Exception as e: logging.debug("Cloudflare verify checkbox not found on the page. %s", repr(e)) finally: From 959fe6c5ab4a863bc2cf957948acd5f6846d6544 Mon Sep 17 00:00:00 2001 From: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com> Date: Sat, 20 Jul 2024 14:26:08 +0100 Subject: [PATCH 3/5] Update release-docker.yml --- .github/workflows/release-docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index 88d5259..ebe302a 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -53,7 +53,7 @@ jobs: with: registry: ghcr.io username: ${{ github.repository_owner }} - password: ${{ secrets.GH_PAT }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v5 From 20f4c849ed74c1daf87075bc26043257b4201153 Mon Sep 17 00:00:00 2001 From: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com> Date: Sat, 20 Jul 2024 19:42:53 +0100 Subject: [PATCH 4/5] revert and bump action version --- .github/workflows/release-docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index ebe302a..4f1b652 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -53,10 +53,10 @@ jobs: with: registry: ghcr.io username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.GH_PAT }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile From 4bcf1bb637dce1b67b477bf55ac0de1150a0c567 Mon Sep 17 00:00:00 2001 From: MCG-pok Date: Fri, 26 Jul 2024 02:52:13 +0200 Subject: [PATCH 5/5] Update css selector to get shadowed iframe --- src/flaresolverr_service.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/flaresolverr_service.py b/src/flaresolverr_service.py index e6f040c..65ff6ce 100644 --- a/src/flaresolverr_service.py +++ b/src/flaresolverr_service.py @@ -282,11 +282,9 @@ def get_shadowed_iframe(driver: WebDriver, css_selector: str): def click_verify(driver: WebDriver): try: logging.debug("Try to find the Cloudflare verify checkbox...") - iframe = get_shadowed_iframe(driver, "div.cf-turnstile-wrapper") + iframe = get_shadowed_iframe(driver, "div:not(:has(div))") driver.switch_to.frame(iframe) - iframe_body = driver.execute_script(""" - return document.querySelector('body'); - """) + iframe_body = driver.find_element(By.CSS_SELECTOR, "body") if iframe_body: iframe_body.click() actions = ActionChains(driver)