我們最終目的就是要把抓取到的圖片保存到本地,所以先寫一個保存圖片的方法(可以保存任何二進制文件)。注意在windows下文件命名包含/ | ?可能會發生錯誤,有的英雄皮膚名稱確實包含/,所以這裏使用正則表達式替換下。方法包含文件路徑,文件名稱,文件內容,簡單粗暴一些。
def save_image(image_dir,image_name,image_content):
if not os.path.exists(image_dir):
os.makedirs(image_dir)
try:
hero_image_path = os.path.join(image_dir,re.sub(r'[/|?]','',image_name))
with open(hero_image_path, 'wb') as image:
image.write(image_content)
except Exception as e:
print('{}保存失敗,錯誤原因:{}'.format(hero_image_path,e))
爬取數據就是模擬瀏覽器請求,經過查看英雄聯盟英雄資料頁面,都是get請求,這裏把使用requests請求寫到一個函數裏,減少些重複代碼。這裏把headers放到self裏,奔着面向對象的思路。
def send_get(self,url):
try:
resp = requests.get(url,headers = self.headers)
assert resp.status_code == 200,'{}請求失敗'.format(url)
return resp
except Exception as e:
print(e)
return None
下面F12再分析一下英雄聯盟英雄資料頁面數據,我們的思路是先在英雄列表得到所有的英雄信息,然後依次循環爬取單個英雄的信息,得到單個英雄的所有皮膚。
如果直接爬取英雄列表頁面地址url,會發現是獲取不到英雄列表數據的,因爲頁面是異步加載的,也可以看作是前端和後臺數據分離的,你爬或不爬,頁面就在那裏,英雄列表數據是動態請求的。
仔細看F12裏的網絡請求,可以看到有一個js請求(前端頁面請求後臺數據通常都是觸發js事件),地址如下:
https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js
看一下這個請求的響應信息,可以看到就是頁面的英雄列表信息,所以我們向這個地址發起請求獲取所有英雄的列表。大概就是醬紫:
隨手截了一個圖,最後一個英雄也是我的最愛,曙光女神(日女),再看下單個英雄的頁面,需要找到單個英雄的地址,然後逐個去請求獲取數據。女神的頁面數據是醬紫的:
單個英雄的地址如下:
https://game.gtimg.cn/images/lol/act/img/js/hero/89.js
#等待動態拼接
https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js
英雄列表數據有了,單個英雄的請求地址也找到了,下面就可以大膽地發起請求了,可以看到英雄列表和單個英雄信息返回的都是json格式的數據,就是python中的字典類型。
最後在單個英雄的返回數據中找到皮膚的圖片地址,發起請求獲取圖片內容即可,然後調用之前寫好的保存圖片的方法即可。
def process_hero(self,**hero_info_dict):
hero = hero_info_dict['hero']
skins = hero_info_dict['skins']
for skin in skins:
# 獲取圖片內容
if skin['mainImg']:
skin_content = self.send_get(skin['mainImg']).content
hero_image_name = '{}.jpg'.format(skin['name'])
hero_image_dir = os.path.join(self.base_path, hero['name'] + hero['title'])
self.save_image(hero_image_dir,hero_image_name,skin_content)
print('hero:{},skins:{}張,處理完成'.format(hero['name'],len(skins)))
time.sleep(1)
完整代碼已經扔到小編的github上了,歡迎來搞,一起開擼。
https://github.com/maidepiao/xiaomai_python3_little_by/blob/master/爬蟲/英雄聯盟圖片爬取.py
英雄聯盟所有英雄數據就這樣輕輕鬆鬆爬取好了,這裏以角色英雄名稱爲文件夾保存英雄皮膚,結果如圖所示: