需求
批量验证和添加手机号码为企业微信账号的联系人
源码
import tkinter as tk import pyautogui as pg import tkinter.messagebox as msgbox def setpos(): global x,y try: x,y = eval(tEntry.get()) except: pass pg.click(x-150,y) pg.typewrite('1') pg.moveTo(x,y,duration=0.5) def alter(num): tList.delete(index) tList.insert(index,phone+','+str(num)) user[index] = phone+','+str(num) with open("phones.txt","w",encoding="utf-8") as f: f.write('\n'.join(user)) def flag0(): alter(0) def flag1(): alter(1) def flag2(): alter(2) def start(): global x,y,index,phone x0,y0 = pg.position() lines = len(user) index = -1 for i in user: index += 1 if len(i)==11:break phone = user[index] if len(phone)>11: msgbox.showinfo('提示','手机号大于11位,或全部结束!') else: try: t = tList.curselection()[0] tList.select_clear(t,t) except: pass tList.select_set(index,index) pg.click(x-150,y) pg.typewrite('\b'*50) pg.typewrite(phone) pg.moveTo(x,y,duration=0.5) pg.click() pg.moveTo(x0,y0) def main(): '''written by hannyang 2021.10.16''' global tEntry,tList global user root = tk.Tk() root.geometry(f'375x323+{x+55}+{y-85}') root.resizable(False, False) root.title('《企业微信好友》') root.wm_attributes('-topmost',True) tEntry = tk.Entry(root,width=8) tEntry.place(x = 275, y = 270) tEntry.insert(0,'995,410') bt1 = tk.Button(root,text=' 定位 ',command = setpos) bt1.place(x = 220, y = 265) bt2 = tk.Button(root,text=' 开始 ',command = start) bt2.place(x = 30, y = 265) bt3 = tk.Button(root,text=' 标0 ',command = flag0) bt3.place(x = 80, y = 265) bt4 = tk.Button(root,text=' 标1 ',command = flag1) bt4.place(x = 125, y = 265) bt5 = tk.Button(root,text=' 标2 ',command = flag2) bt5.place(x = 170, y = 265) user = [] try: with open('phones.txt', 'r', encoding='utf-8') as fn: users = fn.readlines() for usr in users: if usr[-1]=='\n': usr=usr[:-1] user.append(usr.strip()) except: user = ['当前文件夹中phones.txt文件不存在!'] tScroll=tk.Scrollbar(root, orient=tk.VERTICAL) tScroll.place(x=330,y=25,height=220) tList=tk.Listbox(root,selectmode=tk.BROWSE,yscrollcommand=tScroll.set) tList.place(x=30,y=25,width=300,height=220) for i in user: tList.insert(tk.END,i) tScroll.config(command=tList.yview) tList.select_set(0,0) root.update() tmp = list(set(user)) diff = len(user)-len(tmp) if diff!=0: msgbox.showinfo('提示',f'存在{diff}个重复手机号!可忽略') root.mainloop() if __name__ == '__main__': x,y = pg.size() x = (x - 390)//2 + 350 y = (y - 360)//2 + 65 main()
注:代码倒数两三行中,390,360是被点窗口的大小,350,65用于定位坐标。
以下是保存电话的文本文件 phones.txt 的内容,手机号码已隐去:
运行
程序没有设置全自动的验证和添加,如果需要的话,则要把相关的按钮截图保存好.png图片,然后使用 pyautogui.locateCenterOnScreen() 等函数来定位,加上循环语句就能达成。
一起学习交流 Python 的群二维码地址: http://qr01.cn/FHYKEa
附录: PyAutoGUI
PyAutoGUI是一个Python语言的键鼠自动化库,简单来说和按键精灵的功能一样。但是因为是Python的类库,所以可以使用Python代码配合一些其他类库完成更加强大的功能。
PyAutoGUI使用x,y坐标,屏幕左上角坐标是(0, 0)。
鼠标操作函数
操作鼠标点击的函数。
键盘操作函数
操作键盘按键的函数。
提示框函数
PyAutoGUI可以显示提示框,这时候程序会暂停运行,直到用户点击提示框。
屏幕截图和定位函数
截取屏幕的函数,也可以从屏幕中寻找匹配的图片,并返回其坐标。你可以事先保存一些按钮的截图,然后通过这种方式定位按钮的位置,然后点击。
移动鼠标
moveTo函数,绝对坐标
鼠标顺时针移动,并划10次方框
import pyautogui for i in range(10): pyautogui.moveTo(300, 300, duration=0.25) pyautogui.moveTo(400, 300, duration=0.25) pyautogui.moveTo(400, 400, duration=0.25) pyautogui.moveTo(300, 400, duration=0.25)
划圆:
import pyautogui import math width, height = pyautogui.size() r = 250 # 圆的半径 # 圆心 o_x = width/2 o_y = height/2 pi = 3.1415926 for i in range(10): # 转10圈 for angle in range(0, 360, 5): # 利用圆的参数方程 X = o_x + r * math.sin(angle*pi/180) Y = o_y + r * math.cos(angle*pi/180) pyautogui.moveTo(X, Y, duration=0.1) moveRel()函数,相对坐标。以当前鼠标所在位置为基点: import pyautogui for i in range(10): pyautogui.moveRel(100, 0, duration=0.25) pyautogui.moveRel(0, 100, duration=0.25) pyautogui.moveRel(-100, 0, duration=0.25) pyautogui.moveRel(0, -100, duration=0.25)
获得鼠标所在坐标:
import pyautogui x, y = pyautogui.position()
实时获得鼠标位置坐标:
import pyautogui try: while True: x, y = pyautogui.position() print(x,y) except KeyboardInterrupt: print('\nExit.')
鼠标点击、拖拽和滚轮
鼠标点击
使用click()函数发送虚拟鼠标点击,默认情况下在鼠标所在的位置点击左键。函数原型:
pyautogui.click(x=cur_x, y=cur_y, button='left')
x,y是要点击的位置,默认是鼠标当前位置
button是要点击的按键,有三个可选值:‘left’, ‘middle’, ‘right’
要在当前位置点击右键:
import pyautogui
pyautogui.click(button='right')
click函数完成了一次鼠标点击。一次完整的点击包括两部分,按下mouseDown()和弹起mouseUp()。上面这两个函数参数和click函数一样,其实click函数只是简单的封装了mouseDown()和mouseUp()函数。
import pyautogui
pyautogui.click(100, 100)
每个按键按下和松开两个事件可以分开处理:
pyautogui.mouseDown(x=moveToX, y=moveToY, button='left')
pyautogui.mouseUp(x=moveToX, y=moveToY, button='left')
pyautogui.doubleClick():鼠标双击,其实就是执行两次click()函数。
pyautogui.rightClick():右击
pyautogui.middleClick():中击
鼠标拖拽
拖拽的意思是:按下鼠标键并拖动鼠标。PyAutoGUI提供了两个函数:dragTo() 和 dragRel()。它的参数和moveTo() 和 moveRel() 一样。
注意:duration时间不能太短,拖动太快有些系统会吃不消。
要做多次单击可以设置clicks参数,还有interval参数可以设置每次单击之间的时间间隔。例如:
# 双击左键
pyautogui.click(clicks=2)
# 两次单击之间停留0.25秒
pyautogui.click(clicks=2, interval=0.25)
# 三击右键
pyautogui.click(button='right', clicks=2, interval=0.25)
滚轮
使用函数scroll(),它只接受一个整数。如果值为正往上滚,值为负往下滚。
pyautogui.scroll(200)
定位某个按钮的位置
pyautogui有截屏功能
# 返回一个Pillow/PIL的Image对象
pyautogui.screenshot()
pyautogui.screenshot('foo.png')
如果你不需要截取整个屏幕,还有一个可选的region参数。你可以把截取区域的左上角XY坐标值和宽度、高度传入截取。
im = pyautogui.screenshot(region=(0, 0, 300 ,400))
假如你有一个按钮要10秒种点击一下,这个任务使用上面介绍的函数可以轻松实现。但是我们假设你每次点击这个按钮它都会变换一个位置(随机),这时你该怎么办?下面我们就来解决这个问题。
首先看一下怎么使用pyautogui截屏:
import pyautogui
im = pyautogui.screenshot()
# 获得某个坐标的像素
im.getpixel((50, 200))
# (30, 132, 153)
# 判断屏幕坐标的像素是不是等于某个值
pyautogui.pixelMatchesColor(50, 200, (30, 132, 153))
# True
现在我们来解决前面提出的问题。问题的关键是怎么找到按钮所在的坐标。其实很简单,首先对你要点击的按钮截个图,就叫button.png吧。然后使用locateOnScreen函数找到按钮所在的位置:
import pyautogui
pyautogui.locateOnScreen('button.png')
# (643, 745, 70, 29)
locateOnScreen其实就是简单的颜色对比,如果有一个像素不匹配,它就会返回None。这个函数返回了匹配图形的坐标,找到中间点:
x, y = pyautogui.center((643, 745, 70, 29)) # 获得中心点
pyautogui.click(x, y)
locateAllOnScreen():找到所有匹配的位置坐标。
要检查XY坐标是否在屏幕上,需要用onScreen()函数来检验,如果在屏幕上返回True:
import pyautogui
pyautogui.onScreen(0, 0)
# True
pyautogui.onScreen(0, -1)
#False
缓动/渐变(Tween / Easing)函数
缓动/渐变函数的作用是让光标的移动更炫。如果你不需要用到的话,你可以忽略这些。
缓动/渐变函数可以改变光标移动过程的速度和方向。通常鼠标是匀速直线运动,这就是线性缓动/渐变函数。PyAutoGUI有30种缓动/渐变函数,可以通过pyautogui.ease*?查看。其中,pyautogui.easeInQuad()函数可以用于moveTo(),moveRel(),dragTo()和dragRel()函数,光标移动呈现先慢后快的效果,整个过程的时间还是和原来一样。而pyautogui.easeOutQuad函数的效果相反:光标开始移动很快,然后慢慢减速。pyautogui.easeOutElastic是弹簧效果,首先越过终点,然后再反弹回来。例如:
# 开始很慢,不断加速
pyautogui.moveTo(100, 100, 2, pyautogui.easeInQuad)
# 开始很快,不断减速
pyautogui.moveTo(100, 100, 2, pyautogui.easeOutQuad)
# 开始和结束都快,中间比较慢
pyautogui.moveTo(100, 100, 2, pyautogui.easeInOutQuad)
# 一步一徘徊前进
pyautogui.moveTo(100, 100, 2, pyautogui.easeInBounce)
# 徘徊幅度更大,甚至超过起点和终点
pyautogui.moveTo(100, 100, 2, pyautogui.easeInElastic)
这些效果函数是模仿Al Sweigart的PyTweening模块,可以直接使用,不需要额外安装。
如果你想创建自己的效果,也可以定义一个函数,其参数是(0.0,1.0),表示起点和终点,返回值是介于[0.0,1.0]之间的数。
键盘按键
输入字符串
pyautogui.typewrite(): import pyautogui pyautogui.click(100, 100) pyautogui.typewrite('Hello world!')
上面的字符串是一次输入,为了唬人可以延迟输入:
pyautogui.typewrite('Hello world!', 0.25)
PyAutoGUI输入单个字符还可以,但是一些特殊字符怎么办呢?例如上面输入完Hello World,然后换行继续输入。
PyAutoGUI键盘表:
‘enter’(或‘return’ 或 ‘\n’) 回车
‘esc’ ESC键
‘shiftleft’, ‘shiftright’ 左右SHIFT键
‘altleft’, ‘altright’ 左右ALT键
‘ctrlleft’, ‘ctrlright’ 左右CTRL键
‘tab’ (‘\t’) TAB键
‘backspace’, ‘delete’ BACKSPACE 、DELETE键
‘pageup’, ‘pagedown’ PAGE UP 和 PAGE DOWN键
‘home’, ‘end’ HOME 和 END键
‘up’, ‘down’, ‘left’,‘right’ 箭头键
‘f1’, ‘f2’, ‘f3’…. F1…….F12键
‘volumemute’, ‘volumedown’,‘volumeup’ 有些键盘没有
‘pause’ PAUSE键
‘capslock’, ‘numlock’,‘scrolllock’ CAPS LOCK, NUM LOCK, 和 SCROLLLOCK 键
‘insert’ INS或INSERT键
‘printscreen’ PRTSC 或 PRINT SCREEN键
‘winleft’, ‘winright’ Win键
‘command’ Mac OS X command键
import pyautogui pyautogui.click(100, 100) pyautogui.typewrite('Hello world!', 0.25) pyautogui.typewrite(['enter', 'a', 'b', 'left', 'left', 'X', 'Y'], '0.25')
按键的按下和释放 和鼠标按键非常类似。
keyDown():按下某个键
keyUp():松开某个键
press():一次完整的击键,前面两个函数的组合。
alt+F4:
pyautogui.keyDown('altleft'); pyautogui.press('f4'); pyautogui.keyUp('altleft')
直接使用热键函数:
pyautogui.hotkey('altleft', 'f4')
每个按键的按下和松开也可以单独调用:
pyautogui.keyDown(key_name)
pyautogui.keyUp(key_name)
消息弹窗函数
如果你需要消息弹窗,通过单击OK暂停程序,或者向用户显示一些信息,消息弹窗函数就会有类似JavaScript的功能:
pyautogui.alert('这个消息弹窗是文字+OK按钮')
pyautogui.confirm('这个消息弹窗是文字+OK+Cancel按钮')
pyautogui.prompt('这个消息弹窗是让用户输入字符串,单击OK')
在prompt()函数中,如果用户什么都不输入,就会返回None。