Python爬蟲學習:妹子圖
-------------------------------------------------------------------------------------
本文記錄了一些爬蟲的基礎知識,並實現了一個50行左右的爬蟲腳本。
小白上車,大神忽略。
前言
看了一些Python的語法後打算做一個小項目練手,打發一下時間。爬蟲比較容易上手,加之Python十分適合寫爬蟲,於是花了半天時間寫了一個爬蟲,在此記錄一下。
工具
Python比較爽的一點就是開源社區為其貢獻了無數高質量的第三方庫,可以將程序員從繁瑣的細節中解放出來,更加專註於自己的目標。在這裡需要安裝兩個庫
sudo pip3 install requestssudo pip3 install beautifulsoup4
requests用於網路請求,beautifulsoup4用於html解析。
這裡不得不感慨一下,自己一年多前曾經用Java爬取過窩工教務處的網頁,當時網路請求以及html解析均是用原生API寫的,不僅浪費時間,而且經常出錯,當時花了一天多,而今天可能就是一個小時的功夫就完成了,雖然部分是因為當時還Too Young,但也不得不承認Python在提高效率方面的巨大優勢。
開始爬蟲
第一步:分析
對於本次任務,只需做兩件事:1.找到圖片;2.下載圖片。關鍵是如何找到圖片,這就需要分析目標網站:妹子圖。觀察首頁可以看到每個套圖都有一張預覽圖,而一個頁面由若干個套圖的入口(圖片預覽和文字鏈接)組成。
http://ond7j4cnz.bkt.clouddn.com/blogmzitu01.png翻到最下方發現有若干頁面選擇
http://ond7j4cnz.bkt.clouddn.com/blogmzitu03.png點進一個套圖之後,發現每個頁面顯示一張圖片,下方會顯示本套圖一共多少頁。
http://ond7j4cnz.bkt.clouddn.com/blogmzitu02.png針對套圖中的某一頁,在新標籤頁打開圖片,上方的url地址就是我們的目標了
http://ond7j4cnz.bkt.clouddn.com/blogmzitu04.png從圖片的url地址以及剛才的分析來看,這個網站還是十分有規律的,適合新手練習。
第二步:獲取網頁
需要注意的是,由於涉及網路和文件讀寫操作,在Linux環境需要在root下運行(親測命令行需要,PyCharm不需要)。
接下來正式開始,盡量用代碼表達。初次練習,可以用增量式的方法(完成一個功能,驗證正確性後在此基礎上開發下一個):import requests# 爬取目標url = http://www.mzitu.com# 設置報頭,Http協議header = {User-Agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36}main_page = requests.get(url, headers = header)print(main_page.text)
通過以上4行代碼就可以獲取得到首頁內容
第三步:解析網頁
分析可以發現,這個網站的每頁的url其實就是http://www.mzitu.com/n/,其中n是數字,n為1的時候會重定向到妹子圖,所以我們可以設置一個n的最大值,不超過網頁實際最大值即可,如此就可實現網頁的跳轉了,而不用模擬點擊了翻頁的按鈕。
我們比較關心的內容是套圖的入口地址,再對網頁進行分析,可以發現,所有鏈接都在一個id為pins的ul裡面,如此便可獲取該頁面全部套圖的入口地址了。
#!/usr/bin/env python3import requestsfrom bs4 import BeautifulSoup# 爬取目標url = http://www.mzitu.com/page/# 設置報頭,Http協議header = {User-Agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36}# 爬取的預覽頁面數量preview_page_cnt = 2for cur_page in range(1, int(preview_page_cnt)+1): cur_url = url + str(cur_page) cur_page = requests.get(cur_url, headers = header) # 解析網頁 soup = BeautifulSoup(cur_page.text, html.parser) # 圖片入口和文字入口取一個即可 preview_link_list = soup.find(id=pins).find_all(a, target=_blank)[1::2] for link in preview_link_list: print(link)
結果如下,可以看到,現在已經獲取到每個套圖的入口地址了。
http://ond7j4cnz.bkt.clouddn.com/blogmzitu08.png第四步:解析套圖網頁
每個網頁顯示套圖中的一張圖片,所以我們需要做兩件事:1.分析有多少圖片(即網頁)2.每個圖片的地址(即右鍵選擇「在新標籤頁打開」時的地址)。
分析可以發現,頁面數量在class為pagenavi的div裡面,而圖片地址在class為main-image的div裡面,並且每個每個網頁格式一致:http://www.mzitu.com/套圖id/n,其中n為不超過圖片數量的一個數字。#!/usr/bin/env python3import requestsfrom bs4 import BeautifulSoup# 爬取目標url = http://www.mzitu.com/page/parser = html.parser# 設置報頭,Http協議header = {User-Agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36}# 爬取的預覽頁面數量preview_page_cnt = 2for cur_page in range(1, int(preview_page_cnt)+1): cur_url = url + str(cur_page) cur_page = requests.get(cur_url, headers = header) # 解析網頁 soup = BeautifulSoup(cur_page.text, parser) # 圖片入口和文字入口取一個即可 preview_link_list = soup.find(id=pins).find_all(a, target=_blank)[1::2] for link in preview_link_list: link = link[href] soup = BeautifulSoup(requests.get(link).text, parser) # 獲取圖片數量 pic_cnt = soup.find(div, class_=pagenavi).find_all(a)[4].get_text() # 遍歷獲取每頁圖片的地址 for pic_index in range(1, int(pic_cnt)+1): pic_link = link + / + str(pic_index) cur_page = requests.get(pic_link, headers = header) soup = BeautifulSoup(cur_page.text, parser) pic_src = soup.find(div, main-image).find(img)[src] print(pic_src)
運行之後如下:
http://ond7j4cnz.bkt.clouddn.com/blogmzitu10.png第五步:下載圖片
主要涉及文件讀寫,比較簡單,添加之後完整代碼如下:
#!/usr/bin/env python3import requestsfrom bs4 import BeautifulSoupimport os# 爬取目標url = http://www.mzitu.com/page/parser = html.parsercur_path = os.getcwd() + /# 設置報頭,Http協議header = { User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36}# 爬取的預覽頁面數量preview_page_cnt = 2for cur_page in range(1, int(preview_page_cnt) + 1): cur_url = url + str(cur_page) cur_page = requests.get(cur_url, headers=header) # 解析網頁 soup = BeautifulSoup(cur_page.text, parser) # 圖片入口和文字入口取一個即可 preview_link_list = soup.find(id=pins).find_all(a, target=_blank)[1::2] for link in preview_link_list: dir_name = link.get_text().strip().replace(?, ) link = link[href] soup = BeautifulSoup(requests.get(link).text, parser) # 獲取圖片數量 pic_cnt = soup.find(div, class_=pagenavi).find_all(a)[4].get_text() # 創建目錄 pic_path = cur_path + dir_name if os.path.exists(pic_path): print(directory exist!) else: os.mkdir(pic_path) os.chdir(pic_path) # 進入目錄,開始下載 print(下載 + dir_name + ...) # 遍歷獲取每頁圖片的地址 for pic_index in range(1, int(pic_cnt) + 1): pic_link = link + / + str(pic_index) cur_page = requests.get(pic_link, headers=header) soup = BeautifulSoup(cur_page.text, parser) pic_src = soup.find(div, main-image).find(img)[src] pic_name = pic_src.split(/)[-1] f = open(pic_name, wb) f.write(requests.get(pic_src, headers=header).content) f.close() os.chdir(cur_path) # 完成下載,退出目錄print(下載完成)
第六步:爬取圖片
如下:
http://ond7j4cnz.bkt.clouddn.com/blogmzitu-demo.gif總結
人生苦短,我用Python。何況我是澤學家。
以及,哪位知道如何刪除粘貼進知乎編輯器的markdown格式的外鏈。。。。
推薦閱讀:
※一個函數,試試知乎
※校長,我要上車——python模擬登錄熊貓TV
※Python 爬蟲|深入請求(二):URL
※Python用KNN演算法實現驗證碼識別
※從零開始寫Python爬蟲 --- 爬蟲實踐:螺紋鋼數據&Cookies