This commit is contained in:
liukang 2025-02-10 13:49:57 +08:00
commit d07b07cd45
15 changed files with 310 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (weverse)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (weverse)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/weverse.iml" filepath="$PROJECT_DIR$/.idea/weverse.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

10
.idea/weverse.iml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

3
config.json Normal file
View File

@ -0,0 +1,3 @@
{
"executable_path": "C:/Program Files/Google/Chrome/Application/chromedriver.exe"
}

5
config.py Normal file
View File

@ -0,0 +1,5 @@
DB_HOST = 'www.tixly.top'
DB_PORT = 13333
DB_USER = 'root'
DB_PASSWORD = 'Yy5203344.'
DB_NAME = 'weverse'

35
dao.py Normal file
View File

@ -0,0 +1,35 @@
import db
# 数据库连接
try:
db_conn = db.DatabaseConnection()
except Exception as e:
print("数据库连接失败!")
finally:
pass
# 根据num查询演出
def get_apply(num):
query = "SELECT * FROM perform WHERE num = %s limit 1"
result = db_conn.execute_query(query, num)
return result
# 根据演出id查询参与用户
def get_apply_user(pid):
query = "SELECT a.id, u.weverse_email,u.country_code, u.phone_num, u.weverse_password, u.birthday, u.wechat_num FROM apply a left join sys_user u on a.user_id=u.user_id WHERE a.perform_id = %s and a.status = '1' and a.token is null"
result = db_conn.execute_query(query, pid)
return result
# 根据申请id更新token和状态
def update_token(aid, token):
query = "UPDATE apply SET token = %s , status = '2' WHERE id = %s"
db_conn.execute_commit(query, (token, aid))
# apply = get_apply(1)
# if apply:
# user = get_apply_user(apply[0][0])
# print(user)

60
db.py Normal file
View File

@ -0,0 +1,60 @@
import pymysql
import config
import atexit
class DatabaseConnection:
_instance = None
_connection = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(DatabaseConnection, cls).__new__(cls, *args, **kwargs)
# 在这里初始化连接(注意:这里应该使用更安全的配置管理方式)
cls._connection = pymysql.connect(
host=config.DB_HOST,
user=config.DB_USER,
port=config.DB_PORT,
password=config.DB_PASSWORD,
database=config.DB_NAME
)
return cls._instance
def get_connection(self):
return self._connection
@classmethod
def close_connection(cls):
if cls._connection:
cls._connection.close()
cls._connection = None
@classmethod
def execute_query(cls, query, params=None):
"""执行查询并返回结果"""
try:
with cls._connection.cursor() as cursor:
cursor.execute(query, params)
result = cursor.fetchall()
return result
except pymysql.MySQLError as e:
print(f"Error: {e}")
finally:
pass
@classmethod
def execute_commit(cls, query, params=None):
"""执行查询并返回结果"""
try:
with cls._connection.cursor() as cursor:
cursor.execute(query, params)
cls._connection.commit()
except pymysql.MySQLError as e:
print(f"Error: {e}")
cls._connection.rollback()
finally:
pass
# 注册关闭连接的函数,以便在脚本退出时自动调用
atexit.register(DatabaseConnection.close_connection)

54
main.py Normal file
View File

@ -0,0 +1,54 @@
import dao
import sys
import proxy
import w_token
from concurrent.futures import ThreadPoolExecutor, as_completed
def task(aid, username, password):
# proxy_host = proxy.get_proxy()
# t = w_token.get_token(username, password, proxy_host[0], proxy_host[1])
t = w_token.get_token(username, password, None, None)
return [aid, username, t]
def main():
print("输入演出num")
num = input()
r = dao.get_apply(num)
if not r:
print("演出不存在")
sys.exit()
print("演出信息确认:")
print(r[0][2], r[0][3])
t = input("是否确认?(Y/N):")
if t == "N" or t == "n":
sys.exit()
print("请确认人员名单:")
u = dao.get_apply_user(r[0][0])
if not u:
print("人员不存在")
sys.exit()
print("weverse账号 区号 手机号")
for row in u:
print(row[1] + " " + row[2] + " " + row[3])
t = input("是否确认?(Y/N):")
if t == "N" or t == "n":
sys.exit()
with ThreadPoolExecutor(max_workers=5) as executor:
# 提交多个任务给线程池
futures = [executor.submit(task, row[0], row[1], row[4]) for row in u]
# 等待所有任务完成并获取结果
for future in as_completed(futures):
result = future.result()
if not result[2]:
print("applyId:【%s】,username:【%s】获取失败" % (result[0], result[1]))
continue
dao.update_token(result[0], result[2])
print("applyId:【%s】,username:【%s】获取成功!!!" % (result[0], result[1]))
if __name__ == "__main__":
main()

16
proxy.py Normal file
View File

@ -0,0 +1,16 @@
import requests
# 获取代理
def get_proxy():
headers = {
"User-Agent": 'Mozilla/5.0'
}
# proxy_url可通过多米HTTP代理网站购买后生成代理api链接每次请求api链接都是新的ip
proxy_url = 'http://need1.dmdaili.com:7771/dmgetip.asp?apikey=e2c93cc3&pwd=7e7b4dc0c932350a36142d3ed2cdb878&getnum=1&httptype=1&geshi=1&fenge=1&fengefu=&operate=2&setcity=all&provin=jiangsu'
aaa = requests.get(proxy_url, headers=headers).text
# matches = re.findall(r'(\d+\.\d+\.\d+\.\d+):(\d+)', aaa)
# result = [{'host': match[0], 'port': match[1]} for match in matches]
# return result
proxy_host = aaa.splitlines()[0]
return proxy_host.split(":")

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

7
stealth.min.js vendored Normal file

File diff suppressed because one or more lines are too long

85
w_token.py Normal file
View File

@ -0,0 +1,85 @@
from selenium import webdriver
from selenium_stealth import stealth
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service as ChromeService
import json
# 读取配置
f = open('config.json', 'r')
content = f.read()
f.close()
data = json.loads(content)
executablePath = data["executable_path"]
# 获取token
def get_token(email, password, proxy_ip, proxy_port):
# 设置代理
# proxy = Proxy()
# proxy.proxy_type = ProxyType.MANUAL
# proxy.http_proxy = f"{proxy_ip}:{proxy_port}"
# proxy.ssl_proxy = f"{proxy_ip}:{proxy_port}"
# 浏览器配置
options = webdriver.ChromeOptions()
# options.add_argument('--proxy-server=http://{}:{}'.format(proxy_ip, proxy_port))
options.add_experimental_option("detach", True)
options.add_experimental_option('useAutomationExtension', False)
options.add_experimental_option("excludeSwitches", ['enable-automation'])
options.add_argument('--start-maximized')
options.add_argument('disable-infobars')
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--disable-dev-shm-usage')
# service
service = ChromeService(executable_path=executablePath)
driver = webdriver.Chrome(service=service, options=options)
stealth(
driver,
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
languages=["en-US", "en"],
vendor="Google Inc.",
platform="Win32",
webgl_vendor="Intel Inc.",
renderer="Intel Iris OpenGL Engine",
fix_hairline=True,
)
# with open('stealth.min.js', 'r') as f:
# js = f.read()
# # 调用函数在页面加载前执行脚本
# driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': js})
try:
driver.get(
"https://account.weverse.io/zh-CN/login/redirect?client_id=weverse&redirect_uri=https%3A%2F%2Fweverse.io%2FloginResult%3Ftopath%3D%252F")
element = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.NAME, 'email'))
)
driver.find_element(By.NAME, value="email").send_keys(email)
driver.find_element(By.NAME, value="password").send_keys(password)
driver.find_element(By.XPATH, value='//button[@type="submit"]').click()
btn = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.CLASS_NAME, "body"))
)
cookies = driver.get_cookies()
access_token_value = None
# 遍历列表,找到 name 为 'we2_access_token' 的字典
for cookie in cookies:
if cookie['name'] == 'we2_access_token':
access_token_value = cookie['value']
break # 找到后退出循环
return access_token_value
except Exception as e:
return None
finally:
driver.quit()