介绍
入坑碧蓝档案已经有半年,每次想发癫又苦于只能上wiki上看立绘。所以就想爬到本地上,再存到手机里,实现发癫自由。
本来是在两年前做过一次爬取bwiki上立绘的爬虫程序的,但现在bwiki的碧蓝档案分区已经删除了全部页面,所以又得重新写。这次爬取的是碧蓝档案wiki这个网站,里面攻略很全,还有设定集和小漫画等资讯。
爬取方式
一开始本想直接使用requests
请求到页面,在用BeautifulSoup
进行解析来获得每个学生详细页面的url。
但很快就发现获取到的页面数据非常少,就明白此处是使用JavaScript动态加载的,原网页是没有这些内容的。于是改用selenium
来模拟浏览器操作,等网页加载好后在通过css选择器获得url。
代码
import requests as req
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
import time
import urllib.request
import os
base_path='文件夹位置'#下载文件位置
home_url='https://ba.gamekee.com/'
base_url='https:'
extension='.jpg'
driver=webdriver.Edge()#selenium打开edge实例,可以更换为其他已有的浏览器
#下载图片
def downloadImg(url,path,filname):
folder_path=os.path.join(base_path,path)
file_path=os.path.join(base_path,path,filname)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
if not os.path.exists(file_path):
print(f'开始下载:{filname}')
urllib.request.urlretrieve(url, file_path)
print(f'下载完成:{filname}')
#打开详细页面
def info_page(url,name):
print(f"打开{name}的页面!")
driver.get(url)
timeout=5
try:
elements=WebDriverWait(driver,timeout).until(EC.presence_of_element_located((By.CSS_SELECTOR,'#wiki-body > div > div > div.wiki-detail.pc-wiki-detail.detail-portrait > div.wiki-main-box > div > div.main-content > div.wiki-detail-body > div.detail-content-comp.ba-game-content > div ')))
except:
print(f'error:{url} get failed')
tbody=driver.find_elements(By.CSS_SELECTOR,'tbody')[0]
elements=tbody.find_elements(By.CSS_SELECTOR,'tr:nth-child(2)>td>div>img')#无标签页的
if(len(elements)==0):
elements=tbody.find_elements(By.CSS_SELECTOR,'tr:nth-child(2)>td>div>div>div>div.slide-content-group > div.slide-item>div>img')#有标签页的
ind=0
print(f"检测到{len(elements)}张立绘!")
for e in elements:
url=e.get_attribute('src')
if(ind==0):
downloadImg(url,'立绘',name+extension)
else:
downloadImg(url,'立绘',name+str(ind)+extension)
ind=ind+1
def main():
driver.get(home_url)#加载网页
timeout=5#超时时间
try:
element=WebDriverWait(driver,timeout).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#menu-23941 > div:nth-child(3) > div.model-tab-content > div:nth-child(1) > div.item-wrapper.icon-size-6.pc-item-group>a>img')))
except:
driver.quit()
#根据selector获得组件对象
info_url=driver.find_elements(By.CSS_SELECTOR,'#menu-23941 > div:nth-child(3) > div.model-tab-content > div:nth-child(1) > div.item-wrapper.icon-size-6.pc-item-group>a')
print(f"Find {len(info_url)} students !")
urls=[]
for e in info_url:
url=e.get_attribute('href')#获得每个学生详细页面的url
small_head=e.find_elements("tag name", "img")[0].get_attribute('data-src')#获得小头像
student_name=e.text
urls.append({'url':url,'name':student_name})
downloadImg(base_url+small_head,'小头像',student_name+'小头像'+extension)
time.sleep(1)#等待1秒,免得太快被ban
for page in urls:
time.sleep(5)
info_page(page.get('url'),page.get('name'))
driver.quit()
if __name__=='__main__':
main()
总结
其实也没啥能总结的,只是一个很简单的爬虫应用。如果大家有其他建议和方法也希望能不吝赐教!