教你用Python爬美之圖APP全站圖片
爬取結果
程式只執行了2h,最後認為程式沒有問題了就關了(我可不是去殺生去了......
執行環境
-
Python 3.5+
-
Windows 10
-
VSCode
如何使用
下載專案原始碼
https://github.com/cexll/Mzitu.net_Spider.git
安裝依賴
$ pip install requests
執行
python3 Spider.py
...
程式共耗時: 80.55049586296082(不儲存圖片到本地的時間)
複製程式碼
儲存圖片需要網路,伺服器等方面,所以不方便測試一般2h~3h能爬完整站
資訊來源
點選APP
這個導航,然後點選下載APP
,
開啟之後
http://apk.meizitu.net/app/mzitu.apk
複製程式碼
APP 下載連結, 嗯.APP開啟之後大致就是這個樣子
沒有涉黃吧 ...............
只想要APP的同學到這裡就可以離開了/滑稽
思路
最近學習了APP
抓取,就想著來試試,結果還是非常順利,好的,接下來開始
抓包工具 Charles
, 通過手機或者模擬器連線 Charles
8888 埠, 安裝好證照就能通過電腦監控手機的網路請求資訊
提供下載地址: https://www.charlesproxy.com/download/
軟體開啟就是這個樣子,具體怎麼安裝證照,我這裡就不講解了,網路上教程還是挺多的
開啟 Proxy
-> Proxy Settings
檢查一下埠是否開啟,接下來通過手機和模擬器連線本地,我這裡就通過手機來演示了,我認為手機還是比模擬器方便的
- 首先
Windows
開啟CMD
,輸入ipconfig
,找到乙太網 IPV4
找到 乙太網介面卡 乙太網
別找到其他的了, 我這裡的 IPV4 地址
是 192.168.1.49
,所以手機應該設定代理為 IP 192.168.1.49
埠為 8888
, 對了 ,手機需要連線電腦同一網路下的WIFI或者電腦的熱點WIFI ,否則是不行的
- Linux/Unix 使用者應該就不用我說了吧,都是大佬 開啟
終端
, 輸入ifconfig
root@iZwz96yoph60zayn2arjstZ:~# ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:**:3e:**:45:bc
inet addr:172.**.**.*** Bcast:172.**.**.*** Mask:255.255.192.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:20**66 errors:0 dropped:0 overruns:0 frame:0
TX packets:17**64 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:117837880 (117.8 MB) TX bytes:209340524 (209.3 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:6**36 Metric:1
RX packets:3**18 errors:0 dropped:0 overruns:0 frame:0
TX packets:3**18 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:25**728 (2.5 MB) TX bytes:2577728 (2.5 MB)
複製程式碼
這裡 eth0
和其他的不要搞混淆了
- 我是魅族手機大概演示一下設定, 開啟
WIFI
-> 找到WIFI名稱後的設定小按鈕
-> 找到代理設定
點選進去,把IP
,埠
設定好 ,結果如圖
配置好後,開啟 Charles
,發現多了非常多資料,一閃一閃
OK 這一步完成,接下來就是 點選一下左上角的黃色掃帚
,紅色按鈕
左邊,清空一下列表,然後開啟 美之圖
APP,獲取資訊
開啟APP
之後一直往下拉,先載入一些資料出來看看, 這時候要仔細看看那一條資訊一直在閃
這是開啟之後得到的資料,大致可以看出來,因為我們是要抓 meizitu
(美之圖),所以資料肯定不是qq
啥的
這時候拿著手機,使勁往下拉,看看那個在動, 這時候發現
http://adr.meizitu.net
這條資料一直在閃,我們開啟看看
咦,這種資料好熟悉啊, 好像Ajax
開啟看一下
一目瞭然了
再來看看資料規律
posts?page=3&per_page=5
posts?page=4&per_page=5
posts?page=5&per_page=5
posts?page=6&per_page=5
posts?page=7&per_page=5
posts?page=8&per_page=5
posts?page=9&per_page=5
...
複製程式碼
page
就是頁數, per_page
是什麼呢,複製他的URL到瀏覽器看看
好像摸到規律了有沒有, per_page
應該是每次載入得到的資料,我們把 5
改一下試試
結果顯然是的,這時候我們肯定都想知道那他最大能提取多少呢,我試過了 最大是100
/滑稽
OK結束了,寫程式碼了......你確定不認真看看資料裡面的資訊嗎?
我們開啟看看裡面有些什麼東西
這東西...需要打馬賽克嗎 ???
我之前直接提取 thumb_src
,抓取圖片到最後發現圖片沒有多少,只有1.8G
, 這就感覺很不對了,我開啟 APP
發現每一個美女
最少都有20
張圖片,但是到了這裡怎麼就只有一張了呢?
這時候 發現了img_num
,這個數目應該就是圖片的張數,但是還是無法解決(這裡大佬看了別嫌我笨啊,我第一次遇到這種情況)
然後我發現 thumb_src
最後2
位數,,,,,,,,,,,,,,,,試試,結果一試就成了
這時候大體的流程就完成了
程式碼
這裡就上核心程式碼了,完整程式碼在專案裡去看吧 地址:github.com/cexll/Mzitu…
def get_index(page, per):
"""
開啟url得到JSON
:param page: 頁數
:param per: 數量
"""
url = 'http://adr.meizitu.net/wp-json/wp/v2/posts?page=' + str(page) + '&per_page=' + str(per)
print(url)
try:
req = requests.get(url)
if req.status_code == 200:
imgs = req.json()
for item in imgs:
img_num = item.get('img_num')
img_url = item.get('thumb_src')
title = item.get('title')
for i in range(1, img_num+1):
if i >= 10:
u = img_url[0:-6]
ur = u + str(i) + '.jpg'
print("圖片總數: {}, 圖片地址: {}, 圖片標題: {}".format(img_num, ur, title))
# 儲存到JSON
save_to_json(ur, title)
# 儲存圖片到本地
save_image(ur)
else:
u = img_url[0:-5]
ur = u + str(i) + '.jpg'
print(ur, title)
print("圖片總數: {}, 圖片地址: {}, 圖片標題: {}".format(img_num, ur, title))
# 儲存到JSON
save_to_json(ur, title)
# 儲存圖片到本地
save_image(ur)
except ConnectionError:
pass
複製程式碼
程式碼大概意思是通過開啟URL
得到JSON
資料返回,解析裡面的圖片URL
和img_num
,再通過迴圈從1
到img_num
(我這裡寫的簡單粗暴,有更方便的方法可以告訴我),圖片URL後面通過切片來拼接圖片的連結
然後通過將標題
和圖片URL
儲存到本地,圖片下載到本地,通過兩個函式實現,如果不下載圖片
不需要多少時間,但下載圖片時間需要久一點,這裡使用非同步下載圖片應該非常快,但我認為做爬蟲也要有爬蟲的尊嚴,小站就別大批量的去訪問了
執行結果(不儲存圖片)
root@iZwz96yoph60zayn2arjstZ:/home/admin/in/Mzitu.net_Spi_Spider# ls -lh
total 17M
-rw-r--r-- 1 root root 17M Aug 30 11:18 18 result.json
-rw
-rwxrwxr-x 1 admin admin 2.3K Aug 29 22:23 23 Spider.py
複製程式碼
這是在伺服器下執行只儲存資訊到本地,全站圖片資料有17M
最後
再最後,我把我儲存到本地的圖片打包放到百度網盤了,有需要的去取...別問我那麼大什麼時候能下載完成,點這裡
網盤地址: 這裡 提取碼:(57iu)
由於打包在一個壓縮包太大了,而且也無法上傳,就分了4份,每一份1G左右,每一張圖片不重複