1. 程式人生 > >Python爬蟲實戰| Python爬取英雄聯盟高清桌布

Python爬蟲實戰| Python爬取英雄聯盟高清桌布

先看一下最終爬取的效果,每個英雄的桌布都被爬取下來了:

“黑暗之女 安妮”的12張桌布:

高清大圖:

下面開始正式教學!

  • 版本:Python 3.5

  • 工具:Jupyter notebook實現各個環節,最終整合成LOL_scrawl.py檔案

在使用爬蟲前,先花一定時間對爬取物件進行了解,是非常有必要的,這樣可以幫助我們科學合理地設計爬取流程,以避開爬取難點,節約時間。

開啟英雄聯盟官網,看到所有英雄的資訊:

若要爬取全部英雄,我們先要獲取這些英雄的資訊,在網頁上“右擊——檢查——Elements”,就能在看到英雄的資訊了,如下圖所示,包括英雄暱稱、英雄名稱、英文名等等。由於這些資訊是使用JavaScript動態載入的,普通爬取方法無法獲取,我們考慮使用虛擬瀏覽器PhantomJS來獲取這些資訊。

我們點選進入“暗黑之女 安妮”的頁面,頁面地址為“http://lol.qq.com/web201310/info-defail.shtml?id=Annie”,地址中的“Annie”是這個英雄的英文名,若要訪問其他英雄介面,只需要更改英文名就可以了。

在英雄頁面上,通過點選略縮圖可以切換到不同的面板大圖,在大圖上“右擊——在新標籤頁中開啟圖片”,就能開啟大圖,這就是我們要的高清桌布:

觀察上圖的地址資訊,再開啟其他幾張安妮的面板桌布來檢視,發現不同桌布僅在圖片編號上有差別:

http://ossweb-img.qq.com/images/lol/web201310/skin/big1000.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big1001.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big1002.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big1003.jpg

再觀察英雄“盲僧 李青”的桌布地址:

http://ossweb-img.qq.com/images/lol/web201310/skin/big64000.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big64001.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big64002.jpg

再觀察英雄“卡牌大師 崔斯特”的桌布地址:

http://ossweb-img.qq.com/images/lol/web201310/skin/big4000.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big4001.jpg

http://ossweb-img.qq.com/images/lol/web201310/skin/big4002.jpg

可以總結出這樣一條規則:桌布地址由三部分組成,固定地址+英雄id+桌布編號。

  • 固定地址:“http://ossweb-img.qq.com/images/lol/web201310/skin/big”以及末尾的“.jpg”

  • 英雄id:安妮的id是1,李青的id是64,崔斯特的是40,我們還需要找到所有英雄的id

  • 桌布編號:桌布編號從000開始,001、002、003...,根據不同英雄的面板數量而不同,目前每個英雄桌布都不超過20個,也就是最多編到020

在上面的過程中,我們已經基本瞭解了要爬取物件的資訊了,但每一個英雄的id是多少卻還不知道,在網頁原始碼和用JavaScript載入後都找不到英雄和id的對應資訊,猜測這個資訊可能是放在某個js檔案裡,我們來找一找。

在所有英雄資訊介面“右鍵——檢查——Network”,再重新整理一下介面,可以找到一個champion.js檔案:

開啟champion.js檔案,發現裡面就存著我們需要的資訊,英雄英文名與英雄id一一對應:

至此對我們要爬取的物件已經有了一定的瞭解,對於具體爬取方法也有了想法,我們可以設計如下爬蟲流程圖:

根據爬蟲流程圖,我們可以設計如下程式碼框架:

這個程式碼框架非常容易讀懂,主要就是run()函式,run()函式完成了這樣一套工作:建立LOL資料夾——獲得鍵盤輸入的資訊——若資訊為“All”則爬取全部英雄桌布,否則爬取單個英雄桌布。

在爬取所有或者單個英雄桌布時,由於可能因為網路不穩定等因素導致爬取失敗,因此我們要使用try-except來處理爬取桌布時的程式碼:

至此已經打好了爬蟲框架,下面對爬取過程中最核心的兩個程式碼進行解釋:get_heroframe()與get_image(heroid,heroframe)。

首先我們要解析champion.js檔案,得到英雄英文名與id的一一對應關係。使用urllib.request開啟檔案地址,讀取內容並當做字串處理,解析內容並轉為字典{key:value},key為英文名,value為英雄id:

得到字典herodict{Englishname : id}如下:

對於官網網站上的所有英雄資訊頁面,由於是用JavaScript加載出來的,普通方法並不好爬取,我們使用Selenium+PhantomJS的方法來動態載入英雄資訊。Selenium 是自動化測試工具,它支援Chrome、Safari、Firefox 等瀏覽器驅動,在使用前先需要安裝selenium模組。而PhantomJS是一個虛擬瀏覽器,它沒有介面,但它的dom渲染、js執行、網路訪問、canvas/svg繪製等功能都很完備,在頁面抓取、頁面輸出、自動化測試等方面有廣泛的應用。PhantomJS可以在官方網站上下載。

我們使用Selenium+PhantomJS的方法來動態載入英雄資訊,使用BeautifulSoup獲取網址頁面內容:

得到頁面內容後,使用BeautifulSoup對頁面內容進行解析,將英雄暱稱、名稱、id等資訊存入heroframe中:

至此,get_heroframe()函式實現了爬取所有英雄的資訊,並存放在heroframe.csv檔案中,如下所示:

得到每一個英雄的資訊後,我們就可以開始愉快的爬取它們的桌布啦~定義get_image(heroid,heroframe)函式,用於爬取單個英雄的全部桌布。

首先在LOL資料夾中建立該英雄的子資料夾:

然後就可以爬取這個英雄的桌布了。由於每個英雄桌布都不超過20張,我們使用一個20以內的迴圈就能爬取到所有桌布了:

爬取完成後輸出成功的提示:

到這裡就大功告成啦!只要執行一下這個小程式,所有英雄的面板桌布就都收入囊中了,當然也可以爬取單個英雄的所有面板,只要根據提示輸入英雄的暱稱或名稱就好。

爬取單個英雄面板桌布:

爬取所有英雄面板桌布:

執行程式碼時注意保持網路暢通,如果網速太慢可能會爬取失敗。在3兆有線網的網速下爬取全部139個英雄的全部高清桌布(約一千張圖)大概要3-4分鐘。

《王者榮耀》、《陰陽師》、《絕地求生》等其他遊戲的桌布也是同樣道理就可以爬取了,據我實踐,《英雄聯盟》的爬取難度是最高的,因此將上述過程弄懂了,自己再編寫程式碼爬其他遊戲就易如反掌了。