Python3爬蟲系列:理論+實驗+爬取

  • 2020 年 1 月 19 日
  • 筆記

Github: https://github.com/wangy8961/python3-concurrency-pics-02 ,歡迎star

爬蟲系列:

(1) 理論

  • Python3爬蟲系列01 (理論) – I/O Models 阻塞 非阻塞 同步 非同步
  • Python3爬蟲系列02 (理論) – Python並發編程
  • Python3爬蟲系列06 (理論) – 可迭代對象、迭代器、生成器
  • Python3爬蟲系列07 (理論) – 協程
  • Python3爬蟲系列08 (理論) – 使用asyncio模組實現並發

(2) 實驗

  • Python3爬蟲系列03 (實驗) – 同步阻塞下載
  • Python3爬蟲系列04 (實驗) – 多進程並發下載
  • Python3爬蟲系列05 (實驗) – 多執行緒並發下載
  • Python3爬蟲系列09 (實驗) – 使用asyncio+aiohttp並發下載

(3) 實戰

  • Python3爬蟲系列10 (實戰) – 爬取妹子圖 第一彈
  • Python3爬蟲系列11 (實戰) – 爬取妹子圖 第二彈

1. 準備環境

1.1 安裝CentOS

建議使用VMware安裝一台CentOS-7.3虛擬機,請參考:http://www.madmalls.com/blog/post/customize-centos-7-3-autoinstall-iso/

1.2 安裝Python3

請參考:http://www.madmalls.com/blog/post/deploy-flask-gunicorn-nginx-supervisor-on-centos7/#3-python3

1.3 安裝MongoDB

請參考:http://www.madmalls.com/blog/post/deploy-flask-gunicorn-nginx-supervisor-on-centos7/#4-mongodb ,如果是Windows請參考:http://www.madmalls.com/blog/post/win10-install-mongodb/

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

1.4 安裝Git

[root@CentOS ~]# yum -y install git

程式碼已上傳到 https://github.com/wangy8961/python3-concurrency-pics-02 ,克隆程式碼:

[root@CentOS ~]# git clone https://github.com/wangy8961/python3-concurrency-pics-02.git  [root@CentOS ~]# cd python3-concurrency-pics-02/

1.5 準備虛擬環境

如果你的作業系統是Linux:

[root@CentOS python3-concurrency-pics-02]# python3 -m venv venv3  [root@CentOS python3-concurrency-pics-02]# source venv3/bin/activate

Windows激活虛擬環境的命令是: venv3Scriptsactivate

1.6 安裝依賴包

如果你的作業系統是Linux:

(venv3) [root@CentOS python3-concurrency-pics-02]# pip install -r requirements-linux.txt

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

(venv3) C:Userswangy> pip install -r requirements-win32.txt

2. 分析過程

2.1 獲取圖集資訊

使用requests模組或aiohttp模組來獲取入口頁面 http://www.mzitu.com/all/ 的HTML響應,然後通過BeautifulSoup4lxml來解析HTML文檔。每個圖集按年份/月份被放在<div class='all'></div>下面的每個<a href="圖集URL">圖集標題<a>中。需要注意的是,早期圖片需要訪問 http://www.mzitu.com/old/ ,遞歸調用獲取圖集的函數即可

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

訪問 http://www.mzitu.com/all/ 和 http://www.mzitu.com/old/ ,共2次請求

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

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

假設圖集URL為 http://www.mzitu.com/56918 ,發現該圖集下有47張圖片,而且包含圖片的頁面URL也是有規律的,比如包含第1張圖片的頁面URL為 http://www.mzitu.com/56918/1

將每個圖集下面的包含圖片的頁面資訊保存到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) [root@CentOS python3-concurrency-pics-02]# rm -rf downloads/ logs/ __pycache__/

刪除資料庫記錄:

(venv3) [root@CentOS 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來將腳本運行為後台任務:

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

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

[root@CentOS ~]# screen -r spider

即可查看下載的結果,如果有失敗的請求,很正常,再次執行腳本即可

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

3.3 定時任務自動每日更新

[root@CentOS ~]# crontab -e  執行上述命令後,將打開vim編輯器,新增如下兩行內容:    # 爬取 www.mzitu.com 美女圖片  30 23 * * * /usr/bin/python3 /root/python3-concurrency-pics-02/asynchronous.py

將在每天晚上23:30分自動執行爬蟲腳本,查看cron定時任務是否執行:

[root@CentOS ~]# 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)

更多cron知識請參考:http://www.madmalls.com/blog/post/how-to-schedule-tasks-in-linux-with-at-and-cron/