80 lines
3.5 KiB
Python
80 lines
3.5 KiB
Python
"""
|
||
ERP 数据同步器 - 自动化浏览器拉起与登录守护模块
|
||
目标:
|
||
1. 自动寻找本地安装的 Chrome 浏览器。
|
||
2. 以 9222 端口和独立的用户数据目录启动(互不干扰,持久化登录状态)。
|
||
3. 弹出 ERP 登录页面,等待用户手动登录(解决滑块验证码等问题)。
|
||
4. 登录成功后,将浏览器挂在后台作为保活引擎。
|
||
"""
|
||
import sys
|
||
import time
|
||
from pathlib import Path
|
||
from DrissionPage import ChromiumOptions, ChromiumPage
|
||
from config import DATA_DIR
|
||
|
||
# 独立的用户数据目录,放在外部持久化目录,这样重启不会丢失登录状态
|
||
USER_DATA_DIR = DATA_DIR / "browser_login" / "chrome_user_data"
|
||
HOME_URL = "https://yunmes.tftykj.cn/"
|
||
|
||
def start_and_wait_login():
|
||
print("🚀 [1/3] 正在配置内置 Chrome 浏览器引擎...")
|
||
|
||
# 初始化配置
|
||
co = ChromiumOptions()
|
||
co.set_local_port(9222)
|
||
# 指定一个独立的用户数据存放文件夹
|
||
co.set_user_data_path(str(USER_DATA_DIR))
|
||
# 忽略证书错误等常规反爬配置
|
||
co.ignore_certificate_errors()
|
||
|
||
print("🌍 [2/3] 正在拉起浏览器并前往 ERP 登录页...")
|
||
try:
|
||
# 这一步会自动寻找你电脑上的 Chrome,如果没有运行在 9222 端口,它会自动帮你启动一个!
|
||
page = ChromiumPage(co)
|
||
except Exception as e:
|
||
print(f"❌ 启动浏览器失败,请确保电脑安装了 Chrome 浏览器!报错信息: {e}")
|
||
return None
|
||
|
||
page.get(HOME_URL)
|
||
|
||
print("\n" + "="*50)
|
||
print("👀 [等待人工介入] 请在弹出的浏览器窗口中完成登录操作!")
|
||
print("💡 提示: 输入账号密码、通过滑块验证码,直到进入 ERP 系统主界面。")
|
||
print("="*50 + "\n")
|
||
|
||
# 循环检查登录状态
|
||
# 怎么判断登录成功?ERP 登录前 URL 通常带有 Login 等字样,或者登录后页面会出现类似“退出”、“注销”或者用户名的元素
|
||
# 我们这里通过检测页面中是否出现了主菜单的特有元素,或者通过监听一个登录后的特有接口来判断
|
||
is_logged_in = False
|
||
|
||
while not is_logged_in:
|
||
time.sleep(2)
|
||
# 假设登录后页面会出现“首页”或者用户的头像/名字(这里的 xpath 需要根据你们 ERP 登录后的实际情况微调,我们先用一个保险的:看看有没有业务统计报表的菜单)
|
||
# 如果还在登录页,肯定找不到这个元素
|
||
try:
|
||
# 这里的元素用来验证是否已经成功进入系统内部
|
||
menu_ele = page.ele('xpath://*[@id="app"]/div/div[1]/div[1]/div[2]/div/div[1]/div/div[10]/div/p', timeout=1)
|
||
if menu_ele:
|
||
is_logged_in = True
|
||
except:
|
||
pass
|
||
|
||
if not is_logged_in:
|
||
print("⏳ 等待登录中...")
|
||
|
||
print("\n✅ [3/3] 检测到登录成功!")
|
||
print("🔒 登录状态已保存,你可以随时关闭或者最小化这个浏览器窗口。")
|
||
print("🤖 爬虫引擎已挂载至后台,可以开始点击前端界面的【同步数据】按钮了!\n")
|
||
|
||
return page
|
||
|
||
if __name__ == "__main__":
|
||
# 单独运行此文件即可拉起浏览器
|
||
page = start_and_wait_login()
|
||
if page:
|
||
# 为了不让脚本退出,这里写个死循环保活(在真正的桌面软件中,这里就是启动 Flask 后端和 Webview 窗口的地方)
|
||
try:
|
||
while True:
|
||
time.sleep(10)
|
||
except KeyboardInterrupt:
|
||
print("👋 守护进程已退出。") |