1. 程式人生 > >Python3爬蟲系列:理論+實驗+爬取妹子圖實戰

Python3爬蟲系列:理論+實驗+爬取妹子圖實戰

爬蟲系列:

(1) 理論

(2) 實驗

(3) 實戰

1. 準備環境

1.1 安裝CentOS

1.2 安裝Python3

1.3 安裝MongoDB

嘗試使用motor實現MongoDB非同步操作,好像效率更差一些,所以放棄使用該模組。目前資料庫操作是同步阻塞型,使用pymongo模組

1.4 安裝Git

[[email protected] ~]# yum -y install git
[[email protected] ~]# git clone https://github.com/wangy8961/python3-concurrency-pics-02.git
[[email protected] ~]# cd python3-concurrency-pics-02/

1.5 準備虛擬環境

如果你的作業系統是Linux:

[[email protected] python3-concurrency-pics-02]# python3 -m venv venv3
[[email protected] python3-concurrency-pics-02]# source venv3/bin/activate

Windows啟用虛擬環境的命令是: venv3\Scripts\activate

1.6 安裝依賴包

如果你的作業系統是Linux:

(venv3) [[email protected] python3-concurrency-pics-02]# pip install -r requirements-linux.txt

如果你的作業系統是Windows(不會使用uvloop):

(venv3) C:\Users\wangy> pip install -r requirements-win32.txt

2. 分析過程

mzitu step 01 - 04

2.1 獲取圖集資訊

使用requests模組或aiohttp模組來獲取入口頁面 http://www.mzitu.com/all/ 的HTML響應,然後通過BeautifulSoup4

lxml來解析HTML文件。每個圖集按年份/月份被放在<div class='all'></div>下面的每個<a href="圖集URL">圖集標題<a>中。需要注意的是,早期圖片需要訪問 http://www.mzitu.com/old/ ,遞迴呼叫獲取圖集的函式即可

將獲取的4000多個圖集資訊儲存到MongoDB資料庫的albums集合中

2.2 獲取包含圖片的頁面資訊

每個圖集下面的圖片數量不相同,我們需要依次訪問圖集URL,通過分頁導航欄獲取該圖集下最大的圖片數和它的釋出時間,並在本地磁碟上建立按日期分類的目錄,方便以後瀏覽圖片

將每個圖集下面的包含圖片的頁面資訊儲存到MongoDB資料庫的image_pages集合中

依次訪問圖集URL,共4500多次請求

2.3 獲取圖片的真實URL

我們通過訪問每個包含圖片的頁面,獲取每張圖片的真實URL,並儲存到MongoDB資料庫的images集合中

依次訪問包含圖片的頁面URL,共13萬多次請求*

2.4 下載圖片

從MongoDB資料庫的images集合中獲取所有圖片的真實URL,依次下載並儲存到本地

依次訪問圖片的真實URL,共13萬多次請求

3. 使用

3.1 測試

由於圖片有13萬多張,所以測試的時候,你可以指定只下載100個圖集來對比同步下載多執行緒下載非同步下載的效率區別,修改以下三個指令碼中的TEST_NUM = 100

建議每次測試完,都刪除相關目錄:

(venv3) [[email protected] python3-concurrency-pics-02]# rm -rf downloads/ logs/ __pycache__/

刪除資料庫記錄:

(venv3) [[email protected] python3-concurrency-pics-02]# mongo
MongoDB shell version v3.6.6
connecting to: mongodb://127.0.0.1:27017
...
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mzitu   0.036GB
> use mzitu
switched to db mzitu
> db.dropDatabase()
{ "dropped" : "mzitu", "ok" : 1 }
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> 

(1) 依序下載

(venv3) [root@CentOS python3-concurrency-pics-02]# python sequential.py

(2) 多執行緒下載

(venv3) [root@CentOS python3-concurrency-pics-02]# python threadpool.py

(3) 非同步下載

(venv3) [root@CentOS python3-concurrency-pics-02]# python asynchronous.py

3.2 後臺執行爬蟲指令碼

全站下載雖然只有13萬多張圖片,但章節分析過,總請求數差不多有30萬次,所以耗時比較久,為防止不小心關閉Shell客戶端而導致SSH斷開,將使用screen來將指令碼執行為後臺任務:

[[email protected] ~]# yum -y install screen
[[email protected] ~]# screen -dmS spider
[[email protected] ~]# screen -r spider
[[email protected] ~]# cd /root/python3-concurrency-pics-02
[[email protected] python3-concurrency-pics-02]# source venv3/bin/activate
(venv3) [[email protected] python3-concurrency-pics-02]# python asynchronous.py

指令碼執行的過程中,按Ctrl + A + D即可將任務切換到後臺執行,此時再關閉Shell客戶端也沒影響了。等待大約2小時後:

[[email protected] ~]# screen -r spider

即可檢視下載的結果,如果有失敗的請求,很正常,再次執行指令碼即可

async mzitu

(venv3) [[email protected] python3-concurrency-pics-02]# ls -lR downloads/ | grep '^-' | wc -l
138217
(venv3) [[email protected] python3-concurrency-pics-02]# du -sh downloads/
16G downloads/

3.3 定時任務自動每日更新

[[email protected] ~]# crontab -e
執行上述命令後,將開啟vim編輯器,新增如下兩行內容:

# 爬取 www.mzitu.com 美女圖片
30 23 * * * /usr/bin/python3 /root/python3-concurrency-pics-02/asynchronous.py

將在每天晚上23:30分自動執行爬蟲指令碼,檢視cron定時任務是否執行:

[[email protected] ~]# tail -f /var/log/cron
Aug 27 23:30:01 CentOS CROND[6256]: (root) CMD (/usr/bin/python3 /root/python3-concurrency-pics-02/asynchronous.py)
Aug 27 23:30:01 CentOS CROND[6257]: (root) CMD (/usr/lib64/sa/sa1 1 1)