必威体育Betway必威体育官网
当前位置:首页 > IT技术

Python爬虫之——爬取妹子图片

时间:2019-10-27 16:42:10来源:IT技术作者:seo实验室小编阅读:74次「手机版」
 

妹子图片

近期很多博友找我咨询问题,我将更新的代码写在最后,由于精力有限只更新单线程

首先声明,本博文为我原创,但是我在看了 崔庆才 博主的文章之后加以自己的实际处理的所得,感谢 崔庆才 博主,写的爬虫文章都好,博主文章地址:http://cuiqingcai.com/3179.html

环境:Python 3.6

注:单线程版以在安卓的Qpython(py2.7)上运行成功

第三方库

requests:解析url

beautifulsoup4:不会正则表达式童鞋的福音,可以容易的提取到html文件中各种标签及其属性

安装方法:

pip install requests

pip install beautifulsoup4

如果有错误请自行解决

目标

http://mzitu.com

话说回来,我半年前就开始学习py爬虫,但当时应该是兴趣不足,导致半途而废,所以说兴趣非常重要,我们的目标应该可以使大家有很大的兴趣,激励自己学习爬虫。

原理

学习爬虫,首先是要学习它的原理。打开网址(为了防止和谐我就不上图了 ),大家可以发现,一共有141页,每页都有很多套图,如果要你手动去保存,怎么操作?我想应该是这样,从第一页开始,点进第一个套图,然后保存每张图片,然后进行第二个套图…第一页完了之后第二页,从第一个套图开始,保存保存…这就是原理,当然,虽然这样能达到这个目的,但大家应该没有那么多的时间,那么我们就来学习爬虫,来替我们保存图片。

步骤

1.获取网页源码

浏览器的F12可以看到网页的源码,但我们现在要用python这样做。

#coding=utf-8

import requests

url = 'http://www.mzitu.com'

#设置headers网站会根据这个判断你的浏览器及操作系统,很多网站没有此信息将拒绝你访问
header = {
        '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'}

#用get方法打开url并发送headers
html = requests.get(url,headers = header)

#打印结果 .text是打印出文本信息即源码
print(html.text)

如果没问题的话结果会是这样类似

......
        $("#index_banner_load").find("p").appendTo("#index_banner");
        $("#index_banner").css("height", 90);
        $("#index_banner_load").remove();
});
</script>
</body>
</html>

这些就是网页的源码了。

2.寻找所需信息

切换浏览器,右键‘查看网页源代码’,可以发现有很多这样的信息

<li><a href="http://www.mzitu.com/89334" target="_blank"><img width='236' height='354' class='lazy' alt='我是标题我是标题我是标题我是标题我是标题我是标题' src='http://i.meizitu.net/pfiles/img/lazy.png' data-original='http://i.meizitu.net/thumbs/2017/04/89334_02b06_236.jpg' /></a><span><a href="http://www.mzitu.com/89334" target="_blank">我是标题我是标题我是标题我是标题我是标题我是标题我是标题我是标题我是标题我是标题</a></span><span class="time">2017-04-02</span><span class="view">6,788次</span></li>

那么我们只需要提取这些东西就可以了…but:我写不出这么复杂的正则!!!没关系,我们的神器BeautifulSoup要上场了!

我们的步骤是:①将获取的源码转换为BeautifulSoup对象②搜索需要的数据

#coding=utf-8

import requests
from bs4 import BeautifulSoup

url = 'http://www.mzitu.com'
header = {
        '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'}

html = requests.get(url,headers = header)

#使用自带的html.parser解析,速度慢但通用
soup = BeautifulSoup(html.text,'html.parser')

#实际上是第一个class = 'postlist'的p里的所有a 标签是我们要找的信息
all_a = soup.find('p',class_='postlist').find_all('a',target='_blank')

for a in all_a:
    title = a.get_text() #提取文本
    print(title)

这样就找到了当页所有套图的标题

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

3.进入下载

点进一个套图之后,发现他是每个页面显示一个图片。

最大页数

比如http://www.mzitu.com/26685是某个套图的第一页,后面的页数都是再后面跟/和数字http://www.mzitu.com/26685/2 (第二页),那么很简单了,我们只需要找到他一共多少页,然后用循环组成页数就OK了。

#coding=utf-8

import requests
from bs4 import BeautifulSoup

url = 'http://www.mzitu.com/26685'
header = {
        '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'}

html = requests.get(url,headers = header)
soup = BeautifulSoup(html.text,'html.parser')

#最大页数在span标签中的第10个
pic_max = soup.find_all('span')[10].text
print(pic_max)

#输出每个图片页面的地址
for i in range(1,int(pic_max) + 1):
    href = url+'/'+str(i)
    print(href)

好了,那么我们接下来就是进行寻找图片地址并且保存了,右键妹纸图片,“检查”可以发现

图片具体地址

<img src="http://i.meizitu.net/2014/07/20140711w11.jpg" alt="Beautyleg 美腿写真 No.997 Dora">

那么这就是图片的具体地址了

那么我们的目的就要达成,保存它。

#coding=utf-8

import requests
from bs4 import BeautifulSoup

url = 'http://www.mzitu.com/26685'
header = {
        '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'}

html = requests.get(url,headers = header)
soup = BeautifulSoup(html.text,'html.parser')

#最大页数在span标签中的第10个
pic_max = soup.find_all('span')[10].text

#找标题
title = soup.find('h2',class_='main-title').text

#输出每个图片页面的地址
for i in range(1,int(pic_max) + 1):
    href = url+'/'+str(i)
    html = requests.get(href,headers = header)
    mess = BeautifulSoup(html.text,"html.parser")


    #图片地址在img标签alt属性和标题一样的地方
    pic_url = mess.find('img',alt = title)

    html = requests.get(pic_url['src'],headers = header)

    #获取图片的名字方便命名
    file_name = pic_url['src'].split(r'/')[-1]

    #图片不是文本文件,以二进制格式写入,所以是html.content
    f = open(file_name,'wb')
    f.write(html.content)
    f.close()

不出意外你脚本所在的地方会有12张图片

4.批量下载

上面讲了如何下载一个套图,其实所有的套图下载只是加上两重循环。成品如下:

#coding=utf-8
import requests
from bs4 import BeautifulSoup
import os
import sys
'''
#安卓端需要此语句
reload(sys)
sys.setdefaultencoding('utf-8')
'''

if(os.name == 'nt'):
        print(u'你正在使用win平台')
else:
        print(u'你正在使用linux平台')

header = {'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'}
#http请求头
all_url = 'http://www.mzitu.com'
start_html = requests.get(all_url,headers = header)

#保存地址
path = 'D:/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/'
for n in range(1,int(max_page)+1):
    ul = same_url+str(n)
    start_html = requests.get(ul, headers=header)
    soup = BeautifulSoup(start_html.text,"html.parser")
    all_a = soup.find('p',class_='postlist').find_all('a',target='_blank')
    for a in all_a:
        title = a.get_text() #提取文本
        if(title != ''):
            print("准备扒取:"+title)
            
            #win不能创建带?的目录
            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('?',''))
            href = a['href']
            html = requests.get(href,headers = header)
            mess = BeautifulSoup(html.text,"html.parser")
            pic_max = mess.find_all('span')
            pic_max = pic_max[10].text #最大页数
            if(flag == 1 and len(os.listdir(path+title.strip().replace('?',''))) >= int(pic_max)):
                print('已经保存完毕,跳过')
                continue
            for num in range(1,int(pic_max)+1):
                pic = href+'/'+str(num)
                html = requests.get(pic,headers = header)
                mess = BeautifulSoup(html.text,"html.parser")
                pic_url = mess.find('img',alt = title)
                html = requests.get(pic_url['src'],headers = header)
                file_name = pic_url['src'].split(r'/')[-1]
                f = open(file_name,'wb')
                f.write(html.content)
                f.close()
            print('完成')
    print('第',n,'页完成')

5.升级多进程版

#coding=utf-8
import requests
from bs4 import BeautifulSoup
import os
from multiprocessing import Pool
import sys


def find_MaxPage():
    all_url = 'http://www.mzitu.com'
    start_html = requests.get(all_url,headers = header)
    #找寻最大页数
    soup = BeautifulSoup(start_html.text,"html.parser")
    page = soup.find_all('a',class_='page-numbers')
    max_page = page[-2].text
    return max_page

def Download(href,header,title,path):
    html = requests.get(href,headers = header)
    soup = BeautifulSoup(html.text,'html.parser')
    pic_max = soup.find_all('span')
    pic_max = pic_max[10].text  # 最大页数
    if(os.path.exists(path+title.strip().replace('?','')) and len(os.listdir(path+title.strip().replace('?',''))) >= int(pic_max)):
        print('已完毕,跳过'+title)
        return 1
    print("开始扒取:" + title)
    os.makedirs(path+title.strip().replace('?',''))
    os.chdir(path + title.strip().replace('?',''))
    for num in range(1,int(pic_max)+1):
        pic = href+'/'+str(num)
        #print(pic)
        html = requests.get(pic,headers = header)
        mess = BeautifulSoup(html.text,"html.parser")
        pic_url = mess.find('img',alt = title)
        html = requests.get(pic_url['src'],headers = header)
        file_name = pic_url['src'].split(r'/')[-1]
        f = open(file_name,'wb')
        f.write(html.content)
        f.close()
    print('完成'+title)

def download(href,header,title):

    html = requests.get(href,headers = header)
    soup = BeautifulSoup(html.text,'html.parser')
    pic_max = soup.find_all('span')
    #for j in pic_max:
        #print(j.text)
    #print(len(pic_max))
    pic_max = pic_max[10].text  # 最大页数
    print(pic_max)


'''
#安卓端需要此语句
reload(sys)
sys.setdefaultencoding('utf-8')
'''


if __name__=='__main__':
    if (os.name == 'nt'):
        print(u'你正在使用win平台')
    else:
        print(u'你正在使用linux平台')

    header = {
        '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'}
    # http请求头
    path = 'D:/mzitu/'
    max_page = find_MaxPage()
    same_url = 'http://www.mzitu.com/page/'

	#线程池中线程数
    pool = Pool(5)
    for n in range(1,int(max_page)+1):
        each_url = same_url+str(n)
        start_html = requests.get(each_url, headers=header)
        soup = BeautifulSoup(start_html.text, "html.parser")
        all_a = soup.find('p', class_='postlist').find_all('a', target='_blank')
        for a in all_a:
            title = a.get_text()  # 提取文本
            if (title != ''):
                href = a['href']
                pool.apply_async(Download,args=(href,header,title,path))
    pool.close()
    pool.join()
    print('所有图片已下完')

最后结果在这:

这里写图片描述

完结撒花~~~

2019-6-23更新

下载可用,记录已下载内容,修复偶尔网页加载错误

#coding=utf-8
import requests
from bs4 import BeautifulSoup
import os
import time

all_url = 'http://www.mzitu.com'


#http请求头
Hostreferer = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
    'Referer': 'http://www.mzitu.com'
               }
Picreferer = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
    'Referer': 'http://i.meizitu.net'
}
#此请求头破解盗链



#保存地址
path = '/Users/liyutong/mzitu/'

#记录文件
data = '/Users/liyutong/mzitu/.data'

#读取保存记录
def get_log(file):
    page = 1
    line = 0
    try:
        with open(file, 'r') as f:
            l = f.readline()
            page, line = [int(i) for i in l.split('|')]
    except Exception as e:
        print(e)
        print('读取记录失败,从初始开始')
    return page, line


#保存记录
def put_log(file, page, line):
    try:
        with open(file, "w") as f:
            f.write('{}|{}'.format(page, line))
    except Exception as e:
        print('保存记录失败:[{}]'.format(e))


#找寻最大页数
def find_max_page():
    start_html = requests.get(all_url, headers=Hostreferer)
    soup = BeautifulSoup(start_html.text, "html.parser")
    page = soup.find_all('a', class_='page-numbers')
    max_page = page[-2].text
    max_page = int(max_page)
    return max_page

if __name__ == "__main__":
    same_url = 'http://www.mzitu.com/page/'
    max_page = find_max_page()
    page, line = get_log(data)
    print('从{}页,{}行开始缓存'.format(page, line))
    for n in range(page, int(max_page)+1):
        ul = same_url+str(n)
        start_html = requests.get(ul, headers=Hostreferer)
        soup = BeautifulSoup(start_html.text, "html.parser")
        all_a = soup.find('p', class_='postlist').find_all('a', target='_blank')
        for lines in range(line, len(all_a)):
            a = all_a[lines]
            title = a.get_text() #提取文本
            if(title != ''):
                print("准备扒取:"+title)

                #win不能创建带?的目录
                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('?', ''))
                href = a['href']
                html = requests.get(href, headers=Hostreferer)
                mess = BeautifulSoup(html.text, "html.parser")
                # 最大也在class='pagenavi'p中的第6个span
                pic_max = mess.find("p", class_='pagenavi').find_all('span')
                pic_max = pic_max[6].text #最大页数
                if(flag == 1 and len(os.listdir(path+title.strip().replace('?',''))) >= int(pic_max)):
                    print('已经保存完毕,跳过')
                    continue
                for num in range(1, int(pic_max)+1):
                    while True:
                        pic = href+'/'+str(num)
                        html = requests.get(pic, headers=Hostreferer)
                        mess = BeautifulSoup(html.text, "html.parser")
                        pic_url = mess.find('img', alt=title)
                        if(pic_url):
                            break
                    # 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()
                put_log(data, n, lines)
                time.sleep(0.5)
        print('第',n,'页完成')
        line = 0
        time.sleep(10)

文章最后发布于: 2017-04-03 16:19:43

相关阅读

Python爬虫——爬取阳光高考网高校信息

在本次学习中主要爬取的内容如下就简单粗暴直接献上代码吧import requests import time import json from bs4 import BeautifulS

猫眼 — 破解数字反爬获取实时票房

From:https://zhuanlan.zhihu.com/p/33112359 js分析 猫_眼_电_影 字体文件 @font-face:https://www.cnblogs.com/my8100/p/js_maoy

相互保支付宝红包领取了怎么使用?

支付宝上的相互保是蚂蚁保险和芝麻信用联合推出的一种保险,也是大病互助计划,加入是不需要花钱的,还能够享受到30万元的大病保障哦,现

C#获取CPU温度

/// <summary> /// 获取cpu温度 /// </summary> /// <returns></returns> internal static s

成都市住房公积金提取指南办理手续流程

成都市住房公积金提取指南办理手续流程 http://cdzfgjj.chengdu.gov.cn/cdzfgjj/c118013/jk_fwzndet.shtml?detailid=1012 提

分享到:

栏目导航

推荐阅读

热门阅读