爬蟲練習一:爬取睿奢圖片
爬取網站:睿奢-套裝合集-私房定製
目標:爬取並儲存該網站分類下每個主題的所有圖片
python版本:python 3.6
使用庫:urllib,Beautifulsoup,os,random,re,time
對網站進行訪問檢視
首先需要通過瀏覽器對目標網站進行訪問,瞭解該網站的頁面跳轉邏輯。
要獲得想要爬取的圖片,有以下兩個步驟:
1. 通過連結開啟網頁,不需要登陸就可以看到該分類下所有主題的圖片。
2. 隨便點選一個主題,比如“告白氣球”,即跳轉入對應的“告白氣球”主題詳情頁面,這個頁面一次性展示了“告白氣球”主題下所有的圖片。每個詳情頁面下的所有照片就是本次爬取目標。
編寫程式碼
1. 通過睿奢-套裝合集-私房定製 總攬頁面,獲得每個圖片主題對應的名稱和圖片詳情頁url
1)對該總攬頁面進行元素檢查,發現主題的名稱和詳情頁url直接在原始碼中明文展示,並沒有用上非同步載入或是使用介面傳輸資料等方式
因此,直接獲取網站元素後進行解析即可提取想要的資料。
2)該總攬頁面可以進行翻頁,總共有5頁。對比翻頁前後頁面的url發現,只需要對url最後一個數據做替換即可得到翻頁後的url
第一頁:http://www.rayshen.com/plus/list.php?tid=47&TotalResult=90&PageNo=1
第二頁:http://www.rayshen.com/plus/list.php?tid=47&TotalResult=90&PageNo=2
3)實現
orig_url = 'http://rayshen.com/plus/list.php?tid=47&TotalResult=90&PageNo=' # 實現翻頁,page_url是每次翻頁後頁面的url for n in range(1, 6, 1): page_url = orig_url + str(n) def get_girl_url(page_url): headers = {'User_Agent': get_userAgent()} # 使用隨機User-Agent,通過urllib獲取該網頁的元素 url = urllib.request.Request(page_url, headers=headers) page = urllib.request.urlopen(url).read() # 使用Beautifulsoup進行解析 soup = BeautifulSoup(page, 'html.parser') # url_info包含每個主題對應的圖片詳情頁url url_info = soup.find_all('a', class_="img js-anchor etag noul") # girl_info包含每個主題對應的名稱 girl_info = soup.find_all('img', class_="etag js-img bdc4 bds0 bdwa") return url_info, girl_info
2. 通過每個主題的圖片詳情頁url獲得該主題下使用圖片,並儲存至對應資料夾
1)從總攬頁面獲取的每個主題詳情頁的url地址,不能直接進行訪問。需要在url前加上'http://rayshen.com'後才可以正常訪問
2)對詳情頁進行元素檢查,所有圖片的對應url都在頁面原始碼中明文儲存。處理方式同總攬頁,直接從原始碼進行提取
3)詳情頁獲得的每張圖片的url,也不完全。需要在url前加上'http://rayshen.com'後才可以正常訪問
4)實現
def get_each_girl(url_info, girl_info, path): for i in range(len(url_info)): # 當前主題對應詳情頁url info_url = 'http://rayshen.com' + str(url_info[i]['href']) # 當前主題對應名稱 girl_name = girl_info[i]['alt'] # 設定儲存路徑,路徑為本地指定資料夾。單個主題的所有圖片儲存在一個子資料夾內 download_path = path+str(girl_name).replace(' ','')+'/' if not os.path.exists(download_path): os.makedirs(download_path) page = urllib.request.urlopen(info_url).read() # 暫停4s time.sleep(4) soup = BeautifulSoup(page, 'html.parser') # 得到每張照片的url photo_url = soup.find_all('img') i = 0 for each in photo_url: try: # 修正為可訪問的url,並使用urllib儲存至本地 img_url = 'http://rayshen.com' + re.findall('src="(\S+)"', str(each))[0] urllib.request.urlretrieve(img_url, download_path+str(i)+'.jpg') i += 1 print(girl_name, '第', i, '張 done') except: print('passed') path = '/Users/asdfgh/Desktop/ruishe/'
3. 全部程式碼
import urllib.request, urllib.parse, urllib.error from bs4 import BeautifulSoup import random import re import os import time # 訪問網頁時隨機選取一個User-Agent def get_userAgent(): agent = ['Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50', 'Opera/9.80(Macintosh;IntelMacOSX10.6.8;U;en)Presto/2.8.131Version/11.11', 'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)', 'Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; Tablet PC 2.0; .NET4.0E)', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Maxthon/3.0 Safari/534.12', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36'] return agent[random.randint(0, 5)] def get_girl_url(page_url): headers = {'User_Agent': get_userAgent()} # 使用隨機User-Agent,通過urllib獲取該網頁的元素 url = urllib.request.Request(page_url, headers=headers) page = urllib.request.urlopen(url).read() # 使用Beautifulsoup進行解析 soup = BeautifulSoup(page, 'html.parser') # url_info包含每個主題對應的圖片詳情頁url url_info = soup.find_all('a', class_="img js-anchor etag noul") # girl_info包含每個主題對應的名稱 girl_info = soup.find_all('img', class_="etag js-img bdc4 bds0 bdwa") return url_info, girl_info def get_each_girl(url_info, girl_info, path): for i in range(len(url_info)): info_url = 'http://rayshen.com' + str(url_info[i]['href']) girl_name = girl_info[i]['alt'] # 儲存路徑 download_path = path+str(girl_name).replace(' ','')+'/' if not os.path.exists(download_path): os.makedirs(download_path) page = urllib.request.urlopen(info_url).read() # 暫停4s time.sleep(4) soup = BeautifulSoup(page, 'html.parser') photo_url = soup.find_all('img') i = 0 for each in photo_url: try: img_url = 'http://rayshen.com' + re.findall('src="(\S+)"', str(each))[0] urllib.request.urlretrieve(img_url, download_path+str(i)+'.jpg') i += 1 print(girl_name, '第', i, '張 done') except: print('passed') path = '/Users/asdfgh/Desktop/ruishe/' orig_url = 'http://rayshen.com/plus/list.php?tid=47&TotalResult=90&PageNo=' for n in range(1, 6, 1): page_url = orig_url + str(n) url_info, girl_info = get_girl_url(page_url) get_each_girl(url_info, girl_info, path)
實現效果
執行程式碼後,成功爬下網站該分類下所以主題的圖片,並儲存在本地資料夾中。
總結
該網站的結構簡單,也沒有看到使用什麼反爬手段。所以簡單使用urllib庫進行網頁訪問和beautifulsoup進行解析就可以獲得想要爬取的資料。
這次練習的收益在於:
1)將學習到的爬蟲抓取思想運用在實際抓取中,在運用中進行理解
比如:編寫一個爬蟲的流程/方法論,可以用哪些方法來找到應該從哪裡獲取我們想要獲得的資料。
2)熟悉urllib和beautifulsoup庫的基本使用
反思:
1) 完成這個練習的要求很低,僅僅是一個入門練習。還需要嘗試更多更難的練習
2)從實際業務來考慮,編寫爬蟲爬取資料至少是需要一個目的的,即在什麼前提下為了滿足什麼需求才需要進行資料爬取、爬取後資料如何儲存/進一步處理
3)偽造請求頭是一個很有效的反反爬的方法。需要深入練習