使用Python爬取妹子图高清图片

项目分析函数编写梳理过程编写源代码总结项目项目分析

通过分析整个网站,分为性感、台湾、清纯、妹子、街拍、每日更新等项目,发现通过每日更新这个项目,可以找到从2015到2019年全部更新的图片。

每日更新内容分析

从每日更新页面源代码我们可以分析如下爬取思路。

网页源代码分析

我们从网页源代码中提取出列表archives的内容,然后通过列表内容分析提取出每一个列表项目,即每一张图片的地址信息。

每张图片名称及地址信息

我们打开任意一个图片链接来分析每组图片中的图片网址信息。

单张图片名称及下载地址

函数编写

这个项目我们使用过程化变成方法。通过上面的过程分析,我们按照整个爬取事件的过程,分为以下几个函数

获取页面源代码

def getHtml(url='https://妹子图主页/all/'):'''获取所有图片的网页源代码''' 
req = requests.get(headers=header, url=url).text 
return req

获取archives列表的内容

def getTags(html,reg=r'<div class="year">([\s\S]+?)</div><ul class="archives">([\s\S]+?)</ul>'): '''获取ul标签内容,返回5个元组(年份,图片名称、网址)''' 

pattern = re.compile(reg, re.S) 

tags = re.findall(pattern, html) 

return tags

将图片网址信息进行拆分

def getThumList(html):'''获取图片、网址信息进行拆分''' 

img_list = [] 

result = BeautifulSoup(html, 'lxml').findAll('a') 

for item in result: img_list.append((item.text, item['href']))

eturn img_list

数据通过统一格式返回

def resultData(tags):'''将数据以统一格式返回{年份:[(标题,网址)……],}''' resultDict = {} for item in tags: resultDict[item[0]] = getThumList(item[1]) return resultDict

图片下载函数

def downloadImg(img_url, file_path):req = requests.get(headers=header, url=img_url) with open(file_path, 'wb') as f: f.write(req.content)

创建图片名称的文件夹

def createDir(dirName):'''建立一个图片名称文件夹''' if os.path.exists(dirName): print("文件夹已经存在了") curDir=dirName os.chdir(dirName) else: curDir = os.getcwd() curDir = curDir + os.sep + dirName os.mkdir(curDir) os.chdir(curDir) # print(curDir)

每组图片下载成功后,返回上级一目录

def dirParent():'''返回上一级文件夹''' 

parDir = os.path.abspath(os.path.dirname(os.getcwd())) 

os.chdir(parDir) print(os.getcwd())

获得图片页面的每张图片的地址

def getOnepageImg(tuple_info):req = requests.get(headers=header, url=tuple_info[1]).text soup = BeautifulSoup(req, 'lxml') img = soup.findAll('img', {'alt': str(tuple_info[0])})

 # 创建文件夹 createDir(tuple_info[0]) 

# 创建开始爬取网址 startUrl = img[0]['src'] 

# 获取图片索引内容 yema = soup.find('div', {'class': 'pagenavi'}) result = getTags(str(yema), reg=r'<span>(\d{1,3})</span>') 

# 图片张数 maxNumber = int(max(result)) print('图片组《%s》开始下载,这组图片有%d张图片' % (str(tuple_info[0]), maxNumber)) for i in range(maxNumber): curUrl = startUrl[:-6] + changeFormat(i+1) + '.jpg' 

# 在当前文件夹下下载图片,名称为文件的索引名称 downloadImg(curUrl, str(i+1) + '.jpg') print('\t<文件' + str(i+1) + '.jpg 下载成功 !>') # 返回上级目录 dirParent() print('【下一组图片开始下载】')

梳理过程

这个项目的过程很简单,主要是从网页源代码中获取制定ul的列表内容(通过BeautifulSoup获取),然后,通过从获取的专题中逐个获取每一页的图片数目和内容,逐一进行下载。主要难点有两个,一个是获取网页源代码的时候加入请求头进行获取,如果没有加入请求头,则获取不到网页源代码和图片信息;再者就是网页中的图片地址递归获取,从图片地址中找出图片网址规律,从而获得每一张图片的具体地址。

编写源代码

这一步我们将上面几个函数组装起来就可以了,通过过程的梳理,我们来组装试一试哦,源代码如下。

# /usr/bin/python#

coding:utf-8

import requests, re, osfrom bs4

import BeautifulSoupheader = {'Referer': 'https://www.mzitu.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:46.0) Gecko/20100101 Firefox/46.0'}

def getHtml(url='https://www.mzitu.com/all/'): '''获取所有图片的网页源代码''' 

req = requests.get(headers=header, url=url).text 

return reqdef

getTags(html, reg=r'<div class="year">([\s\S]+?)</div><ul class="archives">([\s\S]+?)</ul>'): '''获取ul标签内容,返回5个元组(年份,图片名称、网址)''' 

pattern = re.compile(reg, re.S) 

tags = re.findall(pattern, html) 

return tags

def getThumList(html): '''获取图片、网址信息进行拆分'''

 img_list = [] result = BeautifulSoup(html, 'lxml').findAll('a') 

for item in result: img_list.append((item.text, item['href'])) 

return img_list

def resultData(tags): '''将数据以统一格式返回{年份:[(标题,网址)....],}''' 

resultDict = {} 

for item in tags: resultDict[item[0]] = getThumList(item[1]) 

return resultDictdef changeFormat(a_number): '''将一个小于10的整数前面加一个0,并以字符串形式返回'''

if int(a_number) > 0 and int(a_number) <= 9: a_number = '0' + str(a_number)

else: a_number = str(a_number) return a_numberdef

downloadImg(img_url, file_path): req = requests.get(headers=header, url=img_url) with open(file_path, 'wb') as f: f.write(req.content)def createDir(dirName): '''建立一个图片名称文件夹'''

if os.path.exists(dirName): print("文件夹已经存在了")

curDir=dirName os.chdir(dirName)

else: curDir = os.getcwd() curDir = curDir + os.sep + dirName

os.mkdir(curDir) os.chdir(curDir)

# print(curDir)

def dirParent(): '''返回上一级文件夹''' parDir = os.path.abspath(os.path.dirname(os.getcwd())) os.chdir(parDir) print(os.getcwd())def getOnepageImg(tuple_info): req = requests.get(headers=header, url=tuple_info[1]).text soup = BeautifulSoup(req, 'lxml')

img = soup.findAll('img', {'alt': str(tuple_info[0])})

# 创建文件夹 createDir(tuple_info[0])

# 创建开始爬取网址 startUrl = img[0]['src']

# 获取图片索引内容 yema = soup.find('div', {'class': 'pagenavi'}) result = getTags(str(yema), reg=r'<span>(\d{1,3})</span>')

# 图片张数 maxNumber = int(max(result)) print('图片组《%s》开始下载,这组图片有%d张图片' % (str(tuple_info[0]), maxNumber)) for i in range(maxNumber): curUrl = startUrl[:-6] + changeFormat(i+1) + '.jpg'

# 在当前文件夹下下载图片,名称为文件的索引名称 downloadImg(curUrl, str(i+1) + '.jpg') print('\t<文件' + str(i+1) + '.jpg 下载成功 !>')

# 返回上级目录 dirParent() print('【下一组图片开始下载】')if __name__ == "__main__":

# 获取网页源代码 req = getHtml()

# 获取archives列表内容 tags = getTags(req)

# 将图片列表作为字典返回 resultData = resultData(tags)

# 解析字典,逐个项目进行下载 for key, value in resultData.items():

# 创建年度文件夹 createDir(str(key)) for item in value: getOnepageImg(item)

# 返回上一级文件夹 print(str(key) + '年度文件夹下载成功') dirParent()

图片爬取结果

总结项目

项目基本可以爬取成功,但是存在两个问题,一是爬取速度较慢,如果加入多线程,项目就更加完美了;其次,对于异常处理,程序涉及的比较少,由于下载的图片过多,网速原因,哪些图片下载成功哪些图片没有下载成功,这是一个问题,如果在程序中能够记录一下,就更完美了,感兴趣的朋友可以留言探讨。

爬取结果展示

 

分享到:

未经允许不得转载:just.do.it专注java开发 » 使用Python爬取妹子图高清图片

赞 (0) 打赏

评论 0

评论前必须登录!

登陆 注册

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

Optimized by WPJAM Basic