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響應,然後通過BeautifulSoup4
和lxml
來解析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/