| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import time
- from DrissionPage import ChromiumPage
- from loguru import logger
- class CloudflareBypasser:
- """
- 用于绕过 Cloudflare 页面
- :param driver: ChromiumPage 对象
- :param max_retries: 最大重试次数,默认为 -1
- :param log: 日志记录器,默认为 None
- """
- def __init__(self, driver: ChromiumPage, max_retries=-1, log=None):
- self.driver = driver
- self.max_retries = max_retries
- # self.log = log
- self.log = log or logger
- def search_recursively_shadow_root_with_iframe(self,ele):
- if ele.shadow_root:
- if ele.shadow_root.child().tag == "iframe":
- return ele.shadow_root.child()
- else:
- for child in ele.children():
- result = self.search_recursively_shadow_root_with_iframe(child)
- if result:
- return result
- return None
- def search_recursively_shadow_root_with_cf_input(self,ele):
- if ele.shadow_root:
- if ele.shadow_root.ele("tag:input"):
- return ele.shadow_root.ele("tag:input")
- else:
- for child in ele.children():
- result = self.search_recursively_shadow_root_with_cf_input(child)
- if result:
- return result
- return None
-
- def locate_cf_button(self):
- button = None
- eles = self.driver.eles("tag:input")
- for ele in eles:
- if "name" in ele.attrs.keys() and "type" in ele.attrs.keys():
- if "turnstile" in ele.attrs["name"] and ele.attrs["type"] == "hidden":
- button = ele.parent().shadow_root.child()("tag:body").shadow_root("tag:input")
- break
-
- if button:
- return button
- else:
- # If the button is not found, search it recursively
- self.log_message("Basic search failed. Searching for button recursively.")
- ele = self.driver.ele("tag:body")
- iframe = self.search_recursively_shadow_root_with_iframe(ele)
- if iframe:
- button = self.search_recursively_shadow_root_with_cf_input(iframe("tag:body"))
- else:
- self.log_message("Iframe not found. Button search failed.")
- return button
- def log_message(self, message):
- if self.log:
- # print(message)
- self.log.info(message)
- def click_verification_button(self):
- try:
- button = self.locate_cf_button()
- if button:
- self.log_message("Verification button found. Attempting to click.")
- button.click()
- else:
- self.log_message("Verification button not found.")
- except Exception as e:
- self.log_message(f"Error clicking verification button: {e}")
- def is_bypassed(self):
- try:
- title = self.driver.title.lower()
- return "just a moment" not in title
- except Exception as e:
- self.log_message(f"Error checking page title: {e}")
- return False
- def bypass(self):
-
- try_count = 0
- while not self.is_bypassed():
- if 0 < self.max_retries + 1 <= try_count:
- self.log_message("Exceeded maximum retries. Bypass failed.")
- break
- self.log_message(f"Attempt {try_count + 1}: Verification page detected. Trying to bypass...")
- self.click_verification_button()
- try_count += 1
- time.sleep(2)
- if self.is_bypassed():
- self.log_message("Bypass successful.")
- else:
- self.log_message("Bypass failed.")
|