一、背景知识
最近看微信公众号,发现很多有趣的图片,又不想一一保存,遂产生通过 python
爬虫的方式直接一次性解析保存。
在此过程中,使用到re
、requests
、os
、bs4.BeautifulSoup
、time
、PIL
等多个库,算是综合使用了一下。
有所收获。
二、整体思路
- 分析网页源代码
- 获取图片的 URL
- 根据 URL 保存下载
- 根据图片分辨率进行二次过滤
三、具体分析
1.标题
标题存放在 <h1 class>
标签之下,使用 bs.select
即可获取。
2.图片
图片存放在 img
标签之下,对应的 URL
存放在 data-src
字段。
图片路径通过 os.path.exists()
判断是否存在。
图片内容通过 requests.get(url).content
进行下载保存。
四、实操
1.准备工作
import re
import requests
import os
from bs4 import BeautifulSoup
import urllib
import time
from PIL import Image
# 头部文件
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 'Connection': 'close'
}
2.请求网站
# 待爬取网站
url = r'https://mp.weixin.qq.com/s/zyxFlgm_th1KGWwsEylCVQ' # 我今天非得跟你玩
url = r'https://mp.weixin.qq.com/s/xgwt2ujb1AD_d3_iWhLP2Q' # 这些年,我们看过的那些媛们!
# 请求
response = requests.get(url, headers=headers)
print(response.status_code) # 200 代表正常返回
response.raise_for_status() # 如果异常抛出错误
3.bs4解析标题
# bs4解析
bs = BeautifulSoup(response.text, 'html.parser')
title = bs.select('h1')[0].text.strip()
# title = bs.find_all('h1')[0].text.strip()
# 过滤标题中的中文
title = re.findall('[\u4e00-\u9fa5a-zA-Z0-9]+', title, re.S)
title = '-'.join(title)
4.图片解析
# 第1种解析方式
imglist = []
for img in bs.select('img'):
if 'data-src' in img.attrs:
imglist.append(img['data-src'])
# 第2种解析方式
imglist2 = []
imgs = bs.find_all('img', attrs={'data-type':'gif'})
if imgs is not None:
for img in imgs:
print(img['data-src'])
imglist2.append(img['data-src'])
5.路径生成
# 判断路径是否存在
path = r'C:\Users\Hider\Desktop\图片'
if not os.path.exists(path):
os.mkdir(path)
if not os.path.exists(os.path.join(path, title)):
os.mkdir(os.path.join(path, title))
6.图片下载
# 第1种方式下载图片
num = 0
for jpg_url in imglist:
result = requests.get(jpg_url, headers=headers).content
f = open(os.path.join(path, title, str(num+1) + '.gif'), 'wb')
f.write(result)
f.close()
num += 1
print(f'正在下载第{num}张...')
time.sleep(1)
# 第2种方式下载图片
path = r'C:\Users\Hider\Desktop\图片'
for jpg_url in imglist:
try:
picture_name = jpg_url.split('/')[-2]
fmt = jpg_url.split('=')[-1]
result = requests.get(jpg_url, headers=headers).content
with open(path + '\\' + title + '\\' + picture_name + '.' + fmt, 'wb+') as f:
f.write(result)
except Exception as reason:
print(str(reason))
# 第3种方式下载图片 -- 好像快很多!!!
path = r'C:\Users\Hider\Desktop\图片'
for jpg_url in imglist:
try:
picture_name = jpg_url.split('/')[-2]
fmt = jpg_url.split('=')[-1]
# urllib.request.urlretrieve(jpg_url, '{0}{1}.gif'.format(path, picture_name))
urllib.request.urlretrieve(jpg_url, path + '\\' + title + '\\' + picture_name + '.' + fmt)
except Exception as reason:
print(str(reason))
7.图片过滤
# 过滤图片
file_list = os.listdir(os.path.join(path, title))
for file in file_list:
if file.split('.')[-1] == 'gif':
filename = os.path.join(path, title, file)
img = Image.open(filename)
imgSize = img.size
img.close()
# print(imgSize)
if imgSize[0] > 700 and imgSize[1] > 700:
pass
# print(imgSize)
else:
os.remove(filename) # 删除文件
print(file)
五、封装函数
import re
import requests
import os
from bs4 import BeautifulSoup
import urllib
import time
from PIL import Image
def wechat_picture_download(url, path):
# 头部文件
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 'Connection': 'close'
}
# 请求
response = requests.get(url, headers=headers)
print(response.status_code) # 200 代表正常返回
response.raise_for_status() # 如果异常抛出错误
# bs4解析
bs = BeautifulSoup(response.text, 'html.parser')
title = bs.select('h1')[0].text.strip()
# title = bs.find_all('h1')[0].text.strip()
# 过滤标题中的中文
title = re.findall('[\u4e00-\u9fa5a-zA-Z0-9]+', title, re.S)
title = '-'.join(title)
# 解析
imglist = []
for img in bs.select('img'):
if 'data-src' in img.attrs:
imglist.append(img['data-src'])
# 判断路径是否存在
if not os.path.exists(path):
os.mkdir(path)
if not os.path.exists(os.path.join(path, title)):
os.mkdir(os.path.join(path, title))
num = 0
for jpg_url in imglist:
try:
# urllib.request.urlretrieve(jpg_url, '{0}{1}.gif'.format(path, picture_name))
print('正在下载:', str(num+1) + '.gif')
urllib.request.urlretrieve(jpg_url, os.path.join(path, title, str(num+1) + '.gif'))
time.sleep(1)
num += 1
except Exception as reason:
print(str(reason))
print('-'*10,'全部下载完成!!','-'*10)
# 过滤图片
file_list = os.listdir(os.path.join(path, title))
for file in file_list:
if file.split('.')[-1] == 'gif':
filename = os.path.join(path, title, file)
img = Image.open(filename)
imgSize = img.size
img.close()
# print(imgSize)
if imgSize[0] > 100 and imgSize[1] > 100:
pass
# print(imgSize)
else:
os.remove(filename) # 删除文件
print('正在删除:', file)
print('-'*10,'过滤完成!!','-'*10)
return True
# 待爬取网站
# url = r'https://mp.weixin.qq.com/s/zyxFlgm_th1KGWwsEylCVQ' # 我今天非得跟你玩
url = r'https://mp.weixin.qq.com/s/xgwt2ujb1AD_d3_iWhLP2Q' # 这些年,我们看过的那些媛们!
path = r'C:\Users\Hider\Desktop\图片'
wechat_picture_download(url, path)
参考链接:Python 判断文件夹是否存在(OS)
参考链接:抓取微信公众号文章中的图片
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:爬虫学习笔记:微信公众号文章图片下载 - Python技术站