慎入 我怕你把控不住?Python爬蟲實現貓咪千圖成像

前言

使用 Python 爬取貓咪圖片,并為貓咪制作千圖成像!

爬取貓咪圖片

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

Pythonn 安裝配置過程在此不做詳細介紹,網上隨意搜都是教程!

1、爬取繪藝素材網站

爬取網站:貓咪圖片

首先安裝必須的庫:

pip install BeautifulSoup4

pip install requests

pip install urllib3

pip install lxml

爬取圖片代碼:

from bs4 import BeautifulSoup

import requests

import urllib.request

import os

# 第一頁貓咪圖片網址

url = 'https://www.huiyi8.com/tupian/tag-%E7%8C%AB%E5%92%AA/1.html'

# 圖片保存路徑,這里 r 表示不同意

path = r"/Users/lpc/Downloads/cats/"

# 判斷目錄是否存在,存在則跳過,不存在則創建

if os.path.exists(path):

pass

else:

os.mkdir(path)

# 獲得所有貓咪圖片網頁地址

def allpage():

all_url = []

# 循環翻頁次數 20 次

for i in range(1, 20):

# 替換翻頁的頁數,這里的 [-6] 是指網頁地址倒數第 6 位

each_url = url.replace(url[-6], str(i))

# 將所有獲取的 url 加入 all_url 數組

all_url.append(each_url)

# 返回所有獲取到的地址

return all_url

# 主函數入口

if __name__ == '__main__':

# 調用 allpage 函數獲取所有網頁地址

img_url = allpage()

for url in img_url:

# 獲得網頁源代碼

requ = requests.get(url)

req = requ.text.encode(requ.encoding).decode()

html = BeautifulSoup(req, 'lxml')

# 添加一個 url 數組

img_urls = []

# 獲取 html 中所有 img 標簽的內容

for img in html.find_all('img'):

# 篩選匹配 src 標簽內容以 http 開頭,以 jpg 結束

if img["src"].startswith('http') and img["src"].endswith("jpg"):

# 將符合條件的 img 標簽加入 img_urls 數組

img_urls.append(img)

# 循環數組中所有 src

for k in img_urls:

# 獲取圖片 url

img = k.get('src')

# 獲取圖片名稱,強制類型轉換很重要

name = str(k.get('alt'))

type(name)

# 給圖片命名

file_name = path + name + '.jpg'

# 通過圖片 url 和圖片名稱一樣的是下載貓咪的圖片

with open(file_name, "wb") as f, requests.get(img) as res:

f.write(res.content)

# 打印爬取的圖片

print(img, file_name)

注意: 以上代碼無法直接復制運行,需要修改下載圖片路徑:/Users/lpc/Downloads/cats,請修改為讀者本地的保存路徑!

爬取成功:

共爬取 346 張貓咪圖片!

2、爬取 ZOL 網站

爬取 ZOL 網址:萌貓

爬取代碼:

import requests

import time

import os

from lxml import etree

# 請求的路徑

url = 'https://desk.zol.com.cn/dongwu/mengmao/1.html'

# 圖片保存路徑,這里 r 表示不同意

path = r"/Users/lpc/Downloads/ZOL/"

# 這里是你要保存的路徑位置 前面的r 表示這段時間不轉移

if os.path.exists(path): # 判斷目錄是否存在,存在則跳過,不存在則創建

pass

else:

os.mkdir(path)

# 請求頭

headers = {"Referer": "Referer: http://desk.zol.com.cn/dongman/1920x1080/",

"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", }

headers2 = {

"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", }

def allpage(): # 獲得所有網頁

all_url = []

for i in range(1, 4): # 循環翻頁次數

each_url = url.replace(url[-6], str(i)) # 替換

all_url.append(each_url)

return all_url # 返回地址列表

# TODO 獲取到Html頁面進行解析

if __name__ == '__main__':

img_url = allpage() # 調用函數

for url in img_url:

# 發送請求

resq = requests.get(url, headers=headers)

# 顯示請求是否成功

print(resq)

# 解析請求后獲得的頁面

html = etree.HTML(resq.text)

# 獲取a標簽下進入高清圖頁面的url

hrefs = html.xpath('.//a[@class="pic"]/@href')

# TODO 進入更深一層獲取圖片 高清圖片

for i in range(1, len(hrefs)):

# 請求

resqt = requests.get("https://desk.zol.com.cn" + hrefs[i], headers=headers)

# 解析

htmlt = etree.HTML(resqt.text)

srct = htmlt.xpath('.//img[@id="bigImg"]/@src')

# 截圖片名稱

imgname = srct[0].split('/')[-1]

# 根據url獲取圖片

img = requests.get(srct[0], headers=headers2)

# 執行寫入圖片到文件

with open(path + imgname, "ab") as file:

file.write(img.content)

# 打印爬取的圖片

print(img, imgname)

爬取成功:

共爬取 81 張貓咪圖片!

3、爬取百度圖片網站

爬取百度網站:百度貓咪圖片

1.1 爬取圖片代碼:

import requests

import os

from lxml import etree

path = r"/Users/lpc/Downloads/baidu1/"

# 判斷目錄是否存在,存在則跳過,不存在則創建

if os.path.exists(path):

pass

else:

os.mkdir(path)

page = input('請輸入要爬取多少頁:')

page = int(page) + 1

header = {

'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'

}

n = 0

pn = 1

# pn是從第幾張圖片獲取 百度圖片下滑時默認一次性顯示30張

for m in range(1, page):

url = 'https://image.baidu.com/search/acjson?'

param = {

'tn': 'resultjson_com',

'logid': '7680290037940858296',

'ipn': 'rj',

'ct': '201326592',

'is': '',

'fp': 'result',

'queryWord': '貓咪',

'cl': '2',

'lm': '-1',

'ie': 'utf-8',

'oe': 'utf-8',

'adpicid': '',

'st': '-1',

'z': '',

'ic': '0',

'hd': '1',

'latest': '',

'copyright': '',

'word': '貓咪',

's': '',

'se': '',

'tab': '',

'width': '',

'height': '',

'face': '0',

'istype': '2',

'qc': '',

'nc': '1',

'fr': '',

'expermode': '',

'nojc': '',

'acjsonfr': 'click',

'pn': pn, # 從第幾張圖片開始

'rn': '30',

'gsm': '3c',

'1635752428843=': '',

}

page_text = requests.get(url=url, headers=header, params=param)

page_text.encoding = 'utf-8'

page_text = page_text.json()

print(page_text)

# 先取出所有鏈接所在的字典,并將其存儲在一個列表當中

info_list = page_text['data']

# 由于利用此方式取出的字典最后一個為空,所以刪除列表中最后一個元素

del info_list[-1]

# 定義一個存儲圖片地址的列表

img_path_list = []

for i in info_list:

img_path_list.append(i['thumbURL'])

# 再將所有的圖片地址取出,進行下載

# n將作為圖片的名字

for img_path in img_path_list:

img_data = requests.get(url=img_path, headers=header).content

img_path = path + str(n) + '.jpg'

with open(img_path, 'wb') as fp:

fp.write(img_data)

n = n + 1

pn += 29

1.2 爬取代碼:

# -*- coding:utf-8 -*-

import requests

import re, time, datetime

import os

import random

import urllib.parse

from PIL import Image # 導入一個模塊

imgDir = r"/Volumes/DBA/python/img/"

# 設置headers 為了防止反扒,設置多個headers

# chrome,firefox,Edge

headers = [

{

'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',

'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',

'Connection': 'keep-alive'

},

{

"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0',

'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',

'Connection': 'keep-alive'

},

{

"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',

'Accept-Language': 'zh-CN',

'Connection': 'keep-alive'

}

]

picList = [] # 存儲圖片的空 List

keyword = input("請輸入搜索的關鍵詞:")

kw = urllib.parse.quote(keyword) # 轉碼

# 獲取 1000 張百度搜索出來的縮略圖 list

def getPicList(kw, n):

global picList

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(

kw=kw, n=n * 30)

req = requests.get(url=weburl, headers=random.choice(headers))

req.encoding = req.apparent_encoding # 防止中文亂碼

webJSON = req.text

imgurlReg = '"thumbURL":"(.*?)"' # 正則

picList = picList + re.findall(imgurlReg, webJSON, re.DOTALL | re.I)

for i in range(150): # 循環數比較大,如果實際上沒有這么多圖,那么 picList 數據不會增加。

getPicList(kw, i)

for item in picList:

# 后綴名 和名字

itemList = item.split(".")

hz = ".jpg"

picName = str(int(time.time() * 1000)) # 毫秒級時間戳

# 請求圖片

imgReq = requests.get(url=item, headers=random.choice(headers))

# 保存圖片

with open(imgDir + picName + hz, "wb") as f:

f.write(imgReq.content)

# 用 Image 模塊打開圖片

im = Image.open(imgDir + picName + hz)

bili = im.width / im.height # 獲取寬高比例,根據寬高比例調整圖片大小

newIm = None

# 調整圖片的大小,最小的一邊設置為 50

if bili >= 1:

newIm = im.resize((round(bili * 50), 50))

else:

newIm = im.resize((50, round(50 * im.height / im.width)))

# 截取圖片中 50*50 的部分

clip = newIm.crop((0, 0, 50, 50)) # 截取圖片,crop 裁切

clip.convert("RGB").save(imgDir + picName + hz) # 保存截取的圖片

print(picName + hz + " 處理完畢")

爬取成功:

總結: 三個網站共爬取 1600 張貓咪圖片!

千圖成像

4.爬取千張圖片之后,接下來就需要使用圖片拼接成一張貓咪圖片,即千圖成像。

1、Foto-Mosaik-Edda 軟件實現

首先下載軟件:Foto-Mosaik-Edda Installer,如果無法下載,直接百度搜索 foto-mosaik-edda!

Windows 安裝 Foto-Mosaik-Edda 過程比較簡單!

注意: 但是需要提前安裝 .NET Framework 2,否則報錯如下無法成功安裝!

啟用 .NET Framework 2 的方式:

確認已經成功啟用:

接下來就可以繼續安裝!

安裝完成后,打開如下:

第一步,創建一個圖庫:

第二步,千圖成像:

見證奇跡的時刻:

再制作一張可愛的貓咪:

大功告成!

2、使用 Python 實現

首先,選取一張圖片:

運行以下代碼:

# -*- coding:utf-8 -*-from PIL import Imageimport osimport numpy as np

imgDir = r"/Volumes/DBA/python/img/"bgImg = r"/Users/lpc/Downloads/494.jpg"# 獲取圖像的平均顏色值def compute_mean(imgPath):'''

獲取圖像平均顏色值

:param imgPath: 縮略圖路徑

:return: (r,g,b)整個縮略圖的rgb平均值

'''im = Image.open(imgPath)im = im.convert("RGB") # 轉為 rgb模式# 把圖像數據轉為數據序列。以行為單位,每行存儲每個像素點的色彩'''如:

[[ 60 33 24]

[ 58 34 24]

...

[188 152 136]

[ 99 96 113]]

[[ 60 33 24]

[ 58 34 24]

...

[188 152 136]

[ 99 96 113]]

'''imArray = np.array(im)# mean()函數功能:求指定數據的取均值R = np.mean(imArray[:, :, 0]) # 獲取所有 R 值的平均值G = np.mean(imArray[:, :, 1])B = np.mean(imArray[:, :, 2])return (R, G, B)def getImgList():"""

獲取縮略圖的路徑及平均色彩

:return: list,存儲了圖片路徑、平均色彩值。

"""imgList = []for pic in os.listdir(imgDir):imgPath = imgDir + pic

imgRGB = compute_mean(imgPath)imgList.append({"imgPath": imgPath,"imgRGB": imgRGB})return imgListdef computeDis(color1, color2):'''

計算兩張圖的顏色差,計算機的是色彩空間距離。

dis = (R**2 + G**2 + B**2)**0.5

參數:color1,color2 是色彩數據 (r,g,b)

'''dis = 0for i in range(len(color1)):dis += (color1[i] - color2[i]) ** 2dis = dis ** 0.5return disdef create_image(bgImg, imgDir, N=2, M=50):'''

根據背景圖,用頭像填充出新圖

bgImg:背景圖地址

imgDir:頭像目錄

N:背景圖縮放的倍率

M:頭像的大小(MxM)

'''# 獲取圖片列表imgList = getImgList()# 讀取圖片bg = Image.open(bgImg)# bg = bg.resize((bg.size[0] // N, bg.size[1] // N)) # 縮放。建議縮放下原圖,圖片太大運算時間很長。bgArray = np.array(bg)width = bg.size[0] * M # 新生成圖片的寬度。每個像素倍放大 M 倍height = bg.size[1] * M # 新生成圖片的高度# 創建空白的新圖newImg = Image.new('RGB', (width, height))# 循環填充圖for x in range(bgArray.shape[0]): # x,行數據,可以用原圖寬替代for y in range(bgArray.shape[1]): # y,列數據,,可以用原圖高替代# 找到距離最小的圖片minDis = 10000index = 0for img in imgList:dis = computeDis(img['imgRGB'], bgArray[x][y])if dis < minDis:index = img['imgPath']minDis = dis# 循環完畢,index 就是存儲了色彩最相近的圖片路徑# minDis 存儲了色彩差值# 填充tempImg = Image.open(index) # 打開色差距離最小的圖片# 調整圖片大小,此處可以不調整,因為我在下載圖的時候就已經調整好了tempImg = tempImg.resize((M, M))# 把小圖粘貼到新圖上。注意 x,y ,行列不要搞混了。相距 M 粘貼一張。newImg.paste(tempImg, (y * M, x * M))print('(%d, %d)' % (x, y)) # 打印進度。格式化輸出 x,y# 保存圖片newImg.save('final.jpg') # 最后保存圖片create_image(bgImg, imgDir)

真好,又可以愉快地吸貓了~

最后, 如果本文對你有用的話, 點贊關注收藏支持一波, 持續更新不同的操作, 有你更精彩~~~

原文鏈接:https://blog.csdn.net/m0_50546016/article/details/121766341

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容