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