爬虫福利 之 妹子图网MM批量下载

时间:2024-02-20 11:48:50

目标网站:妹子图网

环境:Python3.x

相关第三方模块:requests、beautifulsoup4

Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import os
 
all_url = \'https://www.mzitu.com\'
 
# http请求头
Hostreferer = {
    \'User-Agent\': \'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\',
    \'Referer\': \'http://www.mzitu.com\'
}
# 此请求头Referer破解盗图链接
Picreferer = {
    \'User-Agent\': \'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\',
    \'Referer\': \'http://i.meizitu.net\'
}
 
# 对mzitu主页all_url发起请求,将返回的HTML数据保存,便于解析
start_html = requests.get(all_url, headers=Hostreferer)
 
# Linux保存地址
# path = \'/home/Nick/Desktop/mzitu/\'
 
# Windows保存地址
path = \'E:/mzitu/\'
 
# 获取最大页数
soup = BeautifulSoup(start_html.text, "html.parser")
page = soup.find_all(\'a\', class_=\'page-numbers\')
max_page = page[-2].text
 
 
# same_url = \'http://www.mzitu.com/page/\'   # 主页默认最新图片
# 获取每一类MM的网址
same_url = \'https://www.mzitu.com/mm/page/\'     # 也可以指定《qingchun MM系列》
 
for n in range(1, int(max_page) + 1):
    # 拼接当前类MM的所有url
    ul = same_url + str(n)
 
    # 分别对当前类每一页第一层url发起请求
    start_html = requests.get(ul, headers=Hostreferer)
 
    # 提取所有MM的标题
    soup = BeautifulSoup(start_html.text, "html.parser")
    all_a = soup.find(\'div\', class_=\'postlist\').find_all(\'a\', target=\'_blank\')
 
    # 遍历所有MM的标题
    for a in all_a:
        # 提取标题文本,作为文件夹名称
        title = a.get_text()
        if(title != \'\'):
            print("准备扒取:" + title)
 
            # windows不能创建带?的目录,添加判断逻辑
            if(os.path.exists(path + title.strip().replace(\'?\', \'\'))):
                # print(\'目录已存在\')
                flag = 1
            else:
                os.makedirs(path + title.strip().replace(\'?\', \'\'))
                flag = 0
            # 切换到上一步创建的目录
            os.chdir(path + title.strip().replace(\'?\', \'\'))
 
            # 提取第一层每一个MM的url,并发起请求
            href = a[\'href\']
            html = requests.get(href, headers=Hostreferer)
            mess = BeautifulSoup(html.text, "html.parser")
 
            # 获取第二层最大页数
            pic_max = mess.find_all(\'span\')
            pic_max = pic_max[9].text
            if(flag == 1 and len(os.listdir(path + title.strip().replace(\'?\', \'\'))) >= int(pic_max)):
                print(\'已经保存完毕,跳过\')
                continue
 
            # 遍历第二层每张图片的url
            for num in range(1, int(pic_max) + 1):
                # 拼接每张图片的url
                pic = href + \'/\' + str(num)
 
                # 发起请求
                html = requests.get(pic, headers=Hostreferer)
                mess = BeautifulSoup(html.text, "html.parser")
                pic_url = mess.find(\'img\', alt=title)
                print(pic_url[\'src\'])
                html = requests.get(pic_url[\'src\'], headers=Picreferer)
 
                # 提取图片名字
                file_name = pic_url[\'src\'].split(r\'/\')[-1]
 
                # 保存图片
                f = open(file_name, \'wb\')
                f.write(html.content)
                f.close()
            print(\'完成\')
    print(\'\', n, \'页完成\')

扒图步骤分析:(送给有兴趣的朋友) 

1、获取网页源码

打开mzitu网址,用浏览器的F12可以看到网页的请求过程及源码

该步骤代码如下: 

 1 #coding=utf-8
 2  
 3 import requests
 4  
 5 url = \'http://www.mzitu.com\'
 6  
 7 #设置headers,网站会根据这个判断你的浏览器及操作系统,很多网站没有此信息将拒绝你访问
 8 header = {
 9         \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36\'}
10  
11 #用get方法打开url并发送headers
12 html = requests.get(url,headers = header)
13  
14 #打印结果 .text是打印出文本信息即源码
15 print(html.text)

 

返回的响应,如果没问题的话结果和下面类似,这些就是网页的源码了。

 

 1 <html>
 2 <body>
 3  
 4 ......
 5  
 6         $("#index_banner_load").find("div").appendTo("#index_banner");
 7         $("#index_banner").css("height", 90);
 8         $("#index_banner_load").remove();
 9 });
10 </script>
11 </body>
12 </html>

2、提取所需信息

  • 将获取的源码转换为BeautifulSoup对象
  • 使用find搜索需要的数据,保存到容器中

该步骤代码如下:

 1 #coding=utf-8
 2  
 3 import requests
 4 from bs4 import BeautifulSoup
 5  
 6 url = \'http://www.mzitu.com\'
 7 header = {
 8         \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36\'}
 9  
10 html = requests.get(url,headers = header)
11  
12 #使用自带的html.parser解析,速度慢但通用
13 soup = BeautifulSoup(html.text,\'html.parser\')
14  
15 #实际上是第一个class = \'postlist\'的div里的所有a 标签是我们要找的信息
16 all_a = soup.find(\'div\',class_=\'postlist\').find_all(\'a\',target=\'_blank\')
17  
18 for a in all_a:
19     title = a.get_text() #提取文本
20     print(title)

如下就找到了当页所有套图的标题:

1 注意:BeautifulSoup()返回的类型是<class \'bs4.BeautifulSoup\'>
2 find()返回的类型是<class \'bs4.element.Tag\'>
3 find_all()返回的类型是<class \'bs4.element.ResultSet\'>
4 <class \'bs4.element.ResultSet\'>不能再进项find/find_all操作

 

 3、进入第二层页面,进行下载操作

 

点进一个套图之后,发现他是每个页面显示一个图片,这时我们需要知道他的总页数,比如:http://www.mzitu.com/26685是某个套图的第一页,后面的页数都是再后面跟/和数字http://www.mzitu.com/26685/2 (第二页),那么很简单了,我们只需要找到他一共多少页,然后用循环组成页数就OK

 

 

 

该步骤代码如下: 

 1 #coding=utf-8
 2  
 3 import requests
 4 from bs4 import BeautifulSoup
 5  
 6 url = \'http://www.mzitu.com/26685\'
 7 header = {
 8         \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36\'}
 9  
10 html = requests.get(url,headers = header)
11 soup = BeautifulSoup(html.text,\'html.parser\')
12  
13 #最大页数在span标签中的第10个
14 pic_max = soup.find_all(\'span\')[10].text
15 print(pic_max)
16  
17 #输出每个图片页面的地址
18 for i in range(1,int(pic_max) + 1):
19     href = url+\'/\'+str(i)
20     print(href)

 

那么我们接下来就是进行寻找图片地址,保存下来;右键MM图片,点击检查可以发现如图:

 

1 <img src="https://i5.meizitu.net/2019/07/01b56.jpg" alt="xxxxxxxxxxxxxxxxxxxxxxxxx" width="728" height="485">

 

如图所示,上面就是我们MM图片的具体地址了,保存它即可。

该步骤代码如下:

 1 #coding=utf-8
 2  
 3 import requests
 4 from bs4 import BeautifulSoup
 5  
 6 url = \'http://www.mzitu.com/26685\'
 7 header = {
 8         \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36\'}
 9  
10 html = requests.get(url,headers = header)
11 soup = BeautifulSoup(html.text,\'html.parser\')
12  
13 #最大页数在span标签中的第10个
14 pic_max = soup.find_all(\'span\')[10].text
15  
16 #找标题
17 title = soup.find(\'h2\',class_=\'main-title\').text
18  
19 #输出每个图片页面的地址
20 for i in range(1,int(pic_max) + 1):
21     href = url+\'/\'+str(i)
22     html = requests.get(href,headers = header)
23     mess = BeautifulSoup(html.text,"html.parser")
24  
25  
26     #图片地址在img标签alt属性和标题一样的地方
27     pic_url = mess.find(\'img\',alt = title)
28  
29     html = requests.get(pic_url[\'src\'],headers = header)
30  
31     #获取图片的名字方便命名
32     file_name = pic_url[\'src\'].split(r\'/\')[-1]
33  
34     #图片不是文本文件,以二进制格式写入,所以是html.content
35     f = open(file_name,\'wb\')
36     f.write(html.content)
37     f.close()

完善后的代码已打包成软件,需要可进讨论群:887934385