微信好友头像爬取及自定义拼接(Python itchat+pillow)

Python环境实现(略)

******百度,琳琅满目******

核心模块

  • itchat(爬取头像)
  • pillow(拼接头像)

内置模块

  • os(文件夹操作)
  • math(数学计算)

效果图

1.  合成图像尺寸(25 * 25)

微信好友头像爬取及自定义拼接(Python itchat+pillow)_第1张图片2

2. 合成图像尺寸(20 * 20)

微信好友头像爬取及自定义拼接(Python itchat+pillow)_第2张图片

3. 合成图像尺寸(16 * 16)

微信好友头像爬取及自定义拼接(Python itchat+pillow)_第3张图片

源码详解

通过 itchat 模块登录网页版微信,run代码时会自动弹窗(二维码登录),用手机微信扫描确认登录:

# 关键字实参hotReload取True使得短时间内无需再次扫码登录
itchat.auto_login(hotReload=True)

获取好友列表:

# 内置函数get_friends获取好友列表,返回的是一个列表
friends = itchat.get_friends(update=True)[0:]

预置存储微信头像的文件夹,判断是否存在,不存在的话,创建新的(第一次,铁定创建新的哈):

# 存储微信头像的文件夹名字
my_friends_file = 'pipixia_womenzou'
# 存储微信头像文件夹的完整地址(注意双反斜杠)
file_full_path = 'D:\pycharm_projects\\' + my_friends_file
# 如果文件夹不存在,创建一个新的我们想要的文件夹
if not os.path.exists(file_full_path):
    os.makedirs(file_full_path)

定义爬取微信好友头像的函数,函数中将头像存储到形参 file_path 的文件夹中,之后调用的时候就传入之前创建的新文件夹 pipixia_womenzou 中:

# 定义函数(获取好友的微信头像)
def get_friends_head_images(file_path, friends):
    image_number = 1
    # 获取好友的头像(friends[0]是自己,不想获取自己的可改为遍历friends[1:])
    for friend in friends:
        """
            内置函数get_head_img获取好友头像
            这里只获取好友头像,所以只需设置关键字实参userName
            如果需要获取群聊中的成员头像,可设置关键字实参chatroomUserName
        """
        img = itchat.get_head_img(userName=friend['UserName'])
        # 头像存储路径为文件夹路径添加上头像的文件名
        store_path = file_path + '\\' + str(image_number) + '.jpg'
        # try-except 经典语句块
        try:
            # 'wb'二进制流写入
            with open(store_path, 'wb') as f:
                f.write(img)
                print('Downloading......' + '第' + str(image_number) + '张头像')
        except Exception as e:
            print(repr(e))
        print('Successfully Downloaded......' + '第' + str(image_number) + '张头像' + '\n')
        image_number += 1

爬取好友头像,存储到创建的文件夹:

# 调用函数get_friends_head_images,下载微信头像
get_friends_head_images(file_full_path, friends)

列表化创建的文件夹下的微信好友头像:

# 调用os模块的listdir函数,将file_full_path文件夹下的文件列表化,方便后续遍历处理
got_head_images_list = os.listdir(file_full_path)

获悉微信头像普遍尺寸大小(实际程序中是注释("""blabla""")掉的,因为我们不需要它起什么作用),得到普遍值为(640, 640, 3), 3代表三个信号通道,通俗理解为BGR,每个像素点由(blue,green, red)构成,三种颜色的取值范围为0~255:

import cv2

got_head_images_list = os.listdir(file_full_path)
for img in got_head_images_list:
    img = cv2.imread(file_full_path + '\\' + img)
    print('head_img_shape: ', img.shape)

运行结果(部分):
        ******************************
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (685, 686, 3)
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (750, 750, 3)
        head_img_shape:  (640, 640, 3)
        head_img_shape:  (640, 640, 3)
        ******************************

定义拼接函数,如果好友数不超过16*16=256个,那么程序会直接调用该函数进行拼接,最后将拼接好的图片存储到之前创建的文件夹,与存储微信好友头像的是同一个文件夹:

# 定义默认拼接函数,处理rows <= 16的情况
def images_splice(file_path, images_list, rows):
    new_image = Image.new('RGB', (640, 640))  # 创建新的空白图片模板,用来合成我们想要的头像集
    single_size = int(640/rows)  # 新单个微信头像尺寸
    img_x, img_y = 0, 0  # 微信头像坐标,每一个为基本单位(0,0)开始,(rows-1,rows-1)结束
    for img in images_list[:rows ** 2]:  # 这里的img即为文件名,type(img) == 
        try:
            img = Image.open(file_path + '\\' + img)
        except IOError:
            print("ERROR: 没有找到文件或读取文件失败")
        else:
            # 重新设置每个微信头像的尺寸,这里为默认值
            img = img.resize((single_size, single_size), Image.ANTIALIAS)
            new_image.paste(img, (img_x * single_size, img_y * single_size))
            img_x += 1  # 第一行结束img_x为(rows-1),加个1成了rows
            if img_x == rows:  # 第一行粘贴完了
                img_x = 0  # 从第一列重新开始
                img_y += 1  # 第一行抬到第二行
    # 将这张得到的图片保存到好友头像所在的文件夹,文件名会异常显眼
    new_image.save(file_path + '\\' + 'wanted_picture_16.jpg')
定义自定义拼接函数,也许你的好友众多,远不止256个,则程序会自动调用改自定义函数,询问你需要拼接多少尺寸的图片。程序会给你一个范围供你挑选( Bigger than 16, but no more than 25: ),你只需要输入一个数字:17 or 18 or 19 or... or 25。
随便输,输成字母也没关系,当然它会一直问你,直到你输对了:
# 自定义拼接函数,处理rows > 16的情况
def customize_images_choose(rows):
    terminal_words = 'How many pictures do you want per line? Bigger than 16, but no more than ' + str(rows) + ': '
    rows_you_want = input(terminal_words)
    while True:
        try:
            got_rows = int(rows_you_want)
        except:
            rows_you_want = input('Please enter a number instead of a string and try again: ')
            continue
        else:
            if got_rows < 16 or got_rows > rows:
                rows_you_want = input('The number you entered is not in range. Please enter again as required: ')
                continue
            else:
                break
    return got_rows

定义好了两个函数,一个默认,一个自定义,程序调用哪一个取决于你的微信好友数量了吆,现在就可以调用它们了:

lst_length = len(got_head_images_list)
can_rows = int(math.sqrt(lst_length))
if can_rows <= 16:
    images_splice(file_full_path, got_head_images_list, can_rows)
else:
    rows_you_want = customize_images_choose(can_rows)
    images_splice(file_full_path, got_head_images_list, rows_you_want)

最后,拼接好的图片已经躺在了之前创建的文件夹中,如果你好友数量众多,需要各种尺寸大小,多运行几次就ok了(因为头像已经下载好了,无需反复下载,生成多种尺寸时先注释掉前边的微信头像下载函数get_friends_head_images以及与 itchat 相关的语句)。

躺在文件夹可不行,你可以将它发送到你自己的微信上或者分享给你的好朋友:

# 将这张得到的图片发送到你的微信
itchat.send_image(file_full_path + '\\' + 'wanted_picture.jpg')
# 当然你也可以将这张得到的图片分享给你的好友
itchat.send_image(file_full_path + '\\' + 'wanted_picture.jpg', toUserName='who you want to share') # 需要你替换成有效的好友名
微信好友头像爬取及自定义拼接(Python itchat+pillow)_第4张图片

你可能感兴趣的:(Python,Python,itchat,pillow,微信好友头像,自定义拼接)