|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
代码太长,我没写注释,问chatgpt他说我代码太长不肯回我 import pygame
from selenium import webdriver
from requests import get
from subprocess import getstatusoutput as _gsout
from threading import Thread, Timer
from os import remove
from os.path import isfile
from pickle import load, dump
from time import sleep
from bs4 import BeautifulSoup
from lxml import html
pygame.init()
pygame.key.set_repeat(1000, 50)
class Button(pygame.sprite.Sprite):
def __init__(self, name, size, font: pygame.font.Font, bgc, fgc, pos, key='\0'):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface(size)
self.image.fill(bgc)
surf = font.render(name, False, fgc)
rect = surf.get_rect()
rect.center = self.image.get_rect().center
self.image.blit(surf, rect)
self.rect = self.image.get_rect()
self.rect.topleft = pos
self.key = key
self.font = font
self.bgc = bgc
self.fgc = fgc
def chosen(self, event: pygame.event.Event):
if event.type == pygame.MOUSEBUTTONUP:
if self.rect.collidepoint(event.pos):
return True
if event.type == pygame.KEYDOWN:
if event.key == ord(self.key) and event.mod & pygame.KMOD_ALT:
return True
return False
def draw(self):
screen.blit(self.image, self.rect)
class Text(pygame.sprite.Sprite):
def __init__(self, text, font, color, pos):
pygame.sprite.Sprite.__init__(self)
self.font = font
self._text = text
self.color = color
self.image = self.font.render(self.text, False, self.color)
self.rect = self.image.get_rect()
self.rect.topleft = pos
def draw(self):
screen.blit(self.image, self.rect)
@property
def text(self):
return self._text
@text.setter
def text(self, new):
self._text = new
self.image = self.font.render(self.text, False, self.color)
class Entry(pygame.sprite.Sprite):
def __init__(self, size, font, bgc, bdc, fgc, pos):
pygame.sprite.Sprite.__init__(self)
self.bgc = bgc
self.bdc = bdc
self.image = pygame.Surface(size)
self.image.fill(bgc)
for x in range(0, size[0]):
self.image.set_at((x, 0), bdc)
self.image.set_at((x, size[1] - 1), bdc)
for y in range(0, size[1]):
self.image.set_at((0, y), bdc)
self.image.set_at((size[0] - 1, y), bdc)
self.text = Text('', font, fgc, pos)
self.image.blit(self.text.image, (0, 0))
self.rect = self.image.get_rect()
self.rect.topleft = pos
self.selected = False
@property
def fgc(self):
return self.text.color
def draw(self):
screen.blit(self.image, self.rect)
def listen(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
self.selected = self.rect.collidepoint(event.pos)
elif event.type == pygame.KEYDOWN:
if self.selected:
if event.key == pygame.K_BACKSPACE:
self.text.text = self.text.text[:-1]
self._update_text()
elif (event.unicode in
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+[];,./{}|:"<>?'
+ "'" + '\\'
):
self.text.text += event.unicode
self._update_text()
def _update_text(self):
size = self.rect.size
self.image = pygame.Surface(size)
self.image.fill(self.bgc)
for x in range(0, size[0]):
self.image.set_at((x, 0), self.bdc)
self.image.set_at((x, size[1] - 1), self.bdc)
for y in range(0, size[1]):
self.image.set_at((0, y), self.bdc)
self.image.set_at((size[0] - 1, y), self.bdc)
self.text = Text(self.text.text, self.text.font, self.fgc, self.rect.topleft)
self.image.blit(self.text.image, (0, 0))
class PasswordEntry(Entry):
def _update_text(self):
size = self.rect.size
self.image = pygame.Surface(size)
self.image.fill(self.bgc)
for x in range(0, size[0]):
self.image.set_at((x, 0), self.bdc)
self.image.set_at((x, size[1] - 1), self.bdc)
for y in range(0, size[1]):
self.image.set_at((0, y), self.bdc)
self.image.set_at((size[0] - 1, y), self.bdc)
self.text = Text(len(self.text.text) * '*', self.text.font, self.fgc, self.rect.topleft)
self.image.blit(self.text.image, (0, 0))
class MyThread(Thread):
def __init__(self, func, args=(), kwargs=None, timeout=None):
Thread.__init__(self)
self.func = func
self.args = args
self.kwargs = {} if kwargs is None else kwargs
self.timeout = timeout
self.result = None
def run(self):
self.result = self.func(*self.args, **self.kwargs)
def timeout(seconds):
def decorated(func):
def done(*args, **kwargs):
err = None
result = None
def inner():
nonlocal err, result
try:
result = func(*args, **kwargs)
except BaseException as msg:
err = msg
thread = Thread(target=inner)
thread.start()
# 只等待seconds秒
thread.join(seconds)
# 如果线程还活着
if thread.is_alive():
raise TimeoutError
if err:
raise err
return result
return done
return decorated
# 实际上是生成了一个新的decorated函数,通过闭包的形式保存了秒数,然后done里再调用inner
@timeout(1)
def soutf(msg):
return _gsout(msg)
def check_internet():
try:
soutf('ping fishc.com.cn')
# 这东西,报错可是最快
print('你没联网')
exit()
except TimeoutError:
# 连上了的话那就好说
pass
def load_image(url):
filename = 'temp.png'
with open(filename, 'wb') as f:
f.write(get(url, headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
}).content)
image = pygame.image.load(filename)
remove(filename)
return image
def save():
with open('fishc.set', 'wb') as f:
dump(data, f)
def loginf(email, password):
driver.get('https://fishc.com.cn/member.php?mod=logging&action=login')
sleep(1)
driver.find_element(
'xpath',
'/html/body/div[6]/div/div[2]/div/div[2]/div[1]/div[1]/form/div/div[1]/table/tbody/tr/td[1]/input'
).send_keys(email)
driver.find_element(
'xpath',
'/html/body/div[6]/div/div[2]/div/div[2]/div[1]/div[1]/form/div/div[2]/table/tbody/tr/td[1]/input'
).send_keys(password)
driver.find_element(
'xpath',
'/html/body/div[6]/div/div[2]/div/div[2]/div[1]/div[1]/form/div/div[6]/table/tbody/tr/td[1]/button'
).click()
sleep(1)
driver.find_element('id', 'succeedmessage_href').click()
return driver.page_source
def getdata(source):
tree = html.fromstring(source)
part = html.tostring(tree.xpath('//strong[@class="vwmy"]')[0], encoding='unicode')
usergroup = html.tostring(tree.xpath('//a[@id="g_upmine"]')[0], encoding='unicode')
soup = BeautifulSoup(part, features='lxml')
soup2 = BeautifulSoup(usergroup, features='lxml')
return soup.find('a').text, soup2.find('font').get('color'), soup2.find('font').text
def login_to1(email, password):
return getdata(loginf(email, password))
def login_to(email, password):
result = login_to1(email, password)
Timer(3, hide_msg).start()
return result
def hide_msg():
global state
state = 3
check_internet()
size = width, height = (640, 480)
screen = pygame.display.set_mode(size)
logo = load_image('https://fishc.com.cn/static/image/common/logo.png')
icon = load_image('https://fishc.com.cn/favicon.ico')
pygame.display.set_caption('FishC App')
pygame.display.set_icon(icon)
font15 = pygame.font.SysFont('microsoftyaheiui', 15)
font20 = pygame.font.SysFont('microsoftyaheiui', 20)
font20b = pygame.font.SysFont('microsoftyaheiui', 20)
font20b.set_bold(True)
chrome = Button('[C]hrome', (100, 50), font20, (0, 255, 0), (0, 0, 0), (100, 200), 'c')
firefox = Button('[F]irefox', (100, 50), font20, (0, 255, 0), (0, 0, 0), (300, 200), 'f')
c_chrome = Button('Change driver(Using Chrome)', (200, 50), font15, (255, 255, 255), (0, 0, 0), (width - 200, 0))
c_firefox = Button('Change driver(Using Firefox)', (200, 50), font15, (255, 255, 255), (0, 0, 0), (width - 200, 0))
change = c_chrome
login = Button('登录(L)', (100, 50), font20, (0, 0, 255), (255, 255, 255), (width - 123, height - 100), 'l')
save1 = Button('保存数据(S)', (150, 50), font20, (0, 0, 255), (255, 255, 255), (width // 2 - 125, height // 2 - 50), 's')
unsave = Button('不保存数据(N)', (150, 50), font20, (0, 0, 255), (255, 255, 255), (width // 2 - 125, height // 2 + 50), 'n')
swin = pygame.Rect(width // 4, height // 4, width // 2, height // 2)
username = Entry((200, 30), font20, (255, 255, 255), (0, 0, 127), (0, 0, 0), (200, 100))
pwd = Entry((200, 30), font20, (255, 255, 255), (0, 0, 127), (0, 0, 0), (200, 180))
t_user = Text('用户名/邮箱', font20b, (0, 0, 0), (90, 100))
t_pwd = Text('密码', font20b, (0, 0, 0), (100, 180))
logining = Text('', font15, (0, 0, 0), (300, 200))
succed = Text('', font15, (0, 0, 0), (width - 150, 10))
data = {
'driver': None,
'username': None,
'password': None
}
state = 0
if isfile('fishc.set'):
with open('fishc.set', 'rb') as f:
data = load(f)
thread = None
clock = pygame.time.Clock()
running = True
while running:
clock.tick(30)
screen.fill((255, 255, 255))
screen.blit(logo, (0, 0))
if state == 1:
pygame.draw.rect(screen, (0, 0, 0), swin, 2)
save1.draw()
unsave.draw()
elif state == 0:
if data['driver'] is None:
chrome.draw()
firefox.draw()
else:
change.draw()
if data['username'] is None or data['password'] is None:
username.draw()
t_user.draw()
pwd.draw()
t_pwd.draw()
login.draw()
elif state == 2:
if thread.result is None:
logining.text = '登录中...'
else:
logining.text = '登录成功!'
logining.draw()
elif state == 3:
succed.text = f'{thread.result[0]}(用户组: {thread.result[2]})'
succed.color = thread.result[1]
succed.rect.topleft = (width - succed.rect.width - 10, 10)
succed.draw()
for event in pygame.event.get():
if event.type == pygame.QUIT:
if state == 1:
running = False
# 虽然只会退出for
break
state = 1
if state == 1:
if save1.chosen(event):
save()
running = False
elif unsave.chosen(event):
running = False
else:
if data['driver'] is None:
temp = False
if chrome.chosen(event):
data['driver'] = (webdriver.Chrome, webdriver.ChromeOptions)
change = c_chrome
temp = True
elif firefox.chosen(event):
data['driver'] = (webdriver.Firefox, webdriver.FirefoxOptions)
change = c_firefox
temp = True
if temp:
option = data['driver'][1]()
option.add_argument('headless')
driver = data['driver'][0](options=option)
else:
if data['username'] is None or data['password'] is None:
username.listen(event)
pwd.listen(event)
if change.chosen(event):
data['driver'] = None
if login.chosen(event):
data['username'] = username.text.text
data['password'] = pwd.text.text
state = 2
thread = MyThread(func=login_to, args=(username.text.text, pwd.text.text))
thread.start()
pygame.display.flip()
pygame.quit()
driver.close()
就这么一个文件
main1.zip
(3.61 KB, 下载次数: 1)
picture:
抱歉,看起来是文本的渲染方式导致的。为了使文本更精确地居中,可以在绘制文本前计算文本宽度的一半,并将其减去屏幕宽度的一半。这样可以确保文本在屏幕中心位置上。修改代码如下:
1. 在 Text 类中添加一个方法 draw_centered ,用于计算并绘制居中的文本:
class Text:
# 省略其他代码...
def draw_centered(self, surface):
self.surface = self.font.render(self.text, True, self.color)
self.rect = self.surface.get_rect()
self.rect.center = (width // 2, height // 2)
surface.blit(self.surface, self.rect.topleft)
2. 更新 state == 3 的情况,使用新的 draw_centered 方法绘制居中的文本:
elif state == 3:
succed.text = f'{thread.result[0]}(用户组: {thread.result[2]})'
succed.color = thread.result[1]
succed.draw_centered(screen)
这样,当登录成功后,用户名和用户组信息将准确显示在屏幕正中间。
|
|