发福利,Python3爬取MZITU

网址

引言

最近有点忙,没怎么学习python,心中无限的罪恶感油然而生,趁着周末打算沉下心学习学习,爬点好玩的东西给single dog发福利

装点工具库

pip对win似乎并不是那么友好,如果安装一些库失败的话,可以尝试升级pip或是以管理员身份运行
- requests (一款网络请求特别棒的库)
- BeautifulSoup (爬数据需要用到的库,如何使用
- lxml (增快BeautifulSoup解析页面的速度)

分析mzitu页面

mzitu链接http://www.mzitu.com/all

我们用postman或是debug当前页面来查看一下页面节点,找找有没有规律

我们看看画红线的部分,每一个跳转查看妹子的图片都有一个规律,那就是a标签都有一个target属性,我们来编码试试

定义一个获取页面的方法,这里面需要注意的是请求头中的Referer,这个是在论坛里面找到的,如果没加的话,爬取的时候获取到的图片全是请勿盗链的图
def downHtml(url):
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240",
        'Connection': 'Keep-Alive',
        'Referer': "http://www.mzitu.com/99566"
    }
    return requests.get(url, headers=headers).text

定义一个解析妹子总页面的方法,来获取单个妹子的链接

def parseHtml(html):
    soup = BeautifulSoup(html, "lxml")
    list = soup.select("a[target='_blank']")
    count=0 #添加一个统计链接的数量
    for a in list:
        print(a["href"], a.get_text())
    print(count)

运行

html = downHtml("http://www.mzitu.com/all")
parseHtml(html)

效果图


多达1901个妹子,我的天,这下爽到爆了

分析mzitu单个妹子页面

既然我们拿到所有妹子的url了,那么,我们随便点击一个url去分析一下页面

根据页面的分析,请看上图两处标红的位置,第一处是妹子的图片,第二处是总共的页码,我们可以看到,第二处标红是一个分页,每一个查看详情页的链接后面跟着的是页码,他是有规律的

我们先看第二处标红的地方,因为拿到所有的url也就意味着可以拿到妹子所有的图片,贴一点关键代码来分析

 <div class="pagenavi">
     <a href='http://www.mzitu.com/108361'>
        <span>&laquo;上一组</span>
     </a>
     <span>1</span>
     <a href='http://www.mzitu.com/108330/2'>
        <span>2</span>
     </a>
     <a href='http://www.mzitu.com/108330/3'>
        <span>3</span>
     </a>
     <a href='http://www.mzitu.com/108330/4'>
        <span>4</span>
     </a>
     <span class='dots'></span>
     <a href='http://www.mzitu.com/108330/30'>
        <span>30</span>
     </a>
     <a href='http://www.mzitu.com/108330/2'>
        <span>下一页&raquo;</span>
     </a>
 </div>

根据这段代码来看,每张图片的详情页都是由主链接加页码形成,也就是说,我们只要拿到页码,然后遍历这个页码添加到主链接的后面,我们就可以拿到每张图片,所以,页码数量30才是我们最关心的地方,我们首先可以根据div class=”pagenavi”来获取整个页码代码,获取到整个页码代码后,我们可以看到,页码30永远都是在倒数第二个span标签,这个时候,我们可以来编码了

编码

def get_pic_num(html):
    soup = BeautifulSoup(html, "lxml")
    list = soup.find("div", class_="pagenavi").find_all("span")
    return int(list[-2].string)

运行

html = downHtml("http://www.mzitu.com/108330")
num = get_pic_num(html)
print(num)

效果图

好了,现在已经拿到图片数量了,然后,我们只需要遍历数量,将页码添加到妹子链接的后面形成妹子详情页url,然后我们在遍历的过程中,每访问一个url就去取出图片的url,那么,接下来如何取图片又是重中之重了


我们先想怎么取图片吧,截取一段代码

  <div class="main-image">
     <p>
        <a href="http://www.mzitu.com/108330/2" >
           <img src="http://i.meizitu.net/2017/11/08a01.jpg" alt="夏美酱:好玩不过黑丝腿,最美不如兔女郎" />
        </a>
     </p>
  </div>

这个地方有个div class=”main-image”,我们可以先从他入手,先找到该节点,然后去找他所有的子节点是img标签的节点,因为img标签只有一个,所以自然而然的就可以定位到图片

编码

拼接url

for i in range(num):

    str = "{}{}{}".format(pic, "/", i + 1)
    html = downHtml(str)
    t = threading.Thread(target=get_pic, args=(html,))
    t.start()
    t.join()

这个地方我开了个线程去处理,因为我们需要将这个图片下载到本地

获取图片

def get_pic(html):
    soup = BeautifulSoup(html, "lxml")
    img = soup.find("div", class_="main-image").find_all("img")
    print(img[0]["src"], img[0]["alt"])
    download_pic(img[0]["src"]) #下载图片

下载图片

def download_pic(url):
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240",
        'Connection': 'Keep-Alive',
        'Referer': "http://www.mzitu.com/99566"
    }
    img = requests.get(url, headers=headers)
    t = time.time()
    nowTime = lambda: int(round(t * 1000))
    with  open("{}.jpg".format(nowTime()), 'ab') as f:
        f.write(img.content)

这个地方用了time库,以时间戳来给存储在本地的图片命名

效果图

all code

import threading
import time
import requests
from bs4 import BeautifulSoup

url = "http://www.mzitu.com/all"
pic = "http://www.mzitu.com/108528"

''' 获取html页面'''
def downHtml(url):
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240",
        'Connection': 'Keep-Alive',
        'Referer': "http://www.mzitu.com/99566"
    }
    return requests.get(url, headers=headers).text

''' 解析获取所有的妹子url  '''
def parseHtml(html):
    soup = BeautifulSoup(html, "lxml")
    list = soup.select("a[target='_blank']")
    count = 0  # 添加一个统计链接的数量
    for a in list:
        print(a["href"], a.get_text())
    print(count)


''' 获取妹子所有图片的数量 '''
def get_pic_num(html):
    soup = BeautifulSoup(html, "lxml")
    list = soup.find("div", class_="pagenavi").find_all("span")
    return int(list[-2].string)

''' 获取妹子的图片 '''
def get_pic(html):
    soup = BeautifulSoup(html, "lxml")
    img = soup.find("div", class_="main-image").find_all("img")
    print(img[0]["src"], img[0]["alt"])
    download_pic(img[0]["src"])

''' 下载妹子的图片 '''
def download_pic(url):
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240",
        'Connection': 'Keep-Alive',
        'Referer': "http://www.mzitu.com/99566"
    }
    img = requests.get(url, headers=headers)
    t = time.time()
    nowTime = lambda: int(round(t * 1000))
    with  open("{}.jpg".format(nowTime()), 'ab') as f:
        f.write(img.content)

# 获取所有妹子的url
# html = downHtml(url)
# parseHtml(html)

#获取妹子所有的图片
html = downHtml(pic)
num = get_pic_num(html)
for i in range(num):
    str = "{}{}{}".format(pic, "/", i + 1)
    html = downHtml(str)
    t = threading.Thread(target=get_pic, args=(html,))
    t.start()
    t.join()

总结

由于图片太多,代码部分我是分了两个部分,第一个部分我是获取所有妹子的url,第二个部分随便拿了一个妹子的url去获取她所有的图片,整体分析下来不是太难
爬虫是一个很有意思的技术,我们可以将这些数据爬下来存进数据库,然后进行数据分析,接下来,朝这个目标迈进,最后附上福利图。

哎呀,羞羞

猜你喜欢

转载自blog.csdn.net/u013000152/article/details/78512443
今日推荐