1、准备环境
下载chrome和chromedriver驱动
chromedriver下载地址:
https://registry.npmmirror.com/binary.html?path=chromedriver
https://googlechromelabs.github.io/chrome-for-testing/
2、编写python脚本
import json
import time
from datetime import datetime
import tkinter as tk
from time import sleep
from tkinter import ttk
import pymysql
import re
from pymysql.cursors import DictCursor
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
# ======需要配置的参数开始===========================================================================================================
# 读取配置文件
with open('demo4_config.json', 'r', encoding='utf-8') as f:
config = json.load(f)
# 使用配置
mysql_config = config['mysql_config']
login_url = config['login_url']
chrome_dir = config['chrome_dir']
chrome_driver_dir = config['chrome_driver_dir']
chrome_driver_dir = config['chrome_driver_dir']
biness_list = config['biness_list']
# ======需要配置的参数结束===========================================================================================================
select_user_and_pwd_sql = "SELECT id,user_name, pwd,ty FROM bus where ty = "
select_cookies_sql = "select id,url,urlName,method,param,cookie,`type` from ftb_crawler_config_for_mt where `type`="
def get_credentials_from_mysql():
"""
从MySQL数据库获取用户名和密码
"""
connection = get_db_connection()
if not connection:
return None
try:
SQL = select_user_and_pwd_sql + user_select_ty
with connection.cursor() as cursor:
cursor.execute(SQL)
credentials = cursor.fetchall()
return credentials
except Exception as e:
print(f"Error connecting to MySQL: {e}")
return None
finally:
if connection:
connection.close()
def get_db_connection():
"""
获取数据库连接
"""
try:
connection = pymysql.connect(
host=mysql_config['host'],
port=mysql_config['port'],
user=mysql_config['user'],
password=mysql_config['password'],
database=mysql_config['database'],
cursorclass=DictCursor
)
return connection
except Exception as e:
print(f"获取数据库连接失败: {e}")
return None
def get_cookies_from_mysql(ty):
"""
查询并写入数据库
"""
connection = get_db_connection()
if not connection:
return None
try:
SelectSql = select_cookies_sql + str(ty)
with connection.cursor() as cursor:
cursor.execute(SelectSql)
credentials = cursor.fetchall()
return credentials
except Exception as e:
print(f"Error connecting to MySQL: {e}")
return None
finally:
if connection:
connection.close()
def login_to_website(driver, url, username, password):
"""
使用Selenium登录网站
"""
try:
driver.get(url)
search_box_user = WebDriverWait(driver, 3).until(
EC.presence_of_element_located(
(By.XPATH, "/html/body/div/div/div[1]/div[2]/div/div/div[3]/div[1]/form/div[1]/div/div[1]/input"))
)
search_box_user.send_keys("yawen")
search_box_password = WebDriverWait(driver, 3).until(
EC.presence_of_element_located(
(By.XPATH, "/html/body/div/div/div[1]/div[2]/div/div/div[3]/div[1]/form/div[2]/div/div[1]/div/input"))
)
search_box_password.send_keys("123456")
# search_box_agree = WebDriverWait(driver, 3).until(
# EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/div/div[1]/div/div/form/div[4]/div/div/label/span"))
# )
# search_box_agree.click()
search_btn_login = WebDriverWait(driver, 3).until(
EC.presence_of_element_located((By.CLASS_NAME, "login_btna"))
)
search_btn_login.click()
sleep(5)
print(f"成功登录: {username}")
return True
except Exception as e:
print(f"登录失败: {e}")
return False
def get_cookies_from_driver(driver):
"""
获取当前会话的Cookies
"""
# 定义一个字典
cookies = driver.get_cookies()
cookiesMap = {}
print("获取到的Cookies:")
for cookie in cookies:
print(f"{cookie['name']}: {cookie['value']}")
cookiesMap[cookie['name']] = cookie['value']
return cookiesMap
def buildCookies(oldCookies, loginToken, merchantNo):
newCookies = {}
if (oldCookies == "" or len(oldCookies) <= 10):
newCookies['cookie'] = "loginToken=" + loginToken + "; merchantNo=" + merchantNo + ";"
else:
newCookies = json.loads(oldCookies)
tempStr = newCookies['cookie']
# 使用正则替换旧字符串中的 loginToken 和 merchantNo
tempStr = re.sub(r'loginToken=[^;]*', f'loginToken={loginToken}', tempStr)
tempStr = re.sub(r'merchantNo=[^;]*', f'merchantNo={merchantNo}', tempStr)
newCookies['cookie'] = tempStr
return json.dumps(newCookies)
def updateCookies(updateSql):
connection = get_db_connection()
if not connection:
return None
try:
with connection.cursor() as cursor:
cursor.execute(updateSql)
connection.commit()
print("更新成功")
except Exception as e:
print(f"Error connecting to MySQL: {e}")
def saveCookesDate(ty, loginToken, merchantNo):
list = get_cookies_from_mysql(ty)
now = datetime.now()
current_time_str = now.strftime("%Y-%m-%d %H:%M:%S")
for item in list:
cookeis = item['cookie']
newCookies = buildCookies(cookeis, loginToken, merchantNo)
updateSql = "update ftb_crawler_config_for_mt set lastUpdateTime='" + current_time_str + "', cookie = '" + newCookies + "' where id = '" + str(
item['id'] + "'")
print(updateSql)
updateCookies(updateSql)
def main():
# MySQL数据库配置
# 1. 从MySQL获取用户名和密码
credentials = get_credentials_from_mysql()
if not credentials:
print("无法从数据库获取凭证")
return
# 使用第一个找到的凭证(根据实际情况调整)
username = credentials[0]['user_name']
password = credentials[0]['pwd']
ty = credentials[0]['ty']
# 初始化Selenium WebDriver(这里使用Chrome,可以根据需要修改)
chrome_options = Options()
chrome_options.binary_location = chrome_dir # macOS 示例
# chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:51249")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option("useAutomationExtension", False)
# 指定ChromeDriver的路径
service = Service(chrome_driver_dir)
driver = webdriver.Chrome(service=service, options=chrome_options)
try:
# 2. 登录网站
if not login_to_website(driver, login_url, username, password):
print("登录失败,终止流程")
return
# 3. 获取Cookies
cookies = get_cookies_from_driver(driver)
loginToken = cookies['BMAP_SECKEY']
print("登录Token:", loginToken)
merchantNo = cookies['cna']
if loginToken != "" and merchantNo != "":
# 写入数据库(loginToken,merchantNo,ty)
saveCookesDate(ty, loginToken, merchantNo)
else:
print("登录失败")
finally:
# 关闭浏览器
time.sleep(50) # 保留5秒查看结果
driver.quit()
def on_select():
global user_select_ty
user_select_ty = biness_select_var.get()
selected_name = biness_list[user_select_ty]
print(f"你选择了:{user_select_ty} = {selected_name}")
binsee_root.destroy() # 关闭窗口
def binsee_select():
global binsee_root, biness_select_var # 使用全局变量便于 on_select 访问
binsee_root = tk.Tk()
binsee_root.title("请选择商家")
binsee_root.geometry("600x300")
biness_select_var = tk.StringVar(value="1") # 默认选中第一个
for key in biness_list:
ttk.Radiobutton(
binsee_root,
text=f"{key} = {biness_list[key]}",
variable=biness_select_var,
value=key
).pack(pady=5)
ttk.Button(binsee_root, text="确认", command=on_select).pack(pady=10)
binsee_root.mainloop()
if __name__ == "__main__":
binsee_select()
main()
3、编写配置脚本
{
"mysql_config": {
"host": "127.0.0.1",
"user": "",
"port": 62754,
"password": "",
"database": "123456"
},
"login_url": "http://192.168.3.24:11001/login",
"chrome_dir": "chrome-win64/chrome.exe",
"chrome_driver_dir": "chromedriver-win64/chromedriver.exe",
"biness_list": {
"1": "大河宴",
"2": "老船长",
"3": "咱妈烀饼"
}
}
4、按照打包工具:
pip install pyinstaller
打包:pyinstaller -F -w "D:\PythonProject\demo\seleniumdemo\demo4.py" --noconsole --onefile
打包成功后:会生成dist目录
把chrome 和chromedriver驱动拷贝 dist目录
把配置文件拷贝到dist目录
在打成压缩包,然后就可以在其他任何地方运行该exe脚本了
5、在打包完成后还可以制作成安装包
5.1 下载并按照安装包工具
https://jrsoftware.org/isinfo.php
5.2 安装安装包制作工具
5.3 运行安装包制作工具的 Compil32.exe
5.4 根据向导制作安装包配置文件 xxx.iss
如:
meituan_token/ ├── demo6.exe ├── demo6_config.json ├── chrome-win64/ │ └── chrome.exe └── chromedriver-win64/ └── chromedriver.exe
; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "美团Token采集工具" #define MyAppVersion "1.0.1" #define MyAppPublisher "翻台宝" #define MyAppURL "https://www.example.com/" #define MyAppExeName "demo6.exe" #define MyAppAssocName MyAppName + " File" #define MyAppAssocExt ".myp" #define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{DF19D0ED-BF55-46C7-A48B-2CEC499121F3} AppName={#MyAppName} AppVersion={#MyAppVersion} ;AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={autopf}\{#MyAppName} UninstallDisplayIcon={app}\{#MyAppExeName} ; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run ; on anything but x64 and Windows 11 on Arm. ArchitecturesAllowed=x64compatible ; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the ; install be done in "64-bit mode" on x64 or Windows 11 on Arm, ; meaning it should use the native 64-bit Program Files directory and ; the 64-bit view of the registry. ArchitecturesInstallIn64BitMode=x64compatible ChangesAssociations=yes DisableProgramGroupPage=yes ; Uncomment the following line to run in non administrative install mode (install for current user only). ;PrivilegesRequired=lowest OutputBaseFilename=mysetup SolidCompression=yes WizardStyle=modern [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] Source: "D:\PythonProject\meituan_token\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion Source: "D:\PythonProject\meituan_token\demo6_config.json"; DestDir: "{app}"; Flags: ignoreversion Source: "D:\PythonProject\meituan_token\chromedriver-win64\*"; DestDir: "{app}\chromedriver-win64"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "D:\PythonProject\meituan_token\chrome-win64\*"; DestDir: "{app}\chrome-win64"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Registry] Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0" Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" [Icons] Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
就会在:Output目录中生成按照包程序
浙公网安备 33010602011771号