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