|
|
@@ -21,20 +21,26 @@ from utils.scroll import HumanScroll
|
|
|
|
|
|
def generate_random_account_detail() -> Dict:
|
|
|
"""基于 randomuser 生成随机账户信息,并保留指定固定字段。"""
|
|
|
- base_date = datetime.utcnow().date() + timedelta(days=random.randint(20, 90))
|
|
|
+ today = datetime.today()
|
|
|
+ base_date = today + timedelta(days=random.randint(20, 90))
|
|
|
arrival_schengen_area_date = base_date.strftime("%Y-%m-%d")
|
|
|
departure_origin_date = (base_date - timedelta(days=random.randint(0, 2))).strftime("%Y-%m-%d")
|
|
|
departure_schengen_area_date = (base_date + timedelta(days=random.randint(2, 15))).strftime("%Y-%m-%d")
|
|
|
+
|
|
|
+ start_date = today - timedelta(days=5*365)
|
|
|
+ random_days = random.randint(0, (today - start_date).days)
|
|
|
+ passport_issue_date = start_date + timedelta(days=random_days)
|
|
|
+ passport_expiry_date = passport_issue_date.replace(year=passport_issue_date.year + 10) - timedelta(days=1)
|
|
|
|
|
|
default_payload = {
|
|
|
"pool_name": "tls.gb.fr.sentinel",
|
|
|
- "email": f"user{random.randint(100000, 999999)}@gmail-app.com",
|
|
|
+ "email": "user@gmail-app.com",
|
|
|
"pwd": "Visafly@111",
|
|
|
"location": "London",
|
|
|
"visa_type": "Short stay (<90 days) - Tourism",
|
|
|
"travel_purpose": "Tourism / Private visit",
|
|
|
# FRA1LO20260411910
|
|
|
- "application_form_id": "FRA" + "".join(str(random.randint(0, 9)) for _ in range(14)),
|
|
|
+ "application_form_id": "FRA1LO20260411910",
|
|
|
"last_name": "Smith",
|
|
|
"first_name": "James",
|
|
|
"gender": "Male",
|
|
|
@@ -42,12 +48,14 @@ def generate_random_account_detail() -> Dict:
|
|
|
"nationality": "United Kingdom",
|
|
|
"province_residence": "London",
|
|
|
"passport_type": "Ordinary passport",
|
|
|
- "passport_no": "".join(random.choices("ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=2)) + "".join(random.choices("0123456789", k=7)),
|
|
|
+ "passport_no": "EJ1934054",
|
|
|
+ "passport_issue_date": "2025-10-11",
|
|
|
+ "passport_expiry_date": "2035-10-10",
|
|
|
"phone_country_code": "44",
|
|
|
"phone_number": "7400000000",
|
|
|
- "departure_origin_date": departure_origin_date,
|
|
|
- "arrival_schengen_area_date": arrival_schengen_area_date,
|
|
|
- "departure_schengen_area_date": departure_schengen_area_date,
|
|
|
+ "departure_origin_date": "2026-07-30",
|
|
|
+ "arrival_schengen_area_date": "2026-07-30",
|
|
|
+ "departure_schengen_area_date": "2026-08-04",
|
|
|
}
|
|
|
|
|
|
try:
|
|
|
@@ -83,15 +91,17 @@ def generate_random_account_detail() -> Dict:
|
|
|
"location": city,
|
|
|
"visa_type": "Short stay (<90 days) - Tourism",
|
|
|
"travel_purpose": "Tourism / Private visit",
|
|
|
- "application_form_id": "FRA" + "".join(str(random.randint(0, 9)) for _ in range(14)),
|
|
|
+ "application_form_id": "FRA1LO" + "".join(str(random.randint(0, 9)) for _ in range(11)),
|
|
|
"last_name": last_name,
|
|
|
"first_name": first_name,
|
|
|
"gender": gender,
|
|
|
"birthday": birthday,
|
|
|
"nationality": country,
|
|
|
- "province_residence": state,
|
|
|
+ "province_residence": "London",
|
|
|
"passport_type": "Ordinary passport",
|
|
|
"passport_no": "".join(random.choices("ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=2)) + "".join(random.choices("0123456789", k=7)),
|
|
|
+ "passport_issue_date": passport_issue_date.strftime("%Y-%m-%d"),
|
|
|
+ "passport_expiry_date": passport_expiry_date.strftime("%Y-%m-%d"),
|
|
|
"phone_country_code": "44",
|
|
|
"phone_number": phone_number,
|
|
|
"departure_origin_date": departure_origin_date,
|
|
|
@@ -220,6 +230,7 @@ class TlsRegistrator:
|
|
|
"""执行自动注册"""
|
|
|
email = self.account_detail.get('email')
|
|
|
password = self.account_detail.get('pwd')
|
|
|
+ self._log(f'Account Detail:{self.account_detail}')
|
|
|
btn_selector = '#submit'
|
|
|
if not self.page.wait.ele_displayed(btn_selector, timeout=3):
|
|
|
register_btn = self.page.ele("tag:a@@href:registration")
|
|
|
@@ -263,7 +274,7 @@ class TlsRegistrator:
|
|
|
|
|
|
self._log("正在等待验证结果 (最多10秒)...")
|
|
|
success_dialog = self.page.wait.ele_displayed('tag:h1@text():Check your email inbox', timeout=10)
|
|
|
-
|
|
|
+
|
|
|
if not success_dialog:
|
|
|
self.page.get_screenshot("failed_submit.png")
|
|
|
raise BizLogicError(message='Failed to submit account registration')
|
|
|
@@ -403,16 +414,33 @@ class TlsRegistrator:
|
|
|
# if "travel-groups" in self.page.url or "auth" in self.page.url:
|
|
|
# raise BizLogicError(message="Redirect to service-level Failed!")
|
|
|
|
|
|
- btn_selector = 'tag:button@@data-testid=btn-add-applicant'
|
|
|
- if not self.page.wait.ele_displayed(btn_selector, timeout=10):
|
|
|
- btn_selector = 'tag:button@@data-testid=btn-max-number-of-applicants'
|
|
|
- if not self.page.ele(btn_selector):
|
|
|
- raise BizLogicError(message=f"Can't find selector={btn_selector}")
|
|
|
- add_btn = self.page.ele(btn_selector)
|
|
|
- add_btn.scroll.to_see(center=True)
|
|
|
- time.sleep(random.uniform(0.6, 0.8))
|
|
|
- add_btn.click()
|
|
|
- time.sleep(6)
|
|
|
+ btn_selector_add = 'tag:button@@data-testid=btn-add-applicant'
|
|
|
+ btn_selector_max = 'tag:button@@data-testid=btn-max-number-of-applicants'
|
|
|
+ error_selector = 'tag:h2@text():Something went wrong'
|
|
|
+
|
|
|
+ for attempt in range(2):
|
|
|
+ try:
|
|
|
+ btn_selector = btn_selector_add
|
|
|
+
|
|
|
+ if not self.page.wait.ele_displayed(btn_selector, timeout=10):
|
|
|
+ btn_selector = btn_selector_max
|
|
|
+ if not self.page.ele(btn_selector):
|
|
|
+ raise BizLogicError(message=f"Can't find selector={btn_selector}")
|
|
|
+
|
|
|
+ add_btn = self.page.ele(btn_selector)
|
|
|
+ add_btn.scroll.to_see(center=True)
|
|
|
+ time.sleep(random.uniform(0.6, 0.8))
|
|
|
+ add_btn.click()
|
|
|
+
|
|
|
+ if self.page.wait.ele_displayed(error_selector, timeout=5):
|
|
|
+ raise BizLogicError("Page shows 'Something went wrong'")
|
|
|
+ break
|
|
|
+ except Exception as e:
|
|
|
+ if attempt == 0:
|
|
|
+ self.page.refresh()
|
|
|
+ time.sleep(5)
|
|
|
+ else:
|
|
|
+ raise BizLogicError(message=f"Click add applicant failed after retry: {e}")
|
|
|
|
|
|
visa_type = self.account_detail.get("visa_type")
|
|
|
if visa_type:
|
|
|
@@ -452,10 +480,13 @@ class TlsRegistrator:
|
|
|
|
|
|
gender = self.account_detail.get('gender')
|
|
|
if gender:
|
|
|
- gender = gender.capitalize()
|
|
|
- ele = self.page.ele(f'tag:label@@text():{gender}')
|
|
|
- ele.scroll.to_see(center=True)
|
|
|
- ele.click()
|
|
|
+ try:
|
|
|
+ gender = gender.capitalize()
|
|
|
+ ele = self.page.ele(f'tag:label@@text():{gender}')
|
|
|
+ ele.scroll.to_see(center=True)
|
|
|
+ ele.click()
|
|
|
+ except Exception as e:
|
|
|
+ self._log(e)
|
|
|
|
|
|
fill_date_field(self.page, 'tag:input@@data-testid=f_pers_birth_date', self.account_detail.get('birthday'))
|
|
|
|
|
|
@@ -497,6 +528,22 @@ class TlsRegistrator:
|
|
|
ele.scroll.to_see(center=True)
|
|
|
ele.input(passport_no.upper())
|
|
|
|
|
|
+ passport_issue_date = self.account_detail.get('passport_issue_date')
|
|
|
+ if passport_issue_date:
|
|
|
+ try:
|
|
|
+ fill_date_field(self.page, 'tag:input@@data-testid=fi_passport_issue_date', passport_issue_date)
|
|
|
+ time.sleep(0.5)
|
|
|
+ except Exception as e:
|
|
|
+ self._log(e)
|
|
|
+
|
|
|
+ passport_expiry_date = self.account_detail.get('passport_expiry_date')
|
|
|
+ if passport_expiry_date:
|
|
|
+ try:
|
|
|
+ fill_date_field(self.page, 'tag:input@@data-testid=fi_passport_expiry_date', passport_expiry_date)
|
|
|
+ time.sleep(0.5)
|
|
|
+ except Exception as e:
|
|
|
+ self._log(e)
|
|
|
+
|
|
|
phone_country_code = self.account_detail.get('phone_country_code')
|
|
|
phone_number = self.account_detail.get('phone_number')
|
|
|
if phone_country_code:
|
|
|
@@ -582,7 +629,7 @@ if __name__ == "__main__":
|
|
|
}
|
|
|
|
|
|
CAPSOLVER_KEY = "CAP-5441DD341DD3CC2FAEF0BE6FE493EE9A"
|
|
|
- TLS_URL = "https://visas-fr.tlscontact.com/en-us/country/cn/vac/cnCNG2fr"
|
|
|
+ TLS_URL = "https://visas-fr.tlscontact.com/en-us/country/gb/vac/gbLON2fr"
|
|
|
ACCOUNT_DETAIL = generate_random_account_detail()
|
|
|
# ============================================
|
|
|
try:
|
|
|
@@ -593,7 +640,7 @@ if __name__ == "__main__":
|
|
|
bot.register()
|
|
|
bot.activate(sent_at=sent_at)
|
|
|
bot.make_account_useful()
|
|
|
- upload_account_to_server(ACCOUNT_DETAIL)
|
|
|
+ bot.upload_account_to_server()
|
|
|
except Exception as e:
|
|
|
print(f'Exception Info={e}')
|
|
|
time.sleep(3600)
|