基本 python 实现的爬取微信好友头像,并拼接成大图

警告
本文最后更新于 2023-07-07,文中内容可能已过时。

Python 通过 wxpy 登录微信网页版,爬取好友所有头像并拼接成一张大图。然后删除所有子图。(注释相关代码可以不删除)
文中涉及的图片涉及个人隐私,仅做举例,请勿传播
文中编码由 Sunbelife 提供,来自他的同名微信公众号,本博仅用于学习,侵删

依赖

  • wxpy(Pythone 登录微信)
  • pillow(拼接头像)
  • os(文件夹操作)
  • math(数学计算)

wxpy:
  wxpy 在 itchat 的基础上,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展。
PIL
  Python Imaging Library,已经是 Python 平台事实上的图像处理标准库了。PIL 功能非常强大,但 API 却非常简单易用。由于 PIL 仅支持到 Python 2.7,加上年久失修,于是一群志愿者在 PIL 的基础上创建了兼容的版本,名字叫 Pillow,支持最新 Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用 Pillow。

安装

1
2
pip install -U wxpy -i "https://pypi.doubanio.com/simple/"
pip install pillow

运行

如果在 Python IDE 运行出错,可能是因为微信好友的 id 是特殊字符,在 IDE 打印出错,注释掉代码 36 行即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from wxpy import *
import math
import PIL.Image as Image
import os
import sys
import shutil
#
### 获取文件所在的绝对路径
def get_dir(sys_arg):
	sys_arg = sys_arg.split("/")

	dir_str = ""
	count = 0
	for cur_dir in sys_arg:
		if count == 0:
			count = count + 1
		if count == len(sys_arg):
			break
		dir_str = dir_str + cur_dir + "/"
		count = count + 1
	return dir_str

curr_dir = get_dir(sys.argv[0])

bot = Bot()

## 机器人账号自身
myself = bot.self
my_friends = bot.friends(update=True)

if not os.path.exists(curr_dir + "group-images/"):
	os.mkdir(curr_dir + "group-images/")

count = 0
for friend in my_friends:
	print(friend.nick_name)
	friend.get_avatar(curr_dir + "group-images/" + str(count) + ".jpg")
	count = count + 1

## 获取下载的头像文件
ls = os.listdir(curr_dir + 'group-images')

## 去除非 .jpg 文件
for filter_ls in ls:
	if ".jpg" in filter_ls:
		continue
	else:
		ls.remove(filter_ls)

## 排序
ls.sort(key=lambda x:int(x[:-4]))

## 头像墙尺寸
image_size = 2560

each_size = math.floor(image_size/math.floor(math.sqrt(len(ls))))
x_lines = math.ceil(math.sqrt(len(ls)))
y_lines = math.ceil(math.sqrt(len(ls)))
image = Image.new('RGB', (each_size * x_lines, each_size * y_lines))

x = 0
y = 0

for file_names in ls:
	try:
		img = Image.open(curr_dir + "group-images/" + file_names)
		print("正在处理" + file_names.split('.jpg')[0] + "/" + str(len(ls)))
	except IOError:
		continue
	else:
		img = img.resize((each_size, each_size))
		image.paste(img, (x * each_size, y * each_size))
		x += 1
		if x == x_lines:
			x = 0
			y += 1

img = image.save(curr_dir + "all.jpg")

try:
	shutil.rmtree(curr_dir + "group-images/")
	print("收尾,清理临时文件")
except FileNotFoundError:
	print("没什么好删的")

print("!!!\n 生成完毕了,放在了目录" + curr_dir + ",去看看吧。")
print("工具作者:@Sunbelife(新浪微博)")
print("公众号:Sunbelife")
print("感谢使用")
print("v1.2")
print("2019.4.18")

群友全家福

修改 11 行群名称

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import itchat
import math
import PIL.Image as Image
import os
import shutil

## 变量
itchat.auto_login(hotReload=True,enableCmdQR=False)
roomslist = itchat.get_chatrooms(update=True)[0:]
itchat.dump_login_status() ## 显示所有的群聊信息,默认是返回保存到通讯录中的群聊
myroom=itchat.search_chatrooms(name=u'绥宁一中高 396 班') #群聊名称
gsq=itchat.update_chatroom(myroom[0]['UserName'], detailedMember=True)

num = 0

if not os.path.exists("./group-images/"):
    os.mkdir("./group-images/")

for i in gsq['MemberList']:
    print(i["UserName"])
    img = itchat.get_head_img(userName=i["UserName"],chatroomUserName=myroom[0]['UserName'])
    fileImage = open("./group-images/" + str(num) + ".jpg",'wb')
    fileImage.write(img)
    fileImage.close()
    num += 1

ls = os.listdir('./group-images')
each_size = int(math.sqrt(float(640*640)/len(ls)))
lines = int(640/each_size)
image = Image.new('RGBA', (640, 640))
x = 0
y = 0
for i in range(0,len(ls)+1):
    try:
        img = Image.open("./group-images/" + str(i) + ".jpg")
    except IOError:
        print("Error")
    else:
        img = img.resize((each_size, each_size), Image.ANTIALIAS)
        image.paste(img, (x * each_size, y * each_size))
        x += 1
        if x == lines:
            x = 0
            y += 1
image.save("all.png")
shutil.rmtree("./group-images")

绥宁一中高 396 班

加个列表,加个循环实现自动爬取所有群聊头像并发送

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import itchat
import math
import PIL.Image as Image
import os
import shutil

## 变量
itchat.auto_login(hotReload=True,enableCmdQR=False)
roomslist = itchat.get_chatrooms(update=True)[0:]
itchat.dump_login_status() ## 显示所有的群聊信息,默认是返回保存到通讯录中的群聊

for room in roomslist:
    print(room['UserName'])
    gsq=itchat.update_chatroom(room['UserName'], detailedMember=True)
    num = 0

    if not os.path.exists("./group-images/"):
        os.mkdir("./group-images/")

    for i in gsq['MemberList']:
        print(i["UserName"])
        img = itchat.get_head_img(userName=i["UserName"],chatroomUserName=room['UserName'])
        fileImage = open("./group-images/" + str(num) + ".jpg",'wb')
        fileImage.write(img)
        fileImage.close()
        num += 1

    ls = os.listdir('./group-images')
    each_size = int(math.sqrt(float(640*640)/len(ls)))
    lines = int(640/each_size)
    image = Image.new('RGB', (640, 640))
    x = 0
    y = 0
    for i in range(0,len(ls)+1):
        try:
            img = Image.open("./group-images/" + str(i) + ".jpg")
        except IOError:
            print("Error")
        else:
            img = img.resize((each_size, each_size), Image.ANTIALIAS)
            image.paste(img, (x * each_size, y * each_size))
            x += 1
            if x == lines:
                x = 0
                y += 1
    image.save("all.jpg")
    itchat.send("写了个好玩的… 测试一下", room['UserName'])
    itchat.send_image("all.jpg", room['UserName'])
    shutil.rmtree("./group-images")
Buy me a coffee~
支付宝
微信
0%