1. 程式人生 > >發福利,Python3爬取MZITU

發福利,Python3爬取MZITU

網址

引言

最近有點忙,沒怎麼學習python,心中無限的罪惡感油然而生,趁著週末打算沉下心學習學習,爬點好玩的東西給single dog發福利

裝點工具庫

pip對win似乎並不是那麼友好,如果安裝一些庫失敗的話,可以嘗試升級pip或是以管理員身份執行
- requests (一款網路請求特別棒的庫)
- BeautifulSoup (爬資料需要用到的庫,如何使用
- lxml (增快BeautifulSoup解析頁面的速度)

分析mzitu頁面

我們用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去獲取她所有的圖片,整體分析下來不是太難
爬蟲是一個很有意思的技術,我們可以將這些資料爬下來存進資料庫,然後進行資料分析,接下來,朝這個目標邁進,最後附上福利圖。

哎呀,羞羞