#避坑总结#
1.项目文件构成
sample.bat --批处理文件
sample.py --执行文件
运行顺序
任务计划程序->sample.bat->sample.py
2.批处理文件完整示例:
@echo off
echo %date% %time% %username% >> c:\log.txt
REM 设置正确的用户名和密码
set your_username=域账户
set your_password=域账户密码
REM 建立网络连接
net use \\服务器\文件名 /user:%your_username% %your_password%
cd /d "C:\Users\admin\PycharmProjects\pythonProject\venv\"
python selenium_bw.py 1>>c:\log.txt 2>>&1
REM 断开网络连接(可选)
REM net use \\服务器\文件名 /delete
echo %date% %time% >> c:\log.txt
2-坑1:批处理文件访问网络服务器资源,需要先建立连接
通过CMD命令窗口或双击运行Bat批处理程序,可以访问正常执行。
通过任务计划程序访问域服务器的资源文件,需要建立网络连接,输入域账户和密码,才能访问。
REM 设置正确的用户名和密码
set your_username=域账户
set your_password=域账户密码
REM 建立网络连接
net use \\服务器\文件名 /user:%your_username% %your_password%
REM 断开网络连接(可选)
REM net use \\服务器\文件名 /delete
3.Python文件完整示例:
完成内容:1.从指定网站下载文件 2.执行数据编辑 3.发送邮件
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import cv2
import os
import shutil
import datetime
import win32com.client
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
def login_and_process():
for _ in range(3): # Try执行3次
try:
###############图形模式##################
#browser = webdriver.Chrome()
#browser.maximize_window()
###############无界模式##################
options = webdriver.ChromeOptions()
# 无界面模式
#options.add_argument('--headless=new')
options.add_argument('--disable-web-security')
options.add_argument('--safebrowsing-disable-download-protection')
options.add_argument('--allow-running-insecure-content')
options.add_argument('--allow-cross-origin-auth-prompt')
# 最大化窗口
options.add_argument('--start-maximized')
options.add_argument('--ignore-certificate-errors')
options.add_experimental_option("prefs", {
"download.default_directory": r"C:\Users\admin\Downloads",
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing.enabled": False
})
browser = webdriver.Chrome(options=options)
####################################
# 登录BW首页
browser.get('http://xxxx.xxxx.com/portal?j_username=用户名&j_password=密码')
time.sleep(3)
# 尝试找到收藏夹按钮并点击
favorite_link_xpath = "//li[@id='Favorites_HyperLink']/*[contains(@title,'收藏夹')]"
browser.find_element('xpath', favorite_link_xpath)
# 定义按钮名称和对应的XPATH
buttons = {
'第一个超链接': "//tr[@class='PopUpMenuItemRow'][contains(@title,'第一个超链接')]",
'第二个超链接': "//tr[@class='PopUpMenuItemRow'][contains(@title,'第二个超链接')]",
'第三个超链接': "//tr[@class='PopUpMenuItemRow'][contains(@title,'第三个超链接')]",
}
for button_name, button_xpath in buttons.items():
time.sleep(3)
browser.find_element('xpath', favorite_link_xpath).click()
time.sleep(1)
# 打开对应的报表链接
browser.find_element('xpath', button_xpath).click()
# 等待1秒钟以确保页面刷新
time.sleep(1)
# 读取目标按钮图像
target_image = cv2.imread(r"C:\Users\admin\Desktop\export.bmp", cv2.IMREAD_GRAYSCALE)
while True:
# 保存屏幕截图
browser.save_screenshot("screenshot.png")
# 在屏幕截图中查找目标按钮位置
screenshot = cv2.imread("screenshot.png", cv2.IMREAD_GRAYSCALE)
result = cv2.matchTemplate(screenshot, target_image, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
threshold = 0.8 # 设置匹配阈值
if max_val >= threshold:
# 如果找到了按钮
# 执行35次Tab键操作
for i in range(36):
# 找到当前焦点所在的元素
current_element = browser.switch_to.active_element
# 将焦点移到下一个元素
current_element.send_keys(Keys.TAB)
# 等待一段时间,以便观察效果
time.sleep(1)
# 判断是否是最后一次循环
if i == 35:
# 最后一次循环,发送 Enter 键
print("找到了,开始点击...")
current_element.send_keys(Keys.ENTER)
# 等待下载完成
time.sleep(6)
print("下载完成...")
break
else:
# 如果没有找到按钮
time.sleep(2)
print("未找到按钮,继续查找...")
browser.quit()
break
except Exception as e:
print("登录或处理出错:", e)
browser.quit()
time.sleep(5)
print("完成,退出程序")
def copy_and_move_files():
print("开始Copy&Move")
try:
# 源文件夹路径
source_folder = r"C:\Users\admin\Downloads"
# 备份文件夹路径
backup_folder = r"C:\bak"
# 目标文件夹路径
target_folder = r"\\服务器名\文件名\targetfolder"
# 获取当日日期
today_date = datetime.datetime.now().strftime("%Y%m%d")
print(today_date)
# 判断是否有5个文件以0ANALYSIS开头
source_files = [f for f in os.listdir(source_folder) if f.startswith('0ANALYSIS')]
if len(source_files) == 5:
# 创建以当日日期为名字的文件夹
target_folder_today = os.path.join(backup_folder, today_date)
os.makedirs(target_folder_today, exist_ok=True)
# 复制文件到当日日期文件夹
for filename in source_files:
source_file = os.path.join(source_folder, filename)
shutil.copy(source_file, target_folder_today)
# 移动文件到服务器文件夹
for filename in source_files:
source_file = os.path.join(source_folder, filename)
target_file = os.path.join(target_folder, filename)
shutil.move(source_file, target_file)
except Exception as e:
print("复制和移动处理出错:", e)
time.sleep(5)
print("复制和移动完成")
def run_excel_macro():
try:
file_path = r"C:\autorun\autotest.xlsm"
macro_name1 = "ThisWorkbook.macro1"
macro_name2 = "ThisWorkbook.macro2"
# 初始化 Outlook 应用程序
appOutlook = win32com.client.Dispatch("Outlook.Application")
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = False # 设置 Excel 不可见
wb = excel.Workbooks.Open(file_path)
excel.Application.Run(macro_name1)
print("macro1运行完成")
excel.Application.Run(macro_name2)
print("macro2运行完成")
except Exception as e:
print("异常错误:", e)
finally:
# if 'wb' in locals():
# wb.Close(SaveChanges=False) # 关闭文件,不保存
if 'excel' in locals():
excel.Quit() # 退出 Excel
excel = None
# 关闭 Outlook 应用程序
appOutlook.Quit()
# 释放对象
appOutlook = None
def main():
try:
login_and_process()
copy_and_move_files()
run_excel_macro()
except Exception as e:
print("程序执行过程中出现异常:", e)
if __name__ == "__main__":
main()
3.坑2:任务计划程序执行Selenium模拟webdriver,需要无界/无头模式运行
任务计划程序模式下,无法正常启动Chrome浏览器,可以通过 --headless=new的Option设置,隐藏Chrome实现启动Chrome,在隐藏模式下,通过Selenium模拟键盘的操作不受影响。
###############无界模式##################
options = webdriver.ChromeOptions()
# 无界面模式
options.add_argument('--headless=new')
options.add_argument('--disable-web-security')
options.add_argument('--safebrowsing-disable-download-protection')
options.add_argument('--allow-running-insecure-content')
options.add_argument('--allow-cross-origin-auth-prompt')
# 最大化窗口
options.add_argument('--start-maximized')
options.add_argument('--ignore-certificate-errors')
options.add_experimental_option("prefs", {
"download.default_directory": r"C:\Users\admin\Downloads",
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing.enabled": False
})
browser = webdriver.Chrome(options=options)
####################################
3.坑3:点击“查看页面代码”获取不到的元素,需要通过Tab键操作
网页代码查看方式:网页任意位置,鼠标点击右键,选择查看页面源代码(如下图),查看控件的ID或者名称是否存在,如果不存在需要通过Tab键间接操作
3.坑4:页面加载完成,通过是否出现预期的按钮判断,比单纯设置等待时间精准高效
while True:
# 保存屏幕截图
browser.save_screenshot("screenshot.png")
# 在屏幕截图中查找目标按钮位置
screenshot = cv2.imread("screenshot.png", cv2.IMREAD_GRAYSCALE)
result = cv2.matchTemplate(screenshot, target_image, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
threshold = 0.8 # 设置匹配阈值
if max_val >= threshold:
#找到了
break
else
#没找到,继续找
3.坑4:屏幕保护模式下,需要Selenium模拟键盘,无法使用Pyautogui点击操作
虽然手动可以启动Chrome完成页面点击操作,在屏保模式下,鼠标将失去焦点,无法完成点击操作,此时需要用到Selenium的模式键盘操作,完成点击操作。
# 从当前按钮开始,按10下Tab键,假设当前按钮顺序第一,希望点击按钮顺序在第11个
for i in range(11):
current_element = browser.switch_to.active_element
# 将焦点移到下一个元素
current_element.send_keys(Keys.TAB)
# 等待一段时间,以便观察效果
time.sleep(1)
# 判断是否是最后一次循环
if i == 10:
# 最后一次循环,发送 Enter 键
print("找到了,开始点击...")
current_element.send_keys(Keys.ENTER)
3.坑5:解决Python执行Excel文件Open时,提示'gbk' codec can't encode character '\u2022'错误
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
3.坑6:任务计划程序模式下,需要创建Desktop文件夹才能打开Excel运行Macro宏
虽然手动可以运行Excel的Macro宏,但是windows任务计划出于安全机制,不允许自动运行Excel的Macro宏,需要通过以下设置回避。
C:\Windows\System32\config\systemprofile\Desktop
C:\Windows\SysWOW64\config\systemprofile\Desktop
3.坑7:使用Google Chrome122之前的版本,可以解决“已阻止不安全的下载”的问题
随着Chrome版本的升级,会遇到之前可以下载,后续遇到无法下载的问题,这时需要卸载当前版本,安装122以前的版本,并关闭Chrome的升级更新,保证不被升级到最新版本。
修改注册表的值,如果没有项或值则新建
路径:计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome
RendererCodeIntegrityEnabled 的值设置为0
需要使用的ChromeDriver下载地址
ChromeDriver - WebDriver for Chrome - Downloads (chromium.org)
解压之后的存放路径,和python.exe放在一起。
C:\Users\admin\AppData\Local\Programs\Python\Python39
4.任务计划程序设置
远程服务器上创建计划任务,不要注销账户,直接关闭远程窗口,任务计划可以正常运行。
起始于:输入批处理文件的路径
程序或脚本:输入批处理文件名
勾选:使用最高权限运行,不管用户是否登录都要运行
4.坑8:任务计划程序,Excel调用Outlook的方法
本案例python执行selenium需要使用最高权限运行,在此设定下无法启动Excel的VBA宏发送创建Outlook邮件实例。对应方案,创建两个计划任务,一个执行python提取数据,一个执行Excel的VBA加工和发送数据。以下为调用Excel的VBA示例
不需要勾选1:不管用户是否登录都要运行
不需要勾选2:使用最高权限运行
程序或脚本:"C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE"
添加参数:C:\autopsi\autotest.xlsm /e
VBA相关代码
Sub Workbook_Open()
Call sendmail
ThisWorkbook.Save
If Workbooks.Count = 1 Then
Application.Quit
Else
ThisWorkbook.Close
End If
End Sub
Public Sub sendmail()
strBody = "<span style=""font-family:MS UI Gothic"">" _
& "大家好:<br>" _
& "<br>" _
& "系统自动发信-无需回复</span>"
baseSubject = "测试邮件"
'Outlook定义
Set appOutlook = CreateObject("Outlook.Application")
Dim objMail As Outlook.MailItem
Set objMail = appOutlook.CreateItem(olMailItem)
' 收件人信息
topath = xxxx@xx.xx
With objMail
.BodyFormat = olFormatHTML
.Subject = baseSubject
.HTMLBody = strBody
.To = topath
.Send
End With
'释放对象
Set objMail = Nothing
End Sub
5.Python运行环境配置
根据Python中使用import导入的库,需要通过CMD命令依次进行安装
不用pyinstaller --onefile sample.py生成exe的原因,python.exe直接运行py文件比运行打包的exe文件速度快,提高调试速度。