调试代码
lure.py
import argparse
import sys
import time
import pandas as pd
from pandas import DataFrame
from selenium import webdriver
from selenium.webdriver.common.by import By
# 传值判断
if len(sys.argv) != 4:
sys.exit(1)
# 读取excel
df: DataFrame = pd.read_excel(sys.argv[3], sheet_name='Sheet1')
# Chrome浏览器
driver = webdriver.Chrome()
driver.get('网站')
time.sleep(1)
# By定位 内置账号密码登录
phone = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/div['
'1]/div/div[2]/input')
phone.send_keys(sys.argv[1])
driver.implicitly_wait(5)
password = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/div['
'2]/div/div/div[2]/input')
password.send_keys(sys.argv[2])
driver.implicitly_wait(5)
logon = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/a')
logon.click()
time.sleep(1)
# 进入页面
driver.get('网站')
# 切换到当前窗口
driver.switch_to.window(driver.window_handles[-1])
driver.implicitly_wait(5)
xm = []
sjh = []
c1 = 0
c2 = 0
for idx, row in df.iterrows():
xm = row['姓名']
sjh = row['手机号']
# 姓名
driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[1]/div/div/div/div[1]/form/div/div/div[1]/div['
'2]/div/div[2]/input').send_keys(xm)
time.sleep(0.3)
# 性别男
male = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[1]/div/div/div/div[1]/form/div/div/div['
'1]/div[3]/div[1]/div/div[2]/label[1]/span[2]')
driver.execute_script("arguments[0].click();", male)
time.sleep(0.2)
# 手机号类别
driver.find_element(By.CSS_SELECTOR,
'div > div > form > div > div > div > div:nth-child(4) > div.am-list-line > div '
'> div > label:nth-child(1) > span.am-radio:first-child').click()
driver.implicitly_wait(10)
time.sleep(0.2)
# 手机号
phone = driver.find_element(By.CSS_SELECTOR, 'div > div > form > div > div > div > '
'div.am-list-item.am-input-item.am-list-item-middle.add-customer-input'
'.undefined.add-customer-phone > div > div.am-input-control > input')
js1 = "arguments[0].scrollIntoView();"
driver.execute_script(js1, phone)
phone.send_keys(sjh)
time.sleep(0.2)
# 打开楼盘选择
driver.find_element(By.CSS_SELECTOR, 'div > div > form > div > div > div.am-list-item.am-list-item-middle > '
'div.am-list-line > div > div').click()
driver.implicitly_wait(3)
# 选择楼盘
driver.find_element(By.CSS_SELECTOR, '#divBuildingScroll > div > div:nth-child(3)').click()
driver.implicitly_wait(3)
time.sleep(1)
# 推荐
driver.find_element(By.CSS_SELECTOR, 'div > div > form > div > div > div > a').click()
time.sleep(1)
# 判断推荐是否成功
report = '报备成功'
failure1 = '推荐失败'
success = driver.find_elements(By.LINK_TEXT, '报备成功')
failure = driver.find_elements(By.LINK_TEXT, '推荐失败')
if success == report:
c1 = c1 + 1
data = {'结果': ['报备成功']}
else:
c2 = c2 + 1
data = {'结果': ['报备失败']}
data = pd.DataFrame(data)
# 将新数据与旧数据合并起来
data1 = pd.concat([df, data])
data1.to_excel(sys.argv[3], index=False)
# 继续推荐
driver.find_element(By.CSS_SELECTOR, 'div > div.report-done__btn.white.undefined').click()
driver.implicitly_wait(20)
# 传递参数
# 初始化参数构造器
parser = argparse.ArgumentParser()
# 在参数命令行添加两个命令行参数
parser.add_argument('--cc1', type=str, default=c1)
parser.add_argument('--cc2', type=str, default=c2)
# 获取所有命令行参数
args = parser.parse_args()
front.py
import sys
import subprocess
from tkinter import *
from lure import args
from tkinter import filedialog
def end():
sys.exit(0)
def select():
filename = filedialog.askopenfilename()
if filename != '':
path.set(filename)
def bring():
global b1, b2, b3
b1 = inp1.get()
b2 = inp2.get()
b3 = inp3.get()
subprocess.Popen(['python', 'lure.py', b1, b2, b3])
return None
# 图形化界面
root = Tk()
root.title('明源云客报备')
root.geometry('500x400')
path = StringVar()
a1 = StringVar()
a2 = StringVar()
b1, b2, b3 = None, None, None
lb1 = Label(root, text='账号', relief=RAISED)
lb1.place(relx=0.05, rely=0.1, relwidth=0.4, relheight=0.1)
inp1 = Entry(root, textvariable=a1)
inp1.place(relx=0.5, rely=0.1, relwidth=0.4, relheight=0.1)
lb2 = Label(root, text='密码', relief=RAISED)
lb2.place(relx=0.05, rely=0.25, relwidth=0.4, relheight=0.1)
inp2 = Entry(root, textvariable=a2)
inp2.place(relx=0.5, rely=0.25, relwidth=0.4, relheight=0.1)
inp3 = Entry(root, textvariable=path)
inp3.place(relx=0.5, rely=0.4, relwidth=0.4, relheight=0.1)
btn1 = Button(text='请选择源文件', command=select)
btn1.place(relx=0.05, rely=0.4, relwidth=0.4, relheight=0.1)
btn2 = Button(root, text='开始', command=bring)
btn2.place(relx=0.05, rely=0.55, relwidth=0.4, relheight=0.1)
btn3 = Button(root, text='结束', command=end)
btn3.place(relx=0.5, rely=0.55, relwidth=0.4, relheight=0.1)
txt = Text(root, relief=SUNKEN)
txt.insert(END, ('报备成功:' + str(args.cc1) + '组' + '\n' + '报备失败:' + str(args.cc2) + '组'))
txt.place(relx=0.05, rely=0.7, relwidth=0.85, relheight=0.25)
root.mainloop()
请求优化代码 使程序可以运行 谢谢
import sys
from subprocess import Popen,PIPE
from tkinter import *
# from lure import args
from tkinter import filedialog
def end():
sys.exit(0)
def select():
filename = filedialog.askopenfilename()
if filename != '':
path.set(filename)
def bring():
global b1, b2, b3
b1 = inp1.get()
b2 = inp2.get()
b3 = inp3.get()
p = Popen(['python', 'lure.py', b1, b2, b3],stdin=PIPE, stdout=PIPE,
stderr=PIPE, shell=True)
p.wait()
t = p.stdout
txt.insert(END, ('报备成功:' + str(t) + '组' + '\n' + '报备失败:' + str(t) + '组'))
return None
# 图形化界面
root = Tk()
root.title('明源云客报备')
root.geometry('500x400')
path = StringVar()
a1 = StringVar()
a2 = StringVar()
a1.set('博主的账户')
a2.set('博主的密码')
b1, b2, b3 = None, None, None
lb1 = Label(root, text='账号', relief=RAISED)
lb1.place(relx=0.05, rely=0.1, relwidth=0.4, relheight=0.1)
inp1 = Entry(root, textvariable=a1)
inp1.place(relx=0.5, rely=0.1, relwidth=0.4, relheight=0.1)
lb2 = Label(root, text='密码', relief=RAISED)
lb2.place(relx=0.05, rely=0.25, relwidth=0.4, relheight=0.1)
inp2 = Entry(root, textvariable=a2)
inp2.place(relx=0.5, rely=0.25, relwidth=0.4, relheight=0.1)
inp3 = Entry(root, textvariable=path)
inp3.place(relx=0.5, rely=0.4, relwidth=0.4, relheight=0.1)
btn1 = Button(text='请选择源文件', command=select)
btn1.place(relx=0.05, rely=0.4, relwidth=0.4, relheight=0.1)
btn2 = Button(root, text='开始', command=bring)
btn2.place(relx=0.05, rely=0.55, relwidth=0.4, relheight=0.1)
btn3 = Button(root, text='结束', command=end)
btn3.place(relx=0.5, rely=0.55, relwidth=0.4, relheight=0.1)
txt = Text(root, relief=SUNKEN)
txt.place(relx=0.05, rely=0.7, relwidth=0.85, relheight=0.25)
root.mainloop()
博主代码有一个致命问题,就是重复调用了lure文件
```python
from lure import args
```和
```python
subprocess.Popen(['python', 'lure.py', str(b1), str(b2), str(b3)])
```,这两个看似没有问题实则是导致问题的关键,你可参试用subprocess模块中的PIPE来开通与终端的交互,这样执行完后的结果与参数可以通过t = p.stdout来实现参数传递,但是博主的第二个脚本还存在一些问题,这里需要博主自行更改一下,这个部分其实并不困难,元素定位就行,然后本人直接舍弃了上面的from lure import args这个调用方法,从而使代码能够成功运行!
当然 p.wait()的阻塞也很关键,不然一样会出现闪退!
最后希望这些建议能够帮助到博主!
以下是针对lure.py代码进行的一些优化:
1.使用 with open() 语句读取 Excel 文件,可以更好地处理文件打开和关闭操作:
with open(sys.argv[3], 'rb') as f:
df: DataFrame = pd.read_excel(f, sheet_name='Sheet1')
2.在登录之前,先判断一下当前是否已经登录,若已经登录,则不需要再进行登录操作。这样可以避免重复登录,提高程序效率:
# 判断是否已经登录
if '登录' in driver.title:
# By定位 内置账号密码登录
phone = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/div['
'1]/div/div[2]/input')
phone.send_keys(sys.argv[1])
driver.implicitly_wait(5)
password = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/div['
'2]/div/div/div[2]/input')
password.send_keys(sys.argv[2])
driver.implicitly_wait(5)
logon = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/a')
logon.click()
time.sleep(1)
else:
driver.get('网站')
3.将 Excel 文件中的数据读取出来后,可以使用 to_dict() 函数把 DataFrame 转化为字典,然后通过迭代器方式逐行处理数据,避免了使用 iterrows() 等容易产生警告的方式:
# 读取Excel并转化为字典
data = pd.read_excel(sys.argv[3], sheet_name='Sheet1').to_dict('records')
for row in data:
xm = row['姓名']
sjh = row['手机号']
# 姓名
driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[1]/div/div/div/div[1]/form/div/div/div[1]/div['
'2]/div/div[2]/input').send_keys(xm)
...
4.在代码中尽量避免使用 time.sleep() 函数,可以使用 WebDriverWait() 等 Selenium 提供的显示等待方式,等待目标元素加载完成后再进行后续操作。这样可以提高程序效率和稳定性。
5.最后,对于 argparse 模块,可以加入一些命令行参数说明,方便其他人理解和使用程序。
# 初始化参数构造器
parser = argparse.ArgumentParser(description='自动批量推荐客户并记录结果')
# 在参数命令行添加两个命令行参数
parser.add_argument('--c1', type=int, default=0, help='报备成功数')
parser.add_argument('--c2', type=int, default=0, help='报备失败数')
# 获取所有命令行参数
args = parser.parse_args()
综上所述,针对该代码,需要进行的优化点包括:使用 with open() 语句读取文件、判断是否已经登录、迭代器方式逐行处理数据、使用显示等待方式等。
针对front.py代码进行的一些优化:
1.导入模块时,应该将他们放在同一个代码段中。如下所示:
import sys
import subprocess
from tkinter import *
from tkinter import filedialog
from lure import args
2.变量名需要有意义,不要使用单个字母作为变量名,可以使用具有描述性的名称,增加代码的可读性。
3.应当更换 subprocess.Popen 命令行方式调用代码的实现方式,使用 Python 内置的 import 的方式导入 lure.py 并直接执行其内部代码,这样可以避免使用 subprocess.Popen 的启动时间并减少运行时间。
4.在 bring() 函数中,不要使用全局变量 b1, b2, b3,而应该使用函数参数代替。
5.在 txt 中,使用 args.c1 和 args.c2 表示 --c1 和 --c2 这两个命令行参数的值,并将它们添加到 txt 控件中。
6.适当添加注释,加强代码可读性。
以下是经过优化后的代码:
# 导入所需的模块
import sys
import subprocess
from tkinter import *
from tkinter import filedialog
from lure import args
def end():
# 退出程序
sys.exit(0)
def select():
# 选择文件
filename = filedialog.askopenfilename()
if filename != '':
path.set(filename)
def bring(b1, b2, b3):
# 执行程序
import lure
lure.main(b1, b2, b3)
# 图形化界面
root = Tk()
root.title('明源云客报备')
root.geometry('500x400')
# 定义字符串变量
path = StringVar()
a1 = StringVar()
a2 = StringVar()
# 设置标签等控件
lb1 = Label(root, text='账号', relief=RAISED)
lb1.place(relx=0.05, rely=0.1, relwidth=0.4, relheight=0.1)
inp1 = Entry(root, textvariable=a1)
inp1.place(relx=0.5, rely=0.1, relwidth=0.4, relheight=0.1)
lb2 = Label(root, text='密码', relief=RAISED)
lb2.place(relx=0.05, rely=0.25, relwidth=0.4, relheight=0.1)
inp2 = Entry(root, textvariable=a2)
inp2.place(relx=0.5, rely=0.25, relwidth=0.4, relheight=0.1)
inp3 = Entry(root, textvariable=path)
inp3.place(relx=0.5, rely=0.4, relwidth=0.4, relheight=0.1)
btn1 = Button(text='请选择源文件', command=select)
btn1.place(relx=0.05, rely=0.4, relwidth=0.4, relheight=0.1)
btn2 = Button(root, text='开始', command=lambda: bring(a1.get(), a2.get(), path.get()))
btn2.place(relx=0.05, rely=0.55, relwidth=0.4, relheight=0.1)
btn3 = Button(root, text='结束', command=end)
btn3.place(relx=0.5, rely=0.55, relwidth=0.4, relheight=0.1)
txt = Text(root, relief=SUNKEN)
txt.insert(END, ('报备成功:' + str(args.c1) + '组' + '\n' + '报备失败:' + str(args.c2) + '组'))
txt.place(relx=0.05, rely=0.7, relwidth=0.85, relheight=0.25)
root.mainloop()
综上所述,在对该代码进行优化时,需要注意的问题包括:导入模块应该放在同一个代码段中、变量名需要有意义、更换 subprocess.Popen 命令行方式调用代码的实现方式、使用 Python 内置的 import 的方式导入 lure.py 并直接执行其内部代码、在 bring() 函数中应使用参数代替全局变量等。
LURE
pandas.read_excel()
方法读取Excel文件时,需要使用文件的绝对路径,而不是相对路径。find_elements()
方法查找元素时,返回的是一个列表,需要使用len()
函数获取列表长度,然后才能进行判断。data
,而不是旧的数据框对象df
。FRONT
args
模块,但是没有导入该模块。Button
对象没有设置父控件,应该将其设置为root
。subprocess.Popen()
方法时,应该先将b1
、b2
、b3
转换为字符串类型,否则会出现类型错误。txt.insert()
方法向Text
对象中插入文本时,应该先清空原来的文本内容,否则会出现重复的文本。你试一试这么修改:
import sys
import subprocess
from tkinter import *
from tkinter import filedialog
from lure import args
def end():
sys.exit(0)
def select():
filename = filedialog.askopenfilename()
if filename != '':
path.set(filename)
def bring():
global b1, b2, b3
b1 = inp1.get()
b2 = inp2.get()
b3 = inp3.get()
subprocess.Popen(['python', 'lure.py', str(b1), str(b2), str(b3)])
return None
# 图形化界面
root = Tk()
root.title('明源云客报备')
root.geometry('500x400')
path = StringVar()
a1 = StringVar()
a2 = StringVar()
b1, b2, b3 = None, None, None
lb1 = Label(root, text='账号', relief=RAISED)
lb1.place(relx=0.05, rely=0.1, relwidth=0.4, relheight=0.1)
inp1 = Entry(root, textvariable=a1)
inp1.place(relx=0.5, rely=0.1, relwidth=0.4, relheight=0.1)
lb2 = Label(root, text='密码', relief=RAISED)
lb2.place(relx=0.05, rely=0.25, relwidth=0.4, relheight=0.1)
inp2 = Entry(root, textvariable=a2)
inp2.place(relx=0.5, rely=0.25, relwidth=0.4, relheight=0.1)
inp3 = Entry(root, textvariable=path)
inp3.place(relx=0.5, rely=0.4, relwidth=0.4, relheight=0.1)
btn1 = Button(root, text='请选择源文件', command=select)
btn1.place(relx=0.05, rely=0.4, relwidth=0.4, relheight=0.1)
btn2 = Button(root, text='开始', command=bring)
btn2.place(relx=0.05, rely=0.55, relwidth=0.4, relheight=0.1)
btn3 = Button(root, text='结束', command=end)
btn3.place(relx=0.5, rely=0.55, relwidth=0.4, relheight=0.1)
txt = Text(root, relief=SUNKEN)
txt.delete(1.0, END) # 清空原来的文本内容
txt.insert(END, ('报备成功:' + str(args.cc1) + '组' + '\\n' + '报备失败:' + str(args.cc2) + '组'))
txt.place(relx=0.05, rely=0.7, relwidth=0.85, relheight=0.25)
root.mainloop()
read_excel要用绝对路径,不能用相对路径
可以参考网上的例子改。百度pandas有很多资料的
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在你提供的代码中存在以下几个问题:
df.iterrows()
返回的是(index, Series)
的元组,需要使用拆包操作,将其拆分成idx
和row
两个变量;success == report
应该改为success.text == report
,同理failure.text == failure1
;parser.add_argument()
中的参数类型应该是int
,而不是str
;args.cc1
和args.cc2
获取参数值,而不是直接使用c1
和c2
。下面是修改后的代码:
lure.py:
import argparse
import sys
import time
import pandas as pd
from pandas import DataFrame
from selenium import webdriver
from selenium.webdriver.common.by import By
# 传值判断
if len(sys.argv) != 4:
sys.exit(1)
# 读取excel
df: DataFrame = pd.read_excel(sys.argv[3], sheet_name='Sheet1')
# Chrome浏览器
driver = webdriver.Chrome()
driver.get('网站')
time.sleep(1)
# By定位 内置账号密码登录
phone = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/div['
'1]/div/div[2]/input')
phone.send_keys(sys.argv[1])
driver.implicitly_wait(5)
password = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/div['
'2]/div/div/div[2]/input')
password.send_keys(sys.argv[2])
driver.implicitly_wait(5)
logon = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div/div/div/div/div[2]/div[1]/div/a')
logon.click()
time.sleep(1)
# 进入页面
driver.get('网站')
# 切换到当前窗口
driver.switch_to.window(driver.window_handles[-1])
driver.implicitly_wait(5)
xm = []
sjh = []
c1 = 0
c2 = 0
for idx, row in df.iterrows():
xm, sjh = row['姓名'], row['手机号']
# 姓名
driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[1]/div/div/div/div[1]/form/div/div/div[1]/div['
'2]/div/div[2]/input').send_keys(xm)
time.sleep(0.3)
# 性别男
male = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[1]/div/div/div/div[1]/form/div/div/div['
'1]/div[3]/div[1]/div/div[2]/label[1]/span[2]')
driver.execute_script("arguments[0].click();", male)
time.sleep(0.2)
# 手机号类别
driver.find_element(By.CSS_SELECTOR,
'div > div > form > div > div > div > div:nth-child(4) > div.am-list-line > div '
'> div > label:nth-child(1) > span.am-radio:first-child').click()
driver.implicitly_wait(10)
time.sleep(0.2)
# 手机号
phone = driver.find_element(By.CSS_SELECTOR, 'div > div > form > div > div > div > '
'div.am-list-item.am-input-item.am-list-item-middle.add-customer-input'
'.undefined.add-customer-phone > div > div.am-input-control > input')
js1 = "arguments[0].scrollIntoView();"
driver.execute_script(js1, phone)
phone.send_keys(sjh)
time.sleep(0.2)
# 打开楼盘选择
driver.find_element(By.CSS_SELECTOR, 'div > div > form > div > div > div.am-list-item.am-list-item-middle > '
'div.am-list-line > div > div').click()
driver.implicitly_wait(3)
# 选择楼盘
driver.find_element(By.CSS_SELECTOR, '#divBuildingScroll > div > div:nth-child(3)').click()
driver.implicitly_wait(3)
time.sleep(1)
# 推荐
driver.find_element(By.CSS_SELECTOR, 'div > div > form > div > div > div > a').click()
time.sleep(1)
# 判断推荐是否成功
report = '报备成功'
failure1 = '推荐失败'
success = driver.find_elements(By.LINK_TEXT, '报备成功')
failure = driver.find_elements(By.LINK_TEXT, '推荐失败')
if success and success[0].text == report:
c1 = c1 + 1
data = {'结果': ['报备成功']}
else:
c2 = c2 + 1
data = {'结果': ['报备失败']}
data = pd.DataFrame(data)
# 将新数据与旧数据合并起来
data1 = pd.concat([df, data])
data1.to_excel(sys.argv[3], index=False)
# 继续推荐
driver.find_element(By.CSS_SELECTOR, 'div > div.report-done__btn.white.undefined').click()
driver.implicitly_wait(20)
# 传递参数
# 初始化参数构造器
parser = argparse.ArgumentParser()
# 在参数命令行添加两个命令行参数
parser.add_argument('--cc1', type=int, default=c1)
parser.add_argument('--cc2', type=int, default=c2)
# 获取所有命令行参数
args = parser.parse_args()
front.py:
import sys
import subprocess
from tkinter import *
from lure import args
from tkinter import filedialog
def end():
sys.exit(0)
def select():
filename = filedialog.askopenfilename()
if filename != '':
path.set(filename)
def bring():
global b1, b2, b3
b1 = inp1.get()
b2 = inp2.get()
b3 = inp3.get()
subprocess.Popen(['python', 'lure.py', b1, b2, b3])
return None
# 图形化界面
root = Tk()
root.title('明源云客报备')
root.geometry('500x400')
path = StringVar()
a1 = StringVar()
a2 = StringVar()
b1, b2, b3 = None, None, None
lb1 = Label(root, text='账号', relief=RAISED)
lb1.place(relx=0.05, rely=0.1, relwidth=0.4, relheight=0.1)
inp1 = Entry(root, textvariable=a1)
inp1.place(relx=0.5, rely=0.1, relwidth=0.4, relheight=0.1)
lb2 = Label(root, text='密码', relief=RAISED)
lb2.place(relx=0.05, rely=0.25, relwidth=0.4, relheight=0.1)
inp2 = Entry(root, textvariable=a2)
inp2.place(relx=0.5, rely=0.25, relwidth=0.4, relheight=0.1)
inp3 = Entry(root, textvariable=path)
inp3.place(relx=0.5, rely=0.4, relwidth=0.4, relheight=0.1)
btn1 = Button(text='请选择源文件', command=select)
btn1.place(relx=0.05, rely=0.4, relwidth=0.4, relheight=0.1)
btn2 = Button(root, text='开始', command=bring)
btn2.place(relx=0.05, rely=0.55, relwidth=0.4, relheight=0.1)
btn3 = Button(root, text='结束', command=end)
btn3.place(relx=0.5, rely=0.55, relwidth=0.4, relheight=0.1)
txt = Text(root, relief=SUNKEN)
txt.insert(END, ('报备成功:' + str(args.cc1) + '组' + '\n' + '报备失败:' + str(args.cc2) + '组'))
txt.place(relx=0.05, rely=0.7, relwidth=0.85, relheight=0.25)
root.mainloop()
如果我的回答解决了您的问题,请采纳!