运维管理36 分钟阅读
Python 批量爬取猫咪图片实现千图成像
@TOC目录 使用 Python 爬取猫咪图片,并为猫咪🐱制作千图成像! 本文使用的 Python 版本是 3.10.0 版本,可直接在官网下载:https://www.python.orghtt
2021年11月2日
database
DBA 实战课程
系统学习 Oracle DBA
- 2738+ 篇实战文章
- 1500+ 步骤截图
- 10 大核心模块
开通会员 ¥128/月起
查看完整课程在知识库中专注阅读,并随时返回相关工具与课程
本章目标:掌握本章核心知识点 前置要求:完成前序章节学习 预计时长:60 分钟
使用 Python 爬取猫咪图片,并为猫咪🐱制作千图成像!

本文使用的 Python 版本是 3.10.0 版本,可直接在官网下载:https://www.python.org 。

Pythonn 的安装配置过程在此不做详细介绍,网上随意搜都是教程!
爬取网站:猫咪图片
首先安装必须的库:
1pip install BeautifulSoup42pip install requests3pip install urllib34pip install lxml爬取图片代码:
1from bs4 import BeautifulSoup2import requests3import urllib.request4import os56# 第一页猫咪图片网址7url = 'https://www.huiyi8.com/tupian/tag-%E7%8C%AB%E5%92%AA/1.html'8# 图片保存路径,这里 r 表示不转义9path = r"/Users/lpc/Downloads/cats/"10# 判断目录是否存在,存在则跳过,不存在则创建11if os.path.exists(path):12 pass13else:14 os.mkdir(path)151617# 获得所有猫咪图片网页地址18def allpage():19 all_url = []20 # 循环翻页次数 20 次21 for i in range(1, 20):22 # 替换翻页的页数,这里的 [-6] 是指网页地址倒数第 6 位23 each_url = url.replace(url[-6], str(i))24 # 将所有获取的 url 加入 all_url 数组25 all_url.append(each_url)26 # 返回所有获取到的地址27 return all_url282930# 主函数入口31if __name__ == '__main__':32 # 调用 allpage 函数获取所有网页地址33 img_url = allpage()34 for url in img_url:35 # 获得网页源代码36 requ = requests.get(url)37 req = requ.text.encode(requ.encoding).decode()38 html = BeautifulSoup(req, 'lxml')39 # 添加一个 url 数组40 img_urls = []41 # 获取 html 中所有 img 标签的内容42 for img in html.find_all('img'):43 # 筛选匹配 src 标签内容以 http 开头,以 jpg 结束44 if img["src"].startswith('http') and img["src"].endswith("jpg"):45 # 将符合条件的 img 标签加入 img_urls 数组46 img_urls.append(img)47 # 循环数组中所有 src48 for k in img_urls:49 # 获取图片 url50 img = k.get('src')51 # 获取图片名称,强制类型转换很重要52 name = str(k.get('alt'))53 type(name)54 # 给图片命名55 file_name = path + name + '.jpg'56 # 通过图片 url 和图片名称下载猫咪图片57 with open(file_name, "wb") as f, requests.get(img) as res:58 f.write(res.content)59 # 打印爬取的图片60 print(img, file_name)📢 注意: 以上代码无法直接复制运行,需要修改下载图片路径:/Users/lpc/Downloads/cats,请修改为读者本地的保存路径!
爬取成功:

共爬取 346 张猫咪图片!
爬取 ZOL 网址:萌猫
爬取代码:
1import requests2import time3import os4from lxml import etree56# 请求的路径7url = 'https://desk.zol.com.cn/dongwu/mengmao/1.html'8# 图片保存路径,这里 r 表示不转义9path = r"/Users/lpc/Downloads/ZOL/"10# 这里是你要保存的路径位置 前面的r 表示这段不转义11if os.path.exists(path): # 判断目录是否存在,存在则跳过,不存在则创建12 pass13else:14 os.mkdir(path)15# 请求头16headers = {"Referer": "Referer: http://desk.zol.com.cn/dongman/1920x1080/",17 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36", }1819headers2 = {20 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0", }212223def allpage(): # 获得所有网页24 all_url = []25 for i in range(1, 4): # 循环翻页次数26 each_url = url.replace(url[-6], str(i)) # 替换27 all_url.append(each_url)28 return all_url # 返回地址列表293031# TODO 获取到Html页面进行解析32if __name__ == '__main__':33 img_url = allpage() # 调用函数34 for url in img_url:35 # 发送请求36 resq = requests.get(url, headers=headers)37 # 显示请求是否成功38 print(resq)39 # 解析请求后获得的页面40 html = etree.HTML(resq.text)41 # 获取a标签下进入高清图页面的url42 hrefs = html.xpath('.//a[@class="pic"]/@href')43 # TODO 进入更深一层获取图片 高清图片44 for i in range(1, len(hrefs)):45 # 请求46 resqt = requests.get("https://desk.zol.com.cn" + hrefs[i], headers=headers)47 # 解析48 htmlt = etree.HTML(resqt.text)49 srct = htmlt.xpath('.//img[@id="bigImg"]/@src')50 # 截图片名称51 imgname = srct[0].split('/')[-1]52 # 根据url获取图片53 img = requests.get(srct[0], headers=headers2)54 # 执行写入图片到文件55 with open(path + imgname, "ab") as file:56 file.write(img.content)57 # 打印爬取的图片58 print(img, imgname)爬取成功:

共爬取 81 张猫咪图片!
爬取百度网站:百度猫咪图片
1、爬取图片代码:
1import requests2import os3from lxml import etree4path = r"/Users/lpc/Downloads/baidu1/"5# 判断目录是否存在,存在则跳过,不存在则创建6if os.path.exists(path):7 pass8else:9 os.mkdir(path)1011page = input('请输入要爬取多少页:')12page = int(page) + 113header = {14 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'15}16n = 017pn = 118# pn是从第几张图片获取 百度图片下滑时默认一次性显示30张19for m in range(1, page):20 url = 'https://image.baidu.com/search/acjson?'2122 param = {23 'tn': 'resultjson_com',24 'logid': '7680290037940858296',25 'ipn': 'rj',26 'ct': '201326592',27 'is': '',28 'fp': 'result',29 'queryWord': '猫咪',30 'cl': '2',31 'lm': '-1',32 'ie': 'utf-8',33 'oe': 'utf-8',34 'adpicid': '',35 'st': '-1',36 'z': '',37 'ic': '0',38 'hd': '1',39 'latest': '',40 'copyright': '',41 'word': '猫咪',42 's': '',43 'se': '',44 'tab': '',45 'width': '',46 'height': '',47 'face': '0',48 'istype': '2',49 'qc': '',50 'nc': '1',51 'fr': '',52 'expermode': '',53 'nojc': '',54 'acjsonfr': 'click',55 'pn': pn, # 从第几张图片开始56 'rn': '30',57 'gsm': '3c',58 '1635752428843=': '',59 }60 page_text = requests.get(url=url, headers=header, params=param)61 page_text.encoding = 'utf-8'62 page_text = page_text.json()63 print(page_text)64 # 先取出所有链接所在的字典,并将其存储在一个列表当中65 info_list = page_text['data']66 # 由于利用此方式取出的字典最后一个为空,所以删除列表中最后一个元素67 del info_list[-1]68 # 定义一个存储图片地址的列表69 img_path_list = []70 for i in info_list:71 img_path_list.append(i['thumbURL'])72 # 再将所有的图片地址取出,进行下载73 # n将作为图片的名字74 for img_path in img_path_list:75 img_data = requests.get(url=img_path, headers=header).content76 img_path = path + str(n) + '.jpg'77 with open(img_path, 'wb') as fp:78 fp.write(img_data)79 n = n + 18081 pn += 292、爬取代码
1# -*- coding:utf-8 -*-2import requests3import re, time, datetime4import os5import random6import urllib.parse7from PIL import Image # 导入一个模块89imgDir = r"/Volumes/DBA/python/img/"10# 设置headers 为了防止反扒,设置多个headers11# chrome,firefox,Edge12headers = [13 {14 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',15 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',16 'Connection': 'keep-alive'17 },18 {19 "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0',20 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',21 'Connection': 'keep-alive'22 },23 {24 "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041',25 'Accept-Language': 'zh-CN',26 'Connection': 'keep-alive'27 }28]2930picList = [] # 存储图片的空 List3132keyword = input("请输入搜索的关键词:")33kw = urllib.parse.quote(keyword) # 转码343536# 获取 1000 张百度搜索出来的缩略图 list37def getPicList(kw, n):38 global picList39 weburl = r"https://image.baidu.com/search/acjson?tn=resultjson_com&logid=11601692320226504094&ipn=rj&ct=201326592&is=&fp=result&queryWord={kw}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=©right=&word={kw}&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&fr=&expermode=&force=&cg=girl&pn={n}&rn=30&gsm=1e&1611751343367=".format(40 kw=kw, n=n * 30)41 req = requests.get(url=weburl, headers=random.choice(headers))42 req.encoding = req.apparent_encoding # 防止中文乱码43 webJSON = req.text44 imgurlReg = '"thumbURL":"(.*?)"' # 正则45 picList = picList + re.findall(imgurlReg, webJSON, re.DOTALL | re.I)464748for i in range(150): # 循环数比较大,如果实际上没有这么多图,那么 picList 数据不会增加。49 getPicList(kw, i)5051for item in picList:52 # 后缀名 和名字53 itemList = item.split(".")54 hz = ".jpg"55 picName = str(int(time.time() * 1000)) # 毫秒级时间戳56 # 请求图片57 imgReq = requests.get(url=item, headers=random.choice(headers))58 # 保存图片59 with open(imgDir + picName + hz, "wb") as f:60 f.write(imgReq.content)61 # 用 Image 模块打开图片62 im = Image.open(imgDir + picName + hz)63 bili = im.width / im.height # 获取宽高比例,根据宽高比例调整图片大小64 newIm = None65 # 调整图片的大小,最小的一边设置为 5066 if bili >= 1:67 newIm = im.resize((round(bili * 50), 50))68 else:69 newIm = im.resize((50, round(50 * im.height / im.width)))70 # 截取图片中 50*50 的部分71 clip = newIm.crop((0, 0, 50, 50)) # 截取图片,crop 裁切72 clip.convert("RGB").save(imgDir + picName + hz) # 保存截取的图片73 print(picName + hz + " 处理完毕")爬取成功:

总结: 三个网站共爬取 1600 张猫咪图片!
爬取千张图片之后,接下来就需要使用图片拼接成一张猫咪图片,即千图成像。
首先下载软件:Foto-Mosaik-Edda Installer,如果无法下载,直接百度搜索 foto-mosaik-edda!
Windows 安装 Foto-Mosaik-Edda 过程比较简单!
📢 注意: 但是需要提前安装 .NET Framework 2,否则报错如下无法成功安装!

启用 .NET Framework 2 的方式:





确认已经成功启用:

接下来就可以继续安装!






安装完成后,打开如下:

第一步,创建一个图库:





第二步,千图成像:



这里勾选第一步创建好的图库:






见证奇迹的时刻:

再制作一张可爱的猫咪:

大功告成!
首先,选取一张图片:

运行以下代码:
1# -*- coding:utf-8 -*-2from PIL import Image3import os4import numpy as np56imgDir = r"/Volumes/DBA/python/img/"7bgImg = r"/Users/lpc/Downloads/494.jpg"8910# 获取图像的平均颜色值11def compute_mean(imgPath):12 '''13 获取图像平均颜色值14 :param imgPath: 缩略图路径15 :return: (r,g,b)整个缩略图的rgb平均值16 '''17 im = Image.open(imgPath)18 im = im.convert("RGB") # 转为 rgb模式19 # 把图像数据转为数据序列。以行为单位,每行存储每个像素点的色彩20 '''如:21 [[ 60 33 24] 22 [ 58 34 24]23 ...24 [188 152 136] 25 [ 99 96 113]]2627 [[ 60 33 24] 28 [ 58 34 24]29 ...30 [188 152 136] 31 [ 99 96 113]]32 '''33 imArray = np.array(im)34 # mean()函数功能:求指定数据的取均值35 R = np.mean(imArray[:, :, 0]) # 获取所有 R 值的平均值36 G = np.mean(imArray[:, :, 1])37 B = np.mean(imArray[:, :, 2])38 return (R, G, B)394041def getImgList():42 """43 获取缩略图的路径及平均色彩44 :return: list,存储了图片路径、平均色彩值。45 """46 imgList = []47 for pic in os.listdir(imgDir):48 imgPath = imgDir + pic49 imgRGB = compute_mean(imgPath)50 imgList.append({51 "imgPath": imgPath,52 "imgRGB": imgRGB53 })54 return imgList555657def computeDis(color1, color2):58 '''59 计算两张图的颜色差,计算机的是色彩空间距离。60 dis = (R**2 + G**2 + B**2)**0.561 参数:color1,color2 是色彩数据 (r,g,b)62 '''63 dis = 064 for i in range(len(color1)):65 dis += (color1[i] - color2[i]) ** 266 dis = dis ** 0.567 return dis686970def create_image(bgImg, imgDir, N=2, M=50):71 '''72 根据背景图,用头像填充出新图73 bgImg:背景图地址74 imgDir:头像目录75 N:背景图缩放的倍率76 M:头像的大小(MxM)77 '''78 # 获取图片列表79 imgList = getImgList()8081 # 读取图片82 bg = Image.open(bgImg)83 # bg = bg.resize((bg.size[0] // N, bg.size[1] // N)) # 缩放。建议缩放下原图,图片太大运算时间很长。84 bgArray = np.array(bg)85 width = bg.size[0] * M # 新生成图片的宽度。每个像素倍放大 M 倍86 height = bg.size[1] * M # 新生成图片的高度8788 # 创建空白的新图89 newImg = Image.new('RGB', (width, height))9091 # 循环填充图92 for x in range(bgArray.shape[0]): # x,行数据,可以用原图宽替代93 for y in range(bgArray.shape[1]): # y,列数据,,可以用原图高替代94 # 找到距离最小的图片95 minDis = 1000096 index = 097 for img in imgList:98 dis = computeDis(img['imgRGB'], bgArray[x][y])99 if dis < minDis:100 index = img['imgPath']101 minDis = dis102 # 循环完毕,index 就是存储了色彩最相近的图片路径103 # minDis 存储了色彩差值104 # 填充105 tempImg = Image.open(index) # 打开色差距离最小的图片106 # 调整图片大小,此处可以不调整,因为我在下载图的时候就已经调整好了107 tempImg = tempImg.resize((M, M))108 # 把小图粘贴到新图上。注意 x,y ,行列不要搞混了。相距 M 粘贴一张。109 newImg.paste(tempImg, (y * M, x * M))110 print('(%d, %d)' % (x, y)) # 打印进度。格式化输出 x,y111112 # 保存图片113 newImg.save('final.jpg') # 最后保存图片114115116create_image(bgImg, imgDir)运行结果:

从上图可以发现,图片的清晰度堪比原图,放大之后小图依然清晰可见!
📢 注意: 使用 Python 运行会比较慢!
真好,又可以愉快地吸猫了~

本文参考: