This commit is contained in:
2025-11-21 01:56:01 +08:00
parent 2e2cd3e260
commit f3b4ec2601
2 changed files with 38 additions and 26 deletions

View File

@@ -1,3 +1,5 @@
# 0.1.0
- 修复cloudflare验证问题
# 0.0.9 # 0.0.9
- 修正cloudflare验证 - 修正cloudflare验证
# 0.0.8 # 0.0.8

View File

@@ -10,16 +10,17 @@ from mail_ import mail_
from bit_browser import bit_browser from bit_browser import bit_browser
from api import api from api import api
class Auto: class Auto:
def __init__(self,http:str=None): def __init__(self, http: str = None):
self.browser = Chromium(http) self.browser = Chromium(http)
self.tab = self.browser.latest_tab self.tab = self.browser.latest_tab
pass pass
# cf打码 # cf打码
def solve_cloudflare(self): def solve_cloudflare(self, is_ok: bool = False):
tab = self.browser.latest_tab tab = self.browser.latest_tab
for _ in range(5): for _ in range(3):
self.tab.wait(1) self.tab.wait(1)
try: try:
shadow1 = tab.ele( shadow1 = tab.ele(
@@ -31,16 +32,16 @@ class Auto:
if shadow2: if shadow2:
logger.debug("找到Cloudflare iframe body shadow root") logger.debug("找到Cloudflare iframe body shadow root")
status = shadow2.ele( status = shadow2.ele(
'x://span[text()="Verifying..."]', timeout=1) 'x://span[text()="Verifying..."]', timeout=1.5)
if status: if status:
tab.wait(3) tab.wait(3)
status = shadow2.ele( status = shadow2.ele(
'x://span[text()="Success!"]', timeout=1) 'x://span[text()="Success!"]', timeout=1.5)
if status: if status:
logger.debug("Cloudflare验证成功") logger.debug("Cloudflare验证成功")
return True return True
checkbox = shadow2.ele( checkbox = shadow2.ele(
'x://input[@type="checkbox"]', timeout=1) 'x://input[@type="checkbox"]', timeout=1.5)
if checkbox: if checkbox:
checkbox.click() checkbox.click()
logger.debug("点击Cloudflare复选框") logger.debug("点击Cloudflare复选框")
@@ -49,8 +50,10 @@ class Auto:
# return False # return False
except Exception as e: except Exception as e:
# logger.error(f"处理Cloudflare异常: {e}") # logger.error(f"处理Cloudflare异常: {e}")
logger.debug(f"cloudflare处理通过: {e}") if is_ok:
return True logger.debug(f"cloudflare处理通过: {e}")
return True
return self.solve_cloudflare(is_ok=True)
tab.wait(1) tab.wait(1)
return False return False
@@ -75,11 +78,13 @@ class Auto:
else: else:
logger.debug("Cloudflare验证成功.") logger.debug("Cloudflare验证成功.")
self.tab.wait(1.5) self.tab.wait(1.5)
bol = self.tab.ele('t:h1@text():Sorry, you have been blocked', timeout=1) bol = self.tab.ele(
't:h1@text():Sorry, you have been blocked', timeout=1)
if bol: if bol:
logger.debug("ip被ban秒") logger.debug("ip被ban秒")
return False return False
bol = self.tab.ele('t:div@text():ERR_SSL_PROTOCOL_ERROR', timeout=1) bol = self.tab.ele(
't:div@text():ERR_SSL_PROTOCOL_ERROR', timeout=1)
if bol: if bol:
logger.debug("刷新网页") logger.debug("刷新网页")
self.tab.refresh() self.tab.refresh()
@@ -116,7 +121,7 @@ class Auto:
continue_button.click() continue_button.click()
logger.debug("点击Continue按钮成功") logger.debug("点击Continue按钮成功")
self.tab.wait(1.5) self.tab.wait(1.5)
bol = self.tab.ele('t:div@text():Loading...',timeout=1) bol = self.tab.ele('t:div@text():Loading...', timeout=1)
if bol: if bol:
logger.debug("Loading...") logger.debug("Loading...")
if bl: if bl:
@@ -125,7 +130,8 @@ class Auto:
logger.debug("异常界面") logger.debug("异常界面")
self.tab.wait(1) self.tab.wait(1)
return self.click_continue(bl=True) return self.click_continue(bl=True)
bol = self.tab.ele('t:h2@text()=You are being rate limited', timeout=1) bol = self.tab.ele(
't:h2@text()=You are being rate limited', timeout=1)
if bol: if bol:
logger.debug("被限流, 退出") logger.debug("被限流, 退出")
return False return False
@@ -149,7 +155,7 @@ class Auto:
return False return False
# 随机取城市 # 随机取城市
def get_random_city(self, province: str|None=None): def get_random_city(self, province: str | None = None):
cities = { cities = {
"Alberta": ["Calgary", "Edmonton"], "Alberta": ["Calgary", "Edmonton"],
"British Columbia": ["Vancouver"], "British Columbia": ["Vancouver"],
@@ -164,8 +170,7 @@ class Auto:
} }
if province is None: if province is None:
province = random.choice(list(cities.keys())) province = random.choice(list(cities.keys()))
return province,random.choice(cities.get(province, [])) return province, random.choice(cities.get(province, []))
def get_province_by_city(self, city: str) -> str | None: def get_province_by_city(self, city: str) -> str | None:
""" """
@@ -186,9 +191,8 @@ class Auto:
} }
return mapping.get(city) return mapping.get(city)
# 随机实物 # 随机实物
def get_random_food(self,city: str, shop: str) -> list[str]: def get_random_food(self, city: str, shop: str) -> list[str]:
""" """
随机选择 1~2 种食物类别,并为每个类别至少选择 1 个具体产品 随机选择 1~2 种食物类别,并为每个类别至少选择 1 个具体产品
@@ -270,8 +274,8 @@ class Auto:
return return
j = 0 j = 0
while True: while True:
if j >3: if j > 3:
return False return False
info = get_random_canada_info(province, city) info = get_random_canada_info(province, city)
if len(info.get('postcode')) > 5: if len(info.get('postcode')) > 5:
break break
@@ -314,7 +318,7 @@ class Auto:
logger.debug(f"填写province: {province}") logger.debug(f"填写province: {province}")
self.tab.ele( self.tab.ele(
't:select@id=CanProv').ele(f't:option@text()={province}').click() 't:select@id=CanProv').ele(f't:option@text()={province}').click()
self.tab.wait(0.1) self.tab.wait(0.1)
logger.debug(f"填写postal_code: {postal_code}") logger.debug(f"填写postal_code: {postal_code}")
self.tab.ele('t:input@id=CanPostal').set.value(postal_code) self.tab.ele('t:input@id=CanPostal').set.value(postal_code)
self.tab.wait(0.1) self.tab.wait(0.1)
@@ -352,7 +356,7 @@ class Auto:
self.tab.wait(0.1) self.tab.wait(0.1)
for i in range(3): for i in range(3):
bol = self.solve_cloudflare() bol = self.solve_cloudflare()
if not bol: if not bol:
logger.debug("Cloudflare验证失败.") logger.debug("Cloudflare验证失败.")
self.tab.wait(0.1) self.tab.wait(0.1)
else: else:
@@ -378,14 +382,14 @@ class Auto:
# 取对应城市的代理 # 取对应城市的代理
def get_proxy( city: str): def get_proxy(city: str):
if city == "Calgary": if city == "Calgary":
return "us.novproxy.io:1000:ozua8623-region-CA-st-Alberta-city-Calgary:6wdcv4gq".split(':') return "us.novproxy.io:1000:ozua8623-region-CA-st-Alberta-city-Calgary:6wdcv4gq".split(':')
elif city =='Edmonton': elif city == 'Edmonton':
return 'us.novproxy.io:1000:ozua8623-region-CA-st-Alberta-city-Edmonton:6wdcv4gq'.split(':') return 'us.novproxy.io:1000:ozua8623-region-CA-st-Alberta-city-Edmonton:6wdcv4gq'.split(':')
elif city =='Vancouver': elif city == 'Vancouver':
return 'us.novproxy.io:1000:ozua8623-region-CA-st-British Columbia-city-Vancouver:6wdcv4gq'.split(':') return 'us.novproxy.io:1000:ozua8623-region-CA-st-British Columbia-city-Vancouver:6wdcv4gq'.split(':')
elif city =='Halifax': elif city == 'Halifax':
return 'us.novproxy.io:1000:ozua8623-region-CA-st-Nova Scotia-city-Halifax:6wdcv4gq'.split(':') return 'us.novproxy.io:1000:ozua8623-region-CA-st-Nova Scotia-city-Halifax:6wdcv4gq'.split(':')
elif city == 'Toronto': elif city == 'Toronto':
return 'us.novproxy.io:1000:ozua8623-region-CA-st-Ontario-city-Toronto:6wdcv4gq'.split(':') return 'us.novproxy.io:1000:ozua8623-region-CA-st-Ontario-city-Toronto:6wdcv4gq'.split(':')
@@ -395,6 +399,8 @@ def get_proxy( city: str):
"""指纹浏览器操作""" """指纹浏览器操作"""
# 创建指纹浏览器 # 创建指纹浏览器
def create_fingerprint_browser(city: str): def create_fingerprint_browser(city: str):
""" """
根据城市创建指纹浏览器并执行问卷流程 根据城市创建指纹浏览器并执行问卷流程
@@ -448,6 +454,7 @@ def create_fingerprint_browser(city: str):
except Exception as e: except Exception as e:
logger.error(f"{city} 删除浏览器异常: {e}") logger.error(f"{city} 删除浏览器异常: {e}")
def run_city_forever(city: str): def run_city_forever(city: str):
""" """
持续循环运行指定城市流程:完成一次即关闭并删除浏览器,然后重新创建继续运行 持续循环运行指定城市流程:完成一次即关闭并删除浏览器,然后重新创建继续运行
@@ -462,6 +469,7 @@ def run_city_forever(city: str):
logger.error(f"{city} 流程异常: {e}") logger.error(f"{city} 流程异常: {e}")
time.sleep(2) time.sleep(2)
def run_all_cities_concurrently(): def run_all_cities_concurrently():
""" """
多线程并发运行所有城市流程 多线程并发运行所有城市流程
@@ -471,7 +479,8 @@ def run_all_cities_concurrently():
# cities = ['Calgary'] # cities = ['Calgary']
threads = [] threads = []
for city in cities: for city in cities:
t = threading.Thread(target=run_city_forever, args=(city,), name=f"{city}-thread") t = threading.Thread(target=run_city_forever,
args=(city,), name=f"{city}-thread")
t.start() t.start()
threads.append(t) threads.append(t)
logger.info(f"{city} 线程已启动") logger.info(f"{city} 线程已启动")
@@ -480,6 +489,7 @@ def run_all_cities_concurrently():
t.join() t.join()
logger.info("所有城市流程执行完成") logger.info("所有城市流程执行完成")
if __name__ == "__main__": if __name__ == "__main__":
# auto = Auto() # auto = Auto()
# auto.get_random_food('a') # auto.get_random_food('a')