根據(jù)下面的提供的王者榮耀 target=_blank class=infotextkey>王者榮耀最低戰(zhàn)力查詢的Python/ target=_blank class=infotextkey>Python源碼,使用PYQT5搭建了一個(gè)GUI,同時(shí)還可以看每個(gè)英雄皮膚的高清圖。
私信小編01即可獲取大量Python學(xué)習(xí)資源
import requests as r
import random
import json
def getMidStr(txt, txt_start, txt_end='', seeks=0, seeke=0):
"""取中間文本函數(shù)"""
try:
if txt_end or seeks or seeke:
pass
else:
raise 1
s_1 = txt.find(txt_start)
if s_1 == -1:
raise 1
l_1 = len(txt_start)
if txt_end:
s_2 = txt.find(txt_end, s_1)
if s_1 == -1 or s_2 == -1:
return False
return txt[s_1 + l_1:s_2]
if seeks:
return txt[s_1 - seeks:s_1]
if seeke:
return txt[s_1 + l_1:s_1 + l_1 + seeke]
except Exception:
return '傳參錯(cuò)誤或未找到傳參文本'
while True:
hero = input("輸入需要查詢的英雄:")
if hero == "":
print("您輸入無效")
elif hero == "0":
exit()
else:
source = r.get("http://s.wukongfenshen.com:9972/main/api/honour/wzpower/static/js/index.js?v=0." + str(
random.randint(1000000, 9999999))).text
_json = getMidStr(source, "var dictAll = ", "}}") + "}}"
_json = json.loads(_json)
try:
_json[hero]
except KeyError as reason:
print("沒有英雄:%s" % reason)
continue
title = _json[hero]["title"]
content = _json[hero]["content"]
print("英雄:%s" % title)
content = str.replace(content, "<p><p>", "n")
content = str.replace(content, "<p> <p>", "n")
content = str.replace(content, "</p>", "n")
content = str.replace(content, "<p>", "")
print(content + "n")
如果想更換主界面背景,修改第90行的圖片路徑即可。
pixmap.load("./image/199-bigskin-3.jpg")
搜索框輸入想查詢的英雄名稱,帶有自動補(bǔ)全。英雄查詢失敗,或者名字不正確,則會被提示
點(diǎn)擊搜索,搜索時(shí)間有時(shí)較長有時(shí)較短,我也不知道為什么。結(jié)果界面如下,背景默認(rèn)為原皮皮膚,可以移動鼠標(biāo)位置到縮略圖上,即可將該皮膚設(shè)置為背景。
點(diǎn)擊QQ頭像即可切換到微信區(qū)
鼠標(biāo)停留在地區(qū)上,則會顯示所屬省份或市級(該功能默認(rèn)關(guān)閉,因?yàn)樾枵{(diào)用百度地圖api, 使用前要自己去申請相應(yīng)的 ak, 申請后將functions文件夾下get_detail_location.py 中的 ak 替換為自己的 ak 即可)
def get_detail_location(place_name):
ak = 'ckXXxxxxxxxxxxxxxxxxcO9' # 替換為自己申請的ak
url = "http://api.map.baidu.com/place/v2/suggestion" +
f"?query={place_name}®ion={place_name}&city_limit=false&output=json&ak={ak}"
res = requests.get(url).json()
return res['result'][0]['province'] + res['result'][0]['city']
核心Python代碼:
from multiprocessing import Pool
import sys
import time
from bs4 import BeautifulSoup
from PyQt5.QtGui import QBrush, QIcon, QMouseEvent, QPalette, QPixmap
from PyQt5.QtCore import pyqtSignal, Qt, QRect, QSize, QThread
from PyQt5.QtWidgets import QApplication, QCompleter, QGraphicsOpacityEffect, QGroupBox,
QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget
import requests
import sip
# 引入自定義組件
from custom_widgets.CustomQLabel import CustomQLabel
from custom_widgets.PowerDisplayArea import PowerDisplayArea
from custom_widgets.SkinBox import SkinBox
from custom_widgets.WarnMessagebox import WarnMessagebox
# 引入自定義函數(shù)
from functions.get_detail_location import get_detail_location
from functions.get_heroSkin_url import heroSkin, download_image_data
from functions.get_power_information import get_power_info
# 讀取qss文件并設(shè)置stylesheet
class QssTool:
@staticmethod
def set_qss(obj, filepath):
with open(filepath, 'r', encoding='utf-8') as f:
style = f.read()
obj.setStyleSheet(style)
class RunThread(QThread):
"""
該線程用于下載圖片數(shù)據(jù)以及獲取地名詳情信息
"""
_signal = pyqtSignal(object)
def __init__(self, hero, qq_info, wx_info):
super(RunThread, self).__init__()
self.hero = hero
self.qq_info = qq_info
self.wx_info = wx_info
def __del__(self):
self.wait()
def run(self):
print('線程開始')
self.load_data(self.hero, self.qq_info, self.wx_info)
def load_data(self, hero, qq_info, wx_info):
"""
1. 調(diào)用 heroSkin 獲取英雄皮膚以及縮略圖網(wǎng)址,然后在線程池中下載圖片數(shù)據(jù)
2. 調(diào)用 get_detail_location 補(bǔ)全定位所在省份或者市級
:param hero:
:param qq_info:
:param wx_info:
:return:
"""
small_skin, big_skin, num = heroSkin(hero) # 爬取高清皮膚、縮略圖網(wǎng)址,以及皮膚數(shù)量
pool = Pool(2 * (num-1)) # 利用線程池下載皮膚高清圖以及縮放圖數(shù)據(jù)
rl = pool.map(download_image_data, big_skin + small_skin)
pool.close() # 關(guān)閉進(jìn)程池,不再接受新的進(jìn)程
pool.join() # 主進(jìn)程阻塞等待子進(jìn)程的退出
img_data = rl
# 補(bǔ)全地區(qū)信息
qq_detail_place = [get_detail_location(qq_item['定位']) for qq_item in qq_info]
wx_detail_place = [get_detail_location(wx_item['定位']) for wx_item in wx_info]
return_data = {
'big_skin': img_data[:num],
'small_skin': img_data[num:],
'qq_detail_place': qq_detail_place,
'wx_detail_place': wx_detail_place,
'qq_info': qq_info,
'wx_info': wx_info,
}
self._signal.emit(return_data)
# 主程序
class App(QWidget):
def __init__(self, parent=None):
super(App, self).__init__(parent)
# 應(yīng)用布局 美化
QssTool.set_qss(self, 'beautify.qss')
self.setWindowTitle("王者戰(zhàn)力查詢")
# 設(shè)置窗口背景
pixmap = QPixmap()
pixmap.load("./image/199-bigskin-3.jpg")
pixmap = pixmap.scaled(960, 441, Qt.KeepAspectRatio, Qt.SmoothTransformation)
palette = QPalette()
palette.setBrush(QPalette.Background, QBrush(pixmap))
self.setPalette(palette)
self.mainLayout = QVBoxLayout(self)
self.mainLayout.setContentsMargins(0, 0, 0, 0)
self.mainLayout.addStretch()
# 顯示皮膚頭像的布局
self.thumbnailLayout = QHBoxLayout()
self.thumbnailLayout.addStretch()
self.smallLayout = QHBoxLayout()
self.smallLayout.setContentsMargins(0, 0, 0, 0)
self.smallLayout.setSpacing(10)
self.thumbnailLayout.addLayout(self.smallLayout)
self.thumbnailLayout.addStretch()
self.mainLayout.addLayout(self.thumbnailLayout)
self.setLayout(self.mainLayout)
self.container = QGroupBox(self)
self.container.setObjectName('container')
self.container.setGeometry(QRect(340, 250, 280, 280))
self.lay = QVBoxLayout()
self.search_box_area = QGroupBox(self)
self.search_box_area.setObjectName('searchBox')
self.search_box_layout = QHBoxLayout()
self.search_box_layout.setSpacing(0)
self.search_box_layout.setContentsMargins(5, 0, 5, 0)
self.channel = CustomQLabel(self)
self.channel.button_clicked_signal.connect(self.channel_Changed)
self.inputBox = QLineEdit(self)
self.inputBox.setObjectName('inputBox')
self.inputBox.setPlaceholderText('輸入英雄名稱')
self.inputBox.setAlignment(Qt.AlignCenter)
self.btn = QPushButton('', self)
self.btn.setIcon(QIcon('./image/scope1.png'))
self.btn.setObjectName('searchButton')
self.btn.setIconSize(QSize(30, 30))
self.btn.setFixedSize(QSize(36, 36))
self.btn.clicked.connect(self.search)
self.search_box_layout.addWidget(self.channel)
self.search_box_layout.addWidget(self.inputBox)
self.search_box_layout.addWidget(self.btn)
self.search_box_area.setLayout(self.search_box_layout)
layout = QHBoxLayout()
layout.addStretch()
layout.addWidget(self.search_box_area)
layout.addStretch()
self.lay.addLayout(layout)
self.container.setLayout(self.lay)
self.lay.addSpacing(20)
self.wid = PowerDisplayArea()
self.wid.setInfo('省標(biāo)')
self.lay.addWidget(self.wid)
self.wid2 = PowerDisplayArea()
self.wid2.setInfo('市標(biāo)')
self.lay.addWidget(self.wid2)
self.wid3 = PowerDisplayArea()
self.wid3.setInfo('縣標(biāo)')
self.lay.addWidget(self.wid3)
self.wid.hide()
self.wid2.hide()
self.wid3.hide()
self.container.setStyleSheet('''
QGroupBox{
background-color:transparent;
}''')
self.status = False
self.start()
def start(self):
url = 'https://pvp.qq.com/web201605/herolist.shtml'
headers = {
'content-type': 'text/html',
'user-agent': '''Mozilla/5.0 (windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'''
}
total_list = requests.get(url, headers)
total_list.encoding = 'GBK'
soup = BeautifulSoup(total_list.text, 'html.parser')
hero_names = soup.select('div[class="herolist-content"]')
soup2 = BeautifulSoup(str(hero_names), 'html.parser')
hero_names = soup2.find_all('a')
hero_list = [item.get_text() for item in hero_names]
# 增加自動補(bǔ)全
completer = QCompleter(hero_list)
# 設(shè)置匹配模式
completer.setFilterMode(Qt.MatchStartsWith)
# 設(shè)置補(bǔ)全模式
completer.setCompletionMode(QCompleter.InlineCompletion)
# 給LineEdit設(shè)置補(bǔ)全器
self.inputBox.setCompleter(completer)
def search(self):
hero = self.inputBox.text()
if hero == "":
warnBox = WarnMessagebox()
warnBox.set_position(self.pos().x() + 380, self.pos().y() + 145)
warnBox.exec_()
else:
try:
self.s1 = time.time()
self.setWindowTitle("王者戰(zhàn)力查詢 (查詢中)")
qq_info, wx_info = get_power_info(hero)
self.thread = RunThread(hero, qq_info, wx_info)
self.thread._signal.connect(self.call_backlog)
# 開始線程
self.thread.start()
except Exception as reason:
print("沒有英雄:%s" % reason)
warnBox = WarnMessagebox()
warnBox.set_position(self.pos().x() + 380, self.pos().y() + 145)
warnBox.exec_()
def call_backlog(self, data):
self.container.setGeometry(QRect(340, 80, 280, 280))
self.container.setStyleSheet('''QGroupBox#container{
background-color:white;
border-radius:10px;
}''')
opacity = QGraphicsOpacityEffect()
opacity.setOpacity(0.7)
self.container.setGraphicsEffect(opacity)
self.inputBox.setStyleSheet('''QLineEdit#inputBox {
border:none;
border-right:2px solid #7F7F7F;
background-color:transparent;
font-size:12pt;
font-family:"微軟雅黑";
color:gray;
}''')
self.search_box_area.setStyleSheet('''
QGroupBox#searchBox{
border:2px solid #7F7F7F;
}
''')
self.btn.setIcon(QIcon('./image/scope2.png'))
self.qq_info, self.wx_info = data['qq_info'], data['wx_info']
# 設(shè)置窗口背景
self.imgData = data['big_skin']
pixmap = QPixmap()
pixmap.loadFromData(self.imgData[0])
pixmap = pixmap.scaled(960, 441, Qt.KeepAspectRatio, Qt.SmoothTransformation)
palette = QPalette()
palette.setBrush(QPalette.Background, QBrush(pixmap))
self.setPalette(palette)
# -----------如果有頭像框,刷新前清除------------
for i in reversed(range(self.smallLayout.count())):
w = self.smallLayout.itemAt(i)
w.widget().deleteLater()
self.smallLayout.removeItem(w)
sip.delete(w.widget())
sip.delete(self.smallLayout)
self.smallLayout = QHBoxLayout()
# ----------重新生成縮略圖區(qū)---------------------------------
SkinBox.numInstance = 0
for i, skin in enumerate(data['small_skin']):
self.skinBox = SkinBox()
self.skinBox.setMouseTracking(True)
self.skinBox.setObjectName(str(i))
self.skinBox.setSkin(skin, 'q' + str(i))
self.smallLayout.addWidget(self.skinBox)
self.skinBox.num_send_signal.connect(self.get_object_name)
self.thumbnailLayout.insertLayout(1, self.smallLayout)
# ------獲取地區(qū)信息---------
self.qq_detailPlace = data['qq_detail_place']
self.wx_detailPlace = data['wx_detail_place']
# -------設(shè)置戰(zhàn)力數(shù)據(jù)--------
self.status = True
self.show_information(self.channel.getStatus())
self.wid.show()
self.wid2.show()
self.wid3.show()
self.setWindowTitle("王者戰(zhàn)力查詢")
self.s2 = time.time()
print('time', self.s2 - self.s1)
del self.thread
def channel_Changed(self):
if self.status:
self.show_information(not self.channel.getStatus())
def show_information(self, IsWx):
if IsWx:
self.wid.setInfo('省標(biāo)', self.wx_info[2]['戰(zhàn)力'], self.wx_info[2]['定位'], self.wx_info[2]['更新時(shí)間'],
self.wx_detailPlace[2])
self.wid2.setInfo('市標(biāo)', self.wx_info[1]['戰(zhàn)力'], self.wx_info[1]['定位'], self.wx_info[1]['更新時(shí)間'],
self.wx_detailPlace[1])
self.wid3.setInfo('縣標(biāo)', self.wx_info[0]['戰(zhàn)力'], self.wx_info[0]['定位'], self.wx_info[0]['更新時(shí)間'],
self.wx_detailPlace[0])
else:
self.wid.setInfo('省標(biāo)', self.qq_info[2]['戰(zhàn)力'], self.qq_info[2]['定位'], self.qq_info[2]['更新時(shí)間'],
self.qq_detailPlace[2])
self.wid2.setInfo('市標(biāo)', self.qq_info[1]['戰(zhàn)力'], self.qq_info[1]['定位'], self.qq_info[1]['更新時(shí)間'],
self.qq_detailPlace[1])
self.wid3.setInfo('縣標(biāo)', self.qq_info[0]['戰(zhàn)力'], self.qq_info[0]['定位'], self.qq_info[0]['更新時(shí)間'],
self.qq_detailPlace[0])
self.lay.addWidget(self.wid)
self.lay.addWidget(self.wid2)
self.lay.addWidget(self.wid3)
strNum = 0
def get_object_name(self, object_name):
"""
1. 根據(jù)對象名稱,得到 SkinBox 中對應(yīng)縮略圖的索引
2. 如果索引發(fā)生改變,則將新的索引值所對應(yīng)的皮膚設(shè)置為當(dāng)前界面背景
:param object_name:
:return:
"""
list_str = list(object_name)
list_str.pop(0)
object_name = ''.join(list_str)
if int(object_name) != self.strNum:
self.strNum = int(object_name)
pixmap = QPixmap()
pixmap.loadFromData(self.imgData[self.strNum])
pixmap = pixmap.scaled(960, 441, Qt.KeepAspectRatio, Qt.SmoothTransformation)
palette = QPalette()
palette.setBrush(QPalette.Background, QBrush(pixmap))
self.setPalette(palette)
else:
pass
def mouseMoveEvent(self, a0: QMouseEvent):
self.setMouseTracking(True)
if __name__ == "__main__":
import ctypes # 解決任務(wù)欄ico無法顯示的問題
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
app = QApplication(sys.argv)
form = App()
form.setFixedSize(960, 441)
form.setWindowIcon(QIcon('image/2021.ico'))
form.show()
sys.exit(app.exec_())