用Python爬虫爬取炉石原画卡牌图片
前段時間看了點Python的語法以及制作爬蟲常用的類庫,于是動手制作了一個爬蟲嘗試爬取一些爐石原畫圖片。本文僅記錄對特定目標網(wǎng)站的分析過程和爬蟲代碼的編寫過程。代碼功能很局限,無通用性,僅作為一個一般爬蟲程序提供參考。
要爬取的網(wǎng)站入口頁面是:https://hearthstone.gamepedia.com/Full_art。網(wǎng)頁上半部分的<li>標記了每個爐石資料片圖片的名稱(其實是錨點連接),通過這些名稱就可以獲得各個資料片的專題鏈接,比如,冠軍的試煉的專題資料片對應的網(wǎng)址為:https://hearthstone.gamepedia.com/The_Grand_Tournament_full_art
進入專題頁面后,可以看到該資料片的圖片列表,其中也有各個圖片的縮略圖連接,但是我想找到每個圖片的原圖。單個圖片介紹的頁面連接在每個class="image"的<a>標簽中。比如連接:https://hearthstone.gamepedia.com/File:Argent_Horserider_full.png
進入單個圖片的介紹頁面后,可以找到class='internal'的<a>標簽,它的href屬性值就是該圖片的原圖連接。(嗯,判斷的依據(jù)是從這個連接下載得到的圖是最大的。。)
目標網(wǎng)站的情況大致分析完了,好像也不復雜。下面按照分析過程給出一些代碼。
題外話:利用Python制作爬蟲,我引用了兩個類庫。分別是BeautifulSoup和requests。Python版本是3.6.1。
首先是根據(jù)入口頁面獲取各個資料片的連接:
def get_links(url):r = requests.get(url)
r.encoding = "utf-8"
only_li = SoupStrainer(class_=re.compile("toclevel-1"))
lis = BeautifulSoup(r.text, "html.parser", parse_only=only_li)
links = []
for li in lis:
link = li.a["href"]
links.append(link)
return links
參數(shù)url就是入口連接的字符串值:"https://hearthstone.gamepedia.com/Full_art"。通過requests.get(str)方法獲得響應對象并設置其編碼格式為"UTF-8"。然后創(chuàng)建了一個SoupStrainer對象,這個對象的作用是在解析(HTML)文檔時進行過濾和篩選。class_=re.compile("toclevel-1")表示標簽的類中含有值"toclevel-1"。然后就是進行文檔解析,解析出來后得到的lis對象,就是包含資料片名稱的各個<li>的集合。循環(huán)獲取其中的<a>標簽的href屬性值即可。
第二步,根據(jù)關鍵字集合拼接連接。這個很簡單。
def get_real_links(basic_url, keywords):real_links = []for keyword in keywords:keyword = keyword[1:]real_links.append(basic_url+"/"+keyword)return real_linksbasic_url是指:https://hearthstone.gamepedia.com,keywords就是前一步操作得到的links集合。keyword = keyword[1:]是截取去掉錨點"#"號。
第三步就是根據(jù)資料片專題畫面獲取該資料片下的所有圖片的圖片介紹頁面的鏈接。
def get_img_page_links(basic_url, real_link):all_img_page_link = []
r = requests.get(real_link)
r.encoding = "utf-8"
ss = SoupStrainer(class_="image")
only_img_a = BeautifulSoup(r.text, "html.parser", parse_only=ss)
for img_a in only_img_a:
all_img_page_link.append(basic_url+img_a["href"])
print(all_img_page_link)
return all_img_page_link
參數(shù)real_link是單個資料片的連接。主要代碼和第一步是類似的,不再贅述了。
第四步,根據(jù)圖片介紹頁面的鏈接集合,獲取原圖片的資源鏈接。
def get_all_img_link(all_img_page_link):all_img_link = []for link in all_img_page_link:img_name = link[link.index("File:") + len("File:"):]path = "D://python/heartstoneimg/Knights_of_the_Frozen_Throne_full_art/"+img_nameif os.path.exists(path):print(img_name+" exists")continueelse:print("requesting:%s"%(link))r = requests.get(link)r.encoding = "utf-8"ss = SoupStrainer(class_="internal")img_a = BeautifulSoup(r.text, "html.parser", parse_only=ss)print("imag_a:%s" % (img_a))print(img_a.a["href"])img_link = img_a.a["href"]all_img_link.append((img_link, img_name))time.sleep(10)if len(all_img_link) > 20:breakprint(all_img_link)return all_img_link這里的代碼有偷懶的痕跡,在實際下載過程中,如果將所有資料片的所有圖片一起循環(huán)下載,如果中間有報連接錯誤(公司網(wǎng)絡不行),文檔解析的工作就會從頭開始。所以我是按照每個資料片,單獨下載的。所以,在本地硬盤中創(chuàng)建對應資料片文件夾這項的工作是手動完成的,更換一次資料片的下載也要再手工修改一次代碼,這部分可以再完善。這部分程序首先是取得文件名字,然后判斷是否已經下載過了,接著獲取原圖鏈接,并把圖片名稱和原圖鏈接做成一個tuple存儲在集合中。這里我每次運行只解析二十張圖片的信息(還是網(wǎng)絡原因)。
最后一步就是圖片下載了。
def do_get_img(all_image_link):for img_link in all_image_link:path = "D://python/heartstoneimg/Knights_of_the_Frozen_Throne_full_art/"+img_link[1];if os.path.exists(path):print(img_link[1]+" exists.")continueelse:print("downloading:%s" % (img_link[0]))try:pic = requests.get(img_link[0], timeout=60)except requests.exceptions.ConnectionError:print("fail or timeout!!")continue# path = "D://python/heartstoneimg/basic_full_art/"+img_link[1]print("writing:%s" % (path))file = open(path, 'wb')file.write(pic.content)file.close()time.sleep(10)好像也很簡單,每張圖片下載的超時時間是六十秒,每次下載完一張圖片后延遲十秒再下載,不然有時網(wǎng)站會因為你訪問太過頻繁而拒絕訪問。
main部分的代碼。
from bs4 import BeautifulSoup import requests import re from bs4 import SoupStrainer import time import os import socketdef start_get_img():url = "http://hearthstone.gamepedia.com/Full_art"keywords = get_links(url)basic_url = "http://hearthstone.gamepedia.com"real_links = get_real_links(basic_url, keywords)all_img_page_link = get_img_page_links(basic_url, real_links[11])all_img_link = get_all_img_link(all_img_page_link)do_get_img(all_img_link)if __name__ == "__main__":start_get_img()
get_img_page_links(str,str)方法的第二個參數(shù)是當前的資料片鏈接。更完善的做法是循環(huán)real_links集合進行下載。
如果網(wǎng)絡正常,每個資料片一百多張圖片可以在一個小時內下載完。
我把下載到的原畫圖片作為資源制作了一個網(wǎng)站。
http://www.blz-art.com
有興趣的可以去看下。
轉載于:https://www.cnblogs.com/derry9005/p/7405151.html
總結
以上是生活随笔為你收集整理的用Python爬虫爬取炉石原画卡牌图片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P2590 [ZJOI2008]树
- 下一篇: 十年之后再看“面向对象”