目标网站:妹子图网
环境: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()