move
This commit is contained in:
commit
d07b07cd45
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal 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
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal 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
7
.idea/misc.xml
Normal 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
8
.idea/modules.xml
Normal 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
6
.idea/vcs.xml
Normal 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
10
.idea/weverse.iml
Normal 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
3
config.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"executable_path": "C:/Program Files/Google/Chrome/Application/chromedriver.exe"
|
||||
}
|
5
config.py
Normal file
5
config.py
Normal 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
35
dao.py
Normal 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
60
db.py
Normal 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
54
main.py
Normal 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
16
proxy.py
Normal 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
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
7
stealth.min.js
vendored
Normal file
7
stealth.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
85
w_token.py
Normal file
85
w_token.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user