import pywinauto
from pywinauto.application import Application
from pywinauto.keyboard import *
import os
import sys
import time
from win32con import WM_INPUTLANGCHANGEREQUEST
import win32gui
import win32api
from ctypes.wintypes import tagPOINT
import pywinauto
class Tools(object):
@staticmethod
def set_english_inputer():
# 0x0409为英文输入法的lid_hex的 中文一般为0x0804
hwnd = win32gui.GetForegroundWindow()
# title = win32gui.GetWindowText(hwnd)
# im_list = win32api.GetKeyboardLayoutList()
# print(im_list)
# im_list = list(map(hex, im_list))
# print(im_list)
result = win32api.SendMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, 0x8040804)
if result == 0:
print("英文输入法切换成功!")
@staticmethod
def readtxt(filename, s_str = ",", isprint = False):
wxlist = []
with open(filename,"r", encoding="utf-8") as f:
while True:
line = f.readline()
if line == "": break
wxline = line.split(s_str) # , \t
wxlist.append(wxline)
if isprint:
print(wxline)
print("\n")
return wxlist
@staticmethod
def saveTxt(filename, data):
with open(filename, 'a', encoding="utf-8") as f:
f.write(data)
print(sys._getframe().f_lineno, filename,":",data)
class WxObject(object):
ok = 1
err = 0
exit = 2
def __init__(self):
self.win = ""
self.page = {u'呢称': '', u'备 注': '', u'地 区': '', u'微信号': '', u'来 源': ''}
# 连接 微信
def _connect_wx(self):
# 连接微信
try:
self.app = Application(backend='uia').connect(path="C:\Program Files (x86)\Tencent\WeChat\WeChat.exe")
if not self.app.微信.is_normal():
self.app.微信.restore()
except:
self.app = Application(backend='uia').start(r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe")
time.sleep(2)
self.app.微信.登录.click_input(button="left")
self.app.微信.wait("visible")
self.app.微信.通讯录.wait('visible',timeout=300)
self.win = self.app[u'微信']
self.win.draw_outline()
# 单击 通讯录 按钮
def _click_address(self): # 点击通讯录
# 找到通讯录点击--> 在点击右边联系人
self.addresslist = self.app[u"微信"][u"通讯录"]
self.addresslist.click_input(button='left')
self.coords = self.addresslist.rectangle()
# 搜索框 输入联系人
def _wx_search(self, search_str):
#搜索,输入昵称
try: #微信电脑客户端升级,可能会变
search_edit = self.win.child_window(title=u"搜索", control_type="Edit")
except:
print(sys._getframe().f_lineno, "搜索框的标识没有找到!")
sys.exit()
search_edit.click_input(button="left")
Tools.set_english_inputer()
search_edit.type_keys(search_str)
time.sleep(1)
# 得到 搜索结果
def _search_ret_items(self):
found_list = [] # 定义找到的联系人列表
try:
con_list = self.win.child_window(title=u"搜索结果", control_type="List") # 联系人
except:
print(sys._getframe().f_lineno, "搜索结果的标识没有找到!")
sys.exit()
time.sleep(1)
item_list = con_list.children() # 搜索结果的所有item项
item_num = len(item_list)
print(sys._getframe().f_lineno, "打印搜索结果:",item_num, "行", item_list)
if item_list[0].friendly_class_name()!= "Pane":
print(sys._getframe().f_lineno, "搜索结果:第一行不是标签项,返回空值")
return []
for i in range(1, item_num): # 第二项开始 项类属性为"ListItem",则是匹配到的联系人
if item_list[i].friendly_class_name() == "ListItem":
if item_list[i].window_text()[0:3] == "搜一搜":
return found_list
found_list.append(item_list[i])
print(item_list[i].window_text())
else:
break
print(sys._getframe().f_lineno, "找到几个?:", len(found_list), found_list, "\n")
return found_list
def _search_ret_items_wait(self,filename = "search_ret.txt", wait_time=10):
found_list = [] # 定义找到的联系人列表
try:
con_list = self.win.child_window(title=u"搜索结果", control_type="List") # 联系人
except:
print(sys._getframe().f_lineno, "搜索结果的标识没有找到!")
sys.exit()
time.sleep(wait_time)
item_list = con_list.children() # 搜索结果的所有item项
item_num = len(item_list)
print(sys._getframe().f_lineno, "打印搜索结果:",item_num, "行", item_list)
if item_list[0].friendly_class_name()!= "Pane":
print(sys._getframe().f_lineno, "搜索结果:第一行不是标签项,返回空值")
return []
for i in range(1, item_num): # 第二项开始 项类属性为"ListItem",则是匹配到的联系人
if item_list[i].friendly_class_name() == "ListItem":
if item_list[i].window_text()[0:3] == "搜一搜":
return found_list
found_list.append(item_list[i])
print(item_list[i].window_text())
Tools.saveTxt(filename, item_list[i].window_text()+"\n")
else:
break
print(sys._getframe().f_lineno, "找到几个?:", len(found_list), "\n")
def _next(self, num=1): # 下一个联系人
win = self.win
self._click_address() # 单击通讯录
titel_str = self.page['备 注']
if titel_str == "点击添加备注" or self.page['备 注'] == "":
titel_str = self.page['呢称']
lxr = self.win.child_window(title=u"%s" % titel_str, control_type="ListItem")
# 点击上次联系人
lxr.click_input(button='left')
while num:
send_keys("{VK_DOWN}")
# self.lxr.type_keys("{DOWN}")
num -= 1
# 循环往下 发消息
def next_send(self, sendinfo): # 发送消息
# 连接微信
self._connect_wx()
# 点击 联系人
pywinauto.mouse.click(button="left", coords=(self.coords.left + 150, self.coords.top + 20))
while True: # 循环读取资料、发送消息
if self. _by_address_get_wxinfo():
# 点击-发消息
self.app.微信.发消息.click_input(button='left')
# 发送消息内容
self._send_info_edit(sendinfo)
self._next()
else:
self._next(2) # 发送消息,此条取消注释
def _write_address_txt(self, filename, header=False): # 把通讯录写入文件
page = self.page
with open(filename, 'a', encoding='utf-8') as f:
if header:
f.write(u'微信号,备注,地区,来源,呢称\r')
else:
f.write(
'%s,%s,%s,%s,%s\r' % (page[u'微信号'], page[u'备 注'], page[u'地 区'], page[u'来 源'], page[u'呢称']))
def _by_address_get_wxinfo(self): # 读联系人资料
win = self.win
self.page[u'呢称'] = ""
self.page[u'备 注'] = ""
self.page[u'地 区'] = ""
self.page[u'来 源'] = ""
try:
static_wxh = win.child_window(title=u"微信号", control_type="Text") # 获取 静态微信号控件
if static_wxh.window_text() != "微信号":
return WxObject.err
Pane = static_wxh.parent().parent() # 获取详情
for item in Pane.children():
item.draw_outline()
lines = item.children()
key = lines[0].window_text()
value = lines[1].window_text()
if key == "微信号" and value ==self.page[key]:
return WxObject.exit
self.page[key] = value
except:
time.sleep(3)
return WxObject.err
nick_edit = win.Edit2 # 获取呢称控件
nick_name = nick_edit.get_value()
self.page['呢称'] = nick_name
print(self.page)
return WxObject.ok
# 读的文件,最后一列是修改列
def _click_lxr_item(self, filename, exefunc, okfile="ret_ok.txt", errfile="ret_err.txt"):
# 连接微信
self._connect_wx()
# 读需要修改的文件
wxlist = Tools.readtxt(filename, isprint=True)
# 循环读取资料、发送消息
for wxline in wxlist:
self.cols = len(wxline)
# 1.打印 更新内容
print(sys._getframe().f_lineno, self.cols, wxline)
ret_detile = ""
# 2. 循环搜索 微信号,备注, 呢称
for i in range(0, self.cols - 1):
print(sys._getframe().f_lineno, i, "搜索:", wxline[i])
try:
# 2.1 搜索
if wxline[i] == "":
continue
self._wx_search(wxline[i])
print(sys._getframe().f_lineno, "搜索结束,往下得到搜索结果!")
# 2.2 返回搜索结果项
items = self._search_ret_items()
# 2.3 结果项为1
if len(items) == 1:
# 2.3.1 单击 选中的联系人项
items[0].click_input(button="left")
# 2.3.2 修改 备注内容
# print(sys._getframe().f_lineno, exefunc)
eval(exefunc) # 微信号,修改内容
break # 跳出循环,继续下一条。
# 2.4 结果项不为1
else:
self.app.微信.清空.click_input(button="left")
ret_detile = ret_detile + wxline[i] + " 匹配到:" + str(len(items)) + "个\n"
except:
Tools.saveTxt(errfile, "搜索时,出错异常!!!****************\n")
Tools.saveTxt(errfile, ",".join(wxline)+ "\n")
if not self.app.微信.is_active():
break
self.app.微信.通讯录.click_input(button="left")
# 3.循环结束,结果项都不为1
else:
print(sys._getframe().f_lineno, wxline, ":搜索:没找到,或匹配到多个项:", ret_detile)
Tools.saveTxt(errfile, ret_detile)
# 读的文件,最后一列不是修改列
def _click_lxr_item2(self, filename, exefunc, okfile="ret_ok.txt", errfile="ret_err.txt"):
# 连接微信
self._connect_wx()
# 读需要修改的文件
wxlist = Tools.readtxt(filename, isprint=True)
# 循环读取资料、发送消息
for wxline in wxlist:
self.cols = len(wxline)
# 1.打印 更新内容
print(sys._getframe().f_lineno, self.cols, wxline)
ret_detile = ""
# 2. 循环搜索 微信号,备注, 呢称
for i in range(0, self.cols):
print(sys._getframe().f_lineno, i, "搜索:", wxline[i])
try:
# 2.1 搜索
if wxline[i] == "":
continue
self._wx_search(wxline[i])
print(sys._getframe().f_lineno, "搜索结束,往下得到搜索结果!")
# 2.2 返回搜索结果项
items = self._search_ret_items()
# 2.3 结果项为1
if len(items) == 1:
# 2.3.1 单击 选中的联系人项
items[0].click_input(button="left")
# 2.3.2 修改 备注内容
try:
eval(exefunc) # 微信号,修改内容
except:
print(sys._getframe().f_lineno, exefunc, "\neval(exefunc)调用错误!")
break # 跳出循环,继续下一条。
# 2.4 结果项不为1
else:
self.app.微信.清空.click_input(button="left")
ret_detile = ret_detile + wxline[i] + " 匹配到:" + str(len(items)) + "个\n"
except:
print(sys._getframe().f_lineno, "搜索时,出错异常!!!****************\n")
Tools.saveTxt(errfile, "搜索时,出错异常!!!****************\n")
Tools.saveTxt(errfile, ",".join(wxline)+ "\n")
if not self.app.微信.is_active():
break
self.app.微信.通讯录.click_input(button="left")
# 3.循环结束,结果项都不为1
else:
print(sys._getframe().f_lineno, wxline, ":搜索:没找到,或匹配到多个项:", ret_detile)
Tools.saveTxt(errfile, ret_detile)
def _memo_chang_verify_wxh(self, wxh, editstr, wxline, okfile, errfile): # 修改备注
# 聊天信息
self.app.微信.聊天信息.click_input(button="left")
# 添加按钮
addbtn = self.win.child_window(title=u"添加", control_type="Button")
addbtn.parent().parent().parent()[1].click_input(button="left")
# 微信号:
get_wxh = self.win.Edit2.get_value()
# 修改备注内容
static_wxh = self.win.child_window(title=u'备 注', control_type="Text")
Pane46 = static_wxh.parent().parent()
for item in Pane46.children():
# item.draw_outline()
lines = item.children()
key = lines[0].window_text()
# value = lines[1].window_text()
if key == u'备 注' and wxh == get_wxh:
lines[1].click_input(button="left")
lines[1].type_keys("^A" + editstr)
# send_keys("{VK_ENTER}")
Tools.saveTxt(okfile, ",".join(wxline))
break
else:
Tools.saveTxt(errfile, "1.详情页未出现,2.异常退出,3.匹配的结果错误——————————\n")
Tools.saveTxt(errfile, ",".join(wxline)+"\n")
ret = False
send_keys("{VK_ESCAPE}")
send_keys("{VK_ESCAPE}")
time.sleep(1)
def _memo_chang_verify_no(self, editstr, wxline, okfile, errfile): # 修改备注
# 聊天信息
self.app.微信.聊天信息.click_input(button="left")
# 添加按钮
addbtn = self.win.child_window(title=u"添加", control_type="Button")
addbtn.parent().parent().parent()[1].click_input(button="left")
# 修改备注内容
static_wxh = self.win.child_window(title=u'备 注', control_type="Text")
Pane46 = static_wxh.parent().parent()
for item in Pane46.children():
lines = item.children()
key = lines[0].window_text()
if key == u'备 注':
lines[1].click_input(button="left")
lines[1].type_keys("^A" + editstr)
Tools.saveTxt(okfile, ",".join(wxline))
break
else:
Tools.saveTxt(errfile, ",".join(wxline)+"\n")
# 回退二页
send_keys("{VK_ESCAPE}")
send_keys("{VK_ESCAPE}")
time.sleep(1)
def _send_info_edit(self, infolist): # 发送消息
try:
# 内容编辑框
send_edit = self.win.child_window(title=u"输入", control_type="Edit")
send_edit.click_input(button='left')
# 发送内容
send_edit.type_keys("^A")
for info in infolist:
send_edit.type_keys(info+"+{ENTER}")
# 点击发送按钮
send_btn = self.win.child_window(title=u"发送(S)", control_type="Button")
send_btn.click_input(button='left')
except:
print(sys._getframe().f_lineno, "_send_info_edit() 出错了")
# 1、保存通讯录
def save_address(self, filename): # 保存通讯录
#1、连接微信
self._connect_wx()
#2、点击 通讯录
self._click_address()
pywinauto.mouse.click(button="left", coords=(self.coords.left + 150, self.coords.top + 30))
#3、写保存通讯录的标题
self._write_address_txt(filename, header=True)
#4、循环读取资料、写进通讯录文本
while True:
#4.1 读wx信息
ret = self._by_address_get_wxinfo()
#4.2 ok,写文件
if ret == WxObject.ok:
self._write_address_txt(filename)
# 4.3 exit,到末尾退出
elif ret == WxObject.exit:
break
if self.app.微信.is_active():
# self.con_list.type_keys("{DOWN}")
send_keys("{VK_DOWN}") # 继续下一条
else:
print(sys._getframe().f_lineno, "微信窗口失去焦点!!!")
break
# 2、搜索成功后,更新备注内容
def update_memo_verify(self, filename, okfile="ret_ok.txt", errfile="ret_err.txt"):
exefunc = "self._memo_chang_verify_wxh((wxline[0], wxline[self.cols-1], wxline, okfile, errfile)"
wx._click_lxr_item(filename, exefunc, okfile, errfile)
def update_memo(self, filename, okfile="ret_ok.txt", errfile="ret_err.txt"):
exefunc = "self._memo_chang_verify_no(wxline[self.cols-1], wxline, okfile, errfile)"
wx._click_lxr_item(filename, exefunc, okfile, errfile)
# 3、搜索成功后,发消息
def send_message(self, filename, infolist, okfile="ret_ok.txt", errfile="ret_err.txt"):
exefunc = "self._send_info_edit(infolist)"
# exefunc = "self._send_info_edit('"+infolist+"')"
wx._click_lxr_item2(filename, exefunc, okfile, errfile)
# 4、模糊查询,返回结果
def fuzzy_query_rets(self,search_txt = "TG"):
self._connect_wx()
self._wx_search(search_txt)
self._search_ret_items_wait()
def test(self):
# 1、连接微信
self._connect_wx()
# 2、点击 通讯录
self._click_address()
self._wx_search("TG-")
time.sleep(5)
ret = self._search_ret_items()
print(ret)
if __name__ == '__main__':
wx = WxObject()
# Tools.set_english_inputer()
# 1、保存通讯录 [微信号,备注,地区,呢称]
# wx.save_address("address_0908.txt") # 保存通讯录
# 通过通讯录,自动往下发消息
# wx.next_send("打扰了,此条消息为测试,勿需回复,谢谢!")
#2、给特定联系人发送消息 ,内容为列表。
infolist = ["打扰了,", "此条消息为测试", "勿需回复,谢谢!"]
wx.send_message("hyh210908.txt",infolist) # 给联系人发送消息
# 3、更新备注 [微信号 备注 呢称 修改的备注内容]
# wx.update_memo_verify("hyh210907.txt", "ret_ok.txt", "ret_err.txt")
# 3.1 更新备注,不校验
# wx.update_memo("hyh210907.txt", "ret_ok.txt", "ret_err.txt")
# 4、模糊查询,返回结果
# wx.fuzzy_query_rets(search_txt = "TG.")
Python自动采集微信联系人_ 批量改备注_发消息
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 大家好 我是你们的同步君 这几天陆陆续续接到了来自 房地产、教育行业、办信用卡等行业 的亲切电话问候 我就知道 大...