-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dc8497b
Showing
156 changed files
with
919 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
spider/chromedriver.exe | ||
spider/cache/ | ||
__pycache__/ | ||
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# pcr-wiki插件 | ||
|
||
本插件需配合[Hoshino(v2)](https://github.com/Ice-Cirno/HoshinoBot)使用 | ||
|
||
数据搬运于[蘭德索爾圖書館](https://pcredivewiki.tw/),图片资源来源[干炸里脊资源站](https://redive.estertion.win/) | ||
|
||
## 功能 | ||
|
||
- **[@bot简介ue] 角色简介**:查询角色简介 | ||
- **[@bot技能ue] 角色技能**:查询角色技能 | ||
- **[@bot技能ue] 角色专武**:查询角色专武 | ||
- **[@bot羁绊ue] 角色羁绊**:查询角色羁绊 | ||
- **启用wiki**:启用pcr-wiki | ||
- **禁用wiki**:禁用pcr-wiki | ||
|
||
## 部署 | ||
|
||
1. 将本项目的`wiki`文件夹复制到`hoshino/modules/priconne`下 | ||
|
||
2. 安装`requirements.txt` | ||
|
||
3. 将本项目的`skill`与`equipment`文件夹复制到`res/img/priconne`文件夹下面 | ||
|
||
> 实际上,只需要新建`skill`与`equipment`文件夹并把`skill`下的`icon_skill_ap01.png`、`icon_skill_ap02.png`、`icon_skill_attack.png`、`icon_skill_tack.png`四个图片复制过去就好,其他没有的图片使用时会自动下载 | ||
4. 重启Hoshino | ||
|
||
> 注意:**不要**在hoshino的配置文件添加模块。 | ||
> | ||
> 注意:**不要**把`spider`文件夹及该文件夹下的文件任何文件放到`hoshino`下 | ||
至此,你可以开始使用插件了。 | ||
|
||
插件的数据源自文件夹下的`data.db`,wiki有更新时需要对应更新(我尝试过实时拉取数据,速度太慢,所以改用数据库存储),`data.db`会不定时更新,如果你想要自己手动更新,请看下一小节 | ||
|
||
## 更新数据 | ||
|
||
> 强烈建议在windows机器上更新数据,更为快速方便。`spider`文件夹仅作更新数据使用,**不要**把这个文件夹混入`hoshino`的任何目录,它是独立的 | ||
#### windows | ||
|
||
1. 打开`spider`文件夹,安装`requirements.txt` | ||
|
||
2. 将你需要更新的`data.db`准备好 | ||
|
||
3. 安装chrome浏览器,并查看chrome版本 | ||
|
||
4. http://npm.taobao.org/mirrors/chromedriver/下载最为接近你的chrome版本的驱动 | ||
|
||
> **不要**双击运行解压得到的exe文件,看下一步! | ||
5. 打开`run.py`按照注释修改对应处(第24、27、35行),打开`data.py`按照注释修改第3行 | ||
|
||
6. 将你最新的`_pcr_data.py`复制到`spider`文件夹下替换(保证`spider/_pcr_data.py`里有你需要更新的id信息) | ||
|
||
7. 运行`run.py` | ||
|
||
8. 若无报错,则更新成功,得到最新的`data.db`,替换掉你`hoshino/modules/priconne/wiki`下的同名件 | ||
|
||
#### Linux | ||
|
||
1. 将`spider`文件夹复制到服务器,打开该文件夹,安装`requirments.txt` | ||
|
||
2. 将你需要更新的`data.db`准备好 | ||
|
||
3. 安装chrome浏览器,并查看chrome版本 | ||
|
||
依次运行以下命令(第二行大概率会报错,不用管,但必须运行) | ||
|
||
``` | ||
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb | ||
sudo dpkg -i google-chrome-stable_current_amd64.deb | ||
sudo apt-get install -f | ||
sudo dpkg -i google-chrome-stable_current_amd64.deb | ||
sudo apt-get install xvfb | ||
google-chrome --version | ||
``` | ||
|
||
4. http://npm.taobao.org/mirrors/chromedriver/下载最为接近你的chrome版本的驱动 | ||
|
||
5. 打开`run.py`按照注释修改对应处(第24、27、35行),打开`data.py`按照注释修改第3行 | ||
|
||
6. 将你最新的`_pcr_data.py`复制到`spider`文件夹下替换(保证`spider/_pcr_data.py`里有你需要更新的id信息) | ||
|
||
7. 运行`run.py` | ||
|
||
8. 若无报错,则更新成功,得到最新的`data.db`,替换掉你`hoshino/modules/priconne/wiki`下的同名件 | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import re, time, os | ||
from selenium.common.exceptions import NoSuchElementException | ||
def get_chara_skill(driver, research=0): | ||
try: | ||
skill_boxes = driver.find_elements_by_class_name('skill-box') | ||
chara_skells = [] | ||
for s_b in skill_boxes: | ||
skill = {} | ||
skill['skill_name'] = s_b.find_element_by_class_name('skill-name').text | ||
skill['skill_type'] = s_b.find_element_by_class_name('skill-type').text | ||
|
||
skill['description'] = s_b.find_element_by_class_name('skill-description').text | ||
skill['description'] = re.sub(r'(EX)?技能[1-3]?\+?|必殺技|\n','', skill['description']) | ||
skill['description'] = skill['description'].replace(skill['skill_name'], '') | ||
|
||
img_src = s_b.find_element_by_class_name('img-fluid').get_attribute('src') | ||
num_match = re.search(r'[0-9]+', os.path.basename(img_src)) | ||
if num_match: | ||
skill['skill_num'] = num_match.group(0) | ||
else: | ||
skill['skill_num'] = -1 | ||
|
||
skill['skill_effect'] = [] | ||
skill_effects = s_b.find_elements_by_css_selector('.skill-effect > .mb-2') | ||
for s_e in skill_effects: | ||
s_e_divs = s_e.find_elements_by_tag_name('div') | ||
e_txt = '' | ||
for div in s_e_divs: | ||
if div.text: | ||
e_txt += div.text | ||
if e_txt: | ||
e_txt = e_txt.replace('\n', '') | ||
skill['skill_effect'].append(e_txt) | ||
chara_skells.append(skill) | ||
return chara_skells | ||
except NoSuchElementException as err : | ||
research += 1 | ||
print(f'get_chara_skill_error ({research}) : {err}') | ||
time.sleep(1) | ||
if research < 4: | ||
get_chara_skill(driver, research ) | ||
else: | ||
raise NoSuchElementException(err) | ||
|
||
def get_chara_info(driver, research=0): | ||
info = {} | ||
keys = { | ||
'名字': 'name', | ||
'公會': 'guild', | ||
'生日': 'birthday', | ||
'年齡': 'age', | ||
'身高': 'height', | ||
'體重': 'weight', | ||
'血型': 'blood_type', | ||
'種族': 'race', | ||
'喜好': 'hobby', | ||
'聲優': 'cv' | ||
} | ||
try: | ||
# 获得角色信息 | ||
table = driver.find_element_by_class_name('chara-table') | ||
tr_list = table.find_elements_by_tag_name('tr') | ||
for tr in tr_list: | ||
item = tr.find_element_by_tag_name('th').text | ||
info[keys.get(item, item)] = tr.find_element_by_tag_name('td').text | ||
|
||
# 获取介绍 | ||
intro = driver.find_elements_by_css_selector('.row>.col-lg-7>.d-block') | ||
if intro: | ||
info['introduce']= intro[0].text | ||
info['introduce'] = info['introduce'].replace('簡介\n', '') | ||
return info | ||
except NoSuchElementException as err: | ||
research += 1 | ||
print(f'get_chara_info_error ({research}) : {err}') | ||
time.sleep(1) | ||
if research < 3: | ||
get_chara_info(driver, research) | ||
else: | ||
raise NoSuchElementException(err) | ||
|
||
def get_chara_kizuna(driver): | ||
kizuna_tables = driver.find_elements_by_css_selector('.chara-table.mb-3') | ||
count = len(kizuna_tables) | ||
if count != 1: count = count / 3 | ||
kizuna = {} | ||
for table in kizuna_tables: | ||
# 检查是否爬取到所有羁绊 | ||
if len(kizuna) == count: | ||
break | ||
|
||
name = table.find_element_by_xpath('.//th[@colspan=2]').get_attribute('innerText') | ||
# 检查羁绊是否以及爬取过 | ||
if name in kizuna or name == '': | ||
continue | ||
else: | ||
# 创建角色羁绊 | ||
kizuna[name] = {} | ||
|
||
for tr in table.find_elements_by_tag_name('tr')[1:]: | ||
|
||
epi_key = tr.find_element_by_tag_name('th').get_attribute('innerText') | ||
effect = tr.find_element_by_tag_name('td').get_attribute('innerHTML') | ||
|
||
# html标签替换为分割符 | ||
effect = re.sub(r'<div[^>]*>|</div>|<!-+>', '~', effect) | ||
# 利用贪婪匹配去除多余分割符 | ||
effect = re.sub(r'~+', '~', effect) | ||
effect = effect.strip('~') | ||
kizuna[name][epi_key] = effect.split('~') | ||
return kizuna | ||
|
||
def get_act_pattern(driver): | ||
act_pattern = {} | ||
for h4 in driver.find_elements_by_css_selector('h4.item-sub-title'): | ||
if h4.text == '起手': | ||
parent_node = h4.find_element_by_xpath('..') | ||
start_pattern = [] | ||
for img in parent_node.find_elements_by_tag_name('img'): | ||
img_src = img.get_attribute('src') | ||
pt = os.path.splitext(os.path.basename(img_src))[0][-4:] | ||
start_pattern.append(pt) | ||
act_pattern['start'] = start_pattern | ||
|
||
if h4.text == '循環': | ||
parent_node = h4.find_element_by_xpath('..') | ||
loop_pattern = [] | ||
for img in parent_node.find_elements_by_tag_name('img'): | ||
img_src = img.get_attribute('src') | ||
act = os.path.splitext(os.path.basename(img_src))[0][-4:] | ||
if act == 'tack': | ||
act = 'attack' | ||
loop_pattern.append(act) | ||
act_pattern['loop'] = loop_pattern | ||
|
||
return act_pattern | ||
|
||
def get_unique_weapon(driver): | ||
for h3 in driver.find_elements_by_css_selector('h3.item-title.mb-0'): | ||
weapon = {} | ||
if '專用裝備' in h3.text: | ||
box = h3.find_element_by_xpath('..').find_element_by_class_name('prod-info-box') | ||
imgsrc = box.find_element_by_class_name('img-fluid').get_attribute('src') | ||
num_match = re.search(r'[0-9]+', os.path.basename(imgsrc)) | ||
if num_match: | ||
weapon['weapon_num'] = num_match.group(0) | ||
else: | ||
weapon['weapon_num'] = -1 | ||
|
||
weapon['name'] = box.find_element_by_id('0').text | ||
weapon['description'] = box.find_element_by_css_selector('.col-lg-8.col-12>p').text | ||
weapon['props'] = [] | ||
for pop_box in box.find_elements_by_class_name('prod-data'): | ||
prop = {} | ||
prop['property'] = pop_box.find_element_by_class_name('title').text | ||
value = pop_box.find_element_by_class_name('prod-value').text | ||
value = value.replace(' ', '') | ||
value = value.replace(')', '') | ||
value_list = value.split('(') | ||
prop['base_value'] = value_list[0] | ||
prop['max_value'] = value_list[1] | ||
weapon['props'].append(prop) | ||
return weapon if weapon else False | ||
|
||
def fetch(driver): | ||
chara_data = {} | ||
chara_data['info'] = get_chara_info(driver) | ||
chara_data['kizuna'] = get_chara_kizuna(driver) | ||
chara_data['skill'] = get_chara_skill(driver) | ||
|
||
uniquei_weapon = get_unique_weapon(driver) | ||
if uniquei_weapon: | ||
# skills = chara_data['skill'] | ||
# for index in range(len(skills)): | ||
# if '專武強化技能' in skills[index]['skill_type']: | ||
# uniquei_weapon['strengthen_skill'] = skills[index] | ||
# # 删除技能中的专武强化技 | ||
# # skills.pop(index) | ||
# break | ||
|
||
chara_data['uniquei'] = uniquei_weapon | ||
|
||
chara_data['pattern'] = get_act_pattern(driver) | ||
return chara_data |
Oops, something went wrong.