PaiGram/model/wiki/characters.py
2022-07-26 18:07:31 +08:00

190 lines
8.9 KiB
Python

import re
from typing import Optional
import httpx
from bs4 import BeautifulSoup
from .helpers import get_headers
class Characters:
CHARACTERS_LIST_URL = "https://genshin.honeyhunterworld.com/db/char/characters/?lang=CHS"
ROOT_URL = "https://genshin.honeyhunterworld.com"
def __init__(self):
self.client = httpx.AsyncClient(headers=get_headers())
async def _get_soup(self, url: str) -> Optional[BeautifulSoup]:
request = await self.client.get(url)
return BeautifulSoup(request.text, "lxml")
async def get_all_characters_url(self):
url_list = []
soup = await self._get_soup(self.CHARACTERS_LIST_URL)
character_list = soup.find_all('div', {'class': 'char_sea_cont'})
for character in character_list:
name = character.find("span", {"class": "sea_charname"}).text
if "旅行者" in name:
continue
character_link = self.ROOT_URL + character.a['href']
url_list.append(character_link)
return url_list
def get_characters_info_template(self):
characters_info_dict = {
"name": "",
"title": "",
"rarity": 0,
"element": {"name": "", "icon": ""},
"description": "",
"constellations": {},
"skills": {
"normal_attack": self.get_skills_info_template(),
"skill_e": self.get_skills_info_template(),
"skill_q": self.get_skills_info_template(),
"skill_replace": self.get_skills_info_template(),
},
"gacha_splash": ""
}
return characters_info_dict
@staticmethod
def get_skills_info_template():
skills_info_dict = {
"icon": "",
"name": "",
"description": ""
}
return skills_info_dict
async def get_characters(self, url: str):
characters_info_dict = self.get_characters_info_template()
soup = await self._get_soup(url)
main_content = soup.find("div", {'class': 'wrappercont'})
char_name = main_content.find('div', {'class': 'custom_title'}).text
characters_info_dict["name"] = char_name
# 基础信息
char_info_table = main_content.find('table', {'class': 'item_main_table'}).find_all('tr')
for char_info_item in char_info_table:
content = char_info_item.find_all('td')
if content[0].text == "Title":
char_title = content[1].text
characters_info_dict["title"] = char_title
if content[0].text == "Allegiance":
char_allegiance = content[1].text
characters_info_dict["allegiance"] = char_allegiance
if content[0].text == "Rarity":
char_rarity = len(content[1].find_all('div', {'class': 'sea_char_stars_wrap'}))
characters_info_dict["rarity"] = char_rarity
if content[0].text == "Element":
char_element_icon_url = self.ROOT_URL + content[1].find('img')['data-src'].replace("_35", "")
characters_info_dict["element"]["icon"] = char_element_icon_url
if content[0].text == "Astrolabe Name":
char_astrolabe_name = content[1].text
if content[0].text == "In-game Description":
char_description = content[1].text
characters_info_dict["description"] = char_description
# 角色属性表格 咕咕咕
skill_dmg_wrapper = main_content.find('div', {'class': 'skilldmgwrapper'}).find_all('tr')
# 命之座
constellations_title = main_content.find('span', {'class': 'item_secondary_title'}, string="Constellations")
constellations_table = constellations_title.findNext('table', {'class': 'item_main_table'}).find_all('tr')
constellations_list = []
constellations_list_index = 0
for index, value in enumerate(constellations_table):
# 判断第一行
if index % 2 == 0:
constellations_dict = {
"icon": "",
"name": "",
"description": ""
}
constellations_list.append(constellations_dict)
icon_url = self.ROOT_URL + value.find_all('img', {'class': 'itempic'})[-1]['data-src']
constellations_name = value.find_all('a', href=re.compile("/db/skill"))[-1].text
constellations_list[constellations_list_index]["icon"] = icon_url
constellations_list[constellations_list_index]["name"] = constellations_name
if index % 2 == 1:
constellations_description = value.find('div', {'class': 'skill_desc_layout'}).text
constellations_list[constellations_list_index]["description"] = constellations_description
constellations_list_index += 1
characters_info_dict["constellations"] = constellations_list
# 技能
skills_title = main_content.find('span', string='Attack Talents')
# 普攻
normal_attack_area = skills_title.find_next_sibling()
normal_attack_info = normal_attack_area.find_all('tr')
normal_attack_icon = self.ROOT_URL + normal_attack_info[0].find('img', {'class': 'itempic'})['data-src']
normal_attack_name = normal_attack_info[0].find('a', href=re.compile('/db/skill/')).text
normal_attack_desc = normal_attack_info[1].find('div', {'class': 'skill_desc_layout'}).text.replace(" ", "\n")
normal_attack = characters_info_dict["skills"]["normal_attack"]
normal_attack["icon"] = normal_attack_icon
normal_attack["name"] = normal_attack_name
normal_attack["description"] = normal_attack_desc
normal_attack_table_area = normal_attack_area.find_next_sibling()
# normal_attack_table = normal_attack_table_area.find_all('tr')
skill_e_area = normal_attack_table_area.find_next_sibling()
skill_e_info = skill_e_area.find_all('tr')
skill_e_icon = self.ROOT_URL + skill_e_info[0].find('img', {'class': 'itempic'})['data-src']
skill_e_name = skill_e_info[0].find('a', href=re.compile('/db/skill/')).text
skill_e_desc = skill_e_info[1].find('div', {'class': 'skill_desc_layout'}).text.replace(" ", "\n")
skill_e = characters_info_dict["skills"]["skill_e"]
skill_e["icon"] = skill_e_icon
skill_e["name"] = skill_e_name
skill_e["description"] = skill_e_desc
skill_e_table_area = skill_e_area.find_next_sibling()
# skillE_table = skillE_table_area.find_all('tr')
load_another_talent_q: bool = False
if char_name in ("神里绫华", "莫娜"):
load_another_talent_q = True
skill_q_area = skill_e_table_area.find_next_sibling()
skill_q_info = skill_q_area.find_all('tr')
skill_q_icon = self.ROOT_URL + skill_q_info[0].find('img', {'class': 'itempic'})['data-src']
skill_q_name = skill_q_info[0].find('a', href=re.compile('/db/skill/')).text
skill_q_desc = skill_q_info[1].find('div', {'class': 'skill_desc_layout'}).text.replace(" ", "\n")
skill_q_table_area = skill_q_area.find_next_sibling()
# skill_q_table = skill_q_table_area.find_all('tr')
if load_another_talent_q:
skill_replace = characters_info_dict["skills"]["skill_replace"]
skill_replace["icon"] = skill_q_icon
skill_replace["name"] = skill_q_name
skill_replace["description"] = skill_q_desc
else:
skill_q = characters_info_dict["skills"]["skill_q"]
skill_q["icon"] = skill_q_icon
skill_q["name"] = skill_q_name
skill_q["description"] = skill_q_desc
if load_another_talent_q:
skill_q2_area = skill_q_table_area.find_next_sibling()
skill_q2_info = skill_q2_area.find_all('tr')
skill_q2_icon = self.ROOT_URL + skill_q2_info[0].find('img', {'class': 'itempic'})['data-src']
skill_q2_name = skill_q2_info[0].find('a', href=re.compile('/db/skill/')).text
skill_q2_desc = skill_q2_info[1].find('div', {'class': 'skill_desc_layout'}).text.replace(" ", "\n")
skill_q2 = characters_info_dict["skills"]["skill_q"]
skill_q2["icon"] = skill_q2_icon
skill_q2["name"] = skill_q2_name
skill_q2["description"] = skill_q2_desc
# 角色图片
char_pic_area = main_content.find('span', string='Character Gallery').find_next_sibling()
all_char_pic = char_pic_area.find("div", {"class": "gallery_cont"})
gacha_splash_text = all_char_pic.find("span", {"class": "gallery_cont_span"}, string="Gacha Splash")
gacha_splash_pic_url = self.ROOT_URL + gacha_splash_text.previous_element.previous_element["data-src"].replace(
"_70", "")
characters_info_dict["gacha_splash"] = gacha_splash_pic_url
return characters_info_dict