first commit
This commit is contained in:
+65
@@ -0,0 +1,65 @@
|
||||
.DS_Store
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
.idea/*
|
||||
xml_files/
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
other/split_clash_config/split_config
|
||||
ai_news/save_data
|
||||
daily/*.txt
|
||||
@@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 检查所有节点是否有重复
|
||||
import asyncio
|
||||
import httpx
|
||||
from typing import Optional, Dict, Any, List, Tuple
|
||||
|
||||
async def check_now_node(url_and_port: str) -> Optional[str]:
|
||||
"""检测当前节点并设置全局代理"""
|
||||
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
try:
|
||||
# 设置全局模式
|
||||
set_url = f"http://{url_and_port}/api/configs"
|
||||
set_data = {"mode": "Global"}
|
||||
set_response = await client.patch(set_url, json=set_data)
|
||||
set_response.raise_for_status()
|
||||
|
||||
# 获取代理信息
|
||||
get_url = f"http://{url_and_port}/api/proxies"
|
||||
get_response = await client.get(get_url)
|
||||
get_response.raise_for_status()
|
||||
|
||||
json_data = get_response.json()
|
||||
proxies: Dict[str, Any] = json_data.get("proxies", {})
|
||||
proxy_global: Dict[str, Any] = proxies.get("GLOBAL", {})
|
||||
now_proxy: Optional[str] = proxy_global.get("now")
|
||||
|
||||
return now_proxy
|
||||
|
||||
except httpx.HTTPError as exc:
|
||||
print(f"请求失败 {url_and_port}: {exc}")
|
||||
return None
|
||||
|
||||
async def batch_check_nodes(ip: str, ports: List[str]) -> Dict[str, Optional[str]]:
|
||||
"""批量检测节点"""
|
||||
tasks = [check_now_node(f"{ip}:{port}") for port in ports]
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
return {
|
||||
f"{ip}:{port}": result
|
||||
for port, result in zip(ports, results)
|
||||
}
|
||||
|
||||
def find_duplicate_nodes(results: Dict[str, Optional[str]]) -> List[Tuple[str, str]]:
|
||||
"""查找重复的节点"""
|
||||
node_to_urls = {}
|
||||
for url, node in results.items():
|
||||
if node: # 只处理成功检测的节点
|
||||
if node not in node_to_urls:
|
||||
node_to_urls[node] = []
|
||||
node_to_urls[node].append(url)
|
||||
|
||||
# 找出有重复的节点
|
||||
duplicates = []
|
||||
for node, urls in node_to_urls.items():
|
||||
if len(urls) > 1:
|
||||
for i in range(len(urls)):
|
||||
for j in range(i + 1, len(urls)):
|
||||
duplicates.append((urls[i], urls[j]))
|
||||
|
||||
return duplicates
|
||||
|
||||
if __name__ == "__main__":
|
||||
ip = '192.168.31.201'
|
||||
ports = [f'{58000 + i}' for i in range(1, 11)]
|
||||
|
||||
results = asyncio.run(batch_check_nodes(ip, ports))
|
||||
|
||||
# 输出所有节点信息
|
||||
for url, node in results.items():
|
||||
print(f"{url}: {node or '检测失败'}")
|
||||
|
||||
# 检查并输出重复节点
|
||||
duplicates = find_duplicate_nodes(results)
|
||||
if duplicates:
|
||||
print("\n发现重复节点:")
|
||||
for url1, url2 in duplicates:
|
||||
print(f"{url1} 和 {url2} 重复")
|
||||
else:
|
||||
print("\n没有发现重复节点")
|
||||
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 所有节点切换为全局
|
||||
import asyncio
|
||||
import httpx
|
||||
|
||||
async def set_global(url_and_port):
|
||||
url = f"http://{url_and_port}"
|
||||
key = "/api/configs"
|
||||
full_url = url + key
|
||||
|
||||
data = {"mode": "Global"}
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
try:
|
||||
response = await client.patch(full_url, json=data, headers=headers)
|
||||
response.raise_for_status() # 自动抛出4xx/5xx异常
|
||||
print(f"成功设置 {url_and_port}")
|
||||
return True
|
||||
except httpx.HTTPError as exc:
|
||||
print(f"请求失败 {url_and_port}: {exc}")
|
||||
return False
|
||||
|
||||
async def main():
|
||||
ip = '192.168.31.201'
|
||||
port_list = [f'{58000 + i}' for i in range(1, 11)] # 生成端口列表
|
||||
|
||||
# 创建任务列表
|
||||
tasks = [set_global(f"{ip}:{port}") for port in port_list]
|
||||
|
||||
# 并发执行所有任务
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
# 统计结果
|
||||
success_count = sum(results)
|
||||
print(f"\n完成设置: {success_count}/{len(port_list)} 个代理成功")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,180 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
获取超级大乐透结果, 并匹配自己购买的号码, 配合定时执行使用
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import asyncio
|
||||
import httpx
|
||||
|
||||
sys.path.append(os.path.join(os.path.abspath(__file__).split('manual')[0] + 'manual'))
|
||||
|
||||
from utils.utils_send_gotify import GotifyNotifier
|
||||
|
||||
|
||||
class CheckDlt:
|
||||
def __init__(self):
|
||||
self.url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=1&isVerify=1&pageNo=1'
|
||||
self.headers = {
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9",
|
||||
"Cache-Control": "max-age=0",
|
||||
"Priority": "u=0, i",
|
||||
"Sec-CH-UA": '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
|
||||
"Sec-CH-UA-Mobile": "?0",
|
||||
"Sec-CH-UA-Platform": '"macOS"',
|
||||
"Sec-Fetch-Dest": "document",
|
||||
"Sec-Fetch-Mode": "navigate",
|
||||
"Sec-Fetch-Site": "none",
|
||||
"Sec-Fetch-User": "?1",
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
|
||||
}
|
||||
self.my_dlt = [
|
||||
['10', '11', '16', '17', '18', '11', '12'],
|
||||
['02', '03', '11', '12', '23', '05', '06'],
|
||||
['07', '09', '15', '17', '22', '09', '11'],
|
||||
['05', '06', '07', '34', '35', '02', '09'],
|
||||
['09', '10', '11', '21', '22', '04', '05']
|
||||
]
|
||||
|
||||
async def req(self):
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
resp = await client.get(self.url, timeout=5)
|
||||
if resp.status_code != 200:
|
||||
print('state code: {}'.format(resp.status_code))
|
||||
log_detail = '访问失败, 状态码:{},url:{}'.format(resp.status_code, self.url)
|
||||
print(log_detail)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f'请求失败 {e}')
|
||||
return None
|
||||
|
||||
return resp.json()
|
||||
|
||||
def data_handle(self, data):
|
||||
if not data:
|
||||
print('获取数据为空')
|
||||
return None
|
||||
|
||||
value = data.get('value')
|
||||
data_list = value.get('list')
|
||||
|
||||
if not data_list:
|
||||
print('获取数据为空')
|
||||
return None
|
||||
|
||||
result_data = []
|
||||
|
||||
for d in data_list:
|
||||
numbers = d.get('lotteryUnsortDrawresult')
|
||||
try:
|
||||
if len(numbers.split(' ')) < 7:
|
||||
continue
|
||||
except Exception as e:
|
||||
print('numbers: {}, err: {}'.format(numbers, e))
|
||||
continue
|
||||
|
||||
red_list = numbers.split(' ')[:5]
|
||||
blue_list = numbers.split(' ')[5:]
|
||||
|
||||
red_list.sort()
|
||||
blue_list.sort()
|
||||
|
||||
try:
|
||||
# 切开红球,蓝球数组
|
||||
red1 = red_list[0]
|
||||
red2 = red_list[1]
|
||||
red3 = red_list[2]
|
||||
red4 = red_list[3]
|
||||
red5 = red_list[4]
|
||||
blue1 = blue_list[0]
|
||||
blue2 = blue_list[1]
|
||||
except Exception as e:
|
||||
print('红球或蓝球数据丢失')
|
||||
continue
|
||||
|
||||
result_data.append({
|
||||
'serial': d.get('lotteryDrawNum'),
|
||||
'red1': red1 or '',
|
||||
'red2': red2 or '',
|
||||
'red3': red3 or '',
|
||||
'red4': red4 or '',
|
||||
'red5': red5 or '',
|
||||
'blue1': blue1 or '',
|
||||
'blue2': blue2 or '',
|
||||
'drawPdfUrl': d.get('drawPdfUrl'),
|
||||
'date': d.get('lotteryDrawTime'),
|
||||
'pool': d.get('poolBalanceAfterdraw')
|
||||
})
|
||||
|
||||
if result_data:
|
||||
return result_data
|
||||
else:
|
||||
print('返回的数据为空, 获取数据失败')
|
||||
return None
|
||||
|
||||
def data_compare(self, all_data):
|
||||
if not all_data:
|
||||
return '', ''
|
||||
|
||||
data = all_data[0]
|
||||
|
||||
red_list = [data['red1'], data['red2'], data['red3'], data['red4'], data['red5']]
|
||||
blue_list = [data['blue1'], data['blue2']]
|
||||
|
||||
# 期号
|
||||
subject = '{}'.format(data['serial'])
|
||||
|
||||
# 组成每期数据的text
|
||||
serial_text = 'serial: {}\t\tlottery draw date: {}\nbonus pool: {} RMB\n{}\nlottery draw num: {} + {}\n\n'.format(
|
||||
data['serial'], data['date'], data['pool'], '*' * 90,
|
||||
red_list, blue_list)
|
||||
|
||||
for my_num in self.my_dlt:
|
||||
my_red_list = my_num[:5]
|
||||
my_blue_list = my_num[5:]
|
||||
|
||||
# 使用列表推导式找出两个列表中都存在的元素
|
||||
red_common_elements = [element for element in red_list if element in my_red_list]
|
||||
blue_common_elements = [element for element in blue_list if element in my_blue_list]
|
||||
|
||||
# 计算相等元素的数量
|
||||
red_equal_count = len(red_common_elements)
|
||||
blue_equal_count = len(blue_common_elements)
|
||||
|
||||
serial_text += 'my nums: {} + {}\nred hit: {}\nblue hit: {}\n\n'.format(my_red_list, my_blue_list,
|
||||
red_equal_count,
|
||||
blue_equal_count)
|
||||
|
||||
serial_text += '{}\n\n\n\n'.format('*' * 90)
|
||||
|
||||
return serial_text, subject
|
||||
|
||||
def send_message(self, text, subject):
|
||||
if not text:
|
||||
return
|
||||
|
||||
title = f'dlt {subject}'
|
||||
|
||||
# 推送到 message
|
||||
GotifyNotifier(title, text, 'dlt').send_message()
|
||||
|
||||
# 发送到邮件
|
||||
# SendEmail(title, title, text).send()
|
||||
|
||||
async def main(self):
|
||||
data = await self.req()
|
||||
result_data = self.data_handle(data)
|
||||
if not result_data:
|
||||
return
|
||||
|
||||
text, subject = self.data_compare(result_data)
|
||||
self.send_message(text, subject)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(CheckDlt().main())
|
||||
@@ -0,0 +1,171 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
获取超级大乐透结果, 并匹配自己购买的号码, 配合定时执行使用
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import asyncio
|
||||
import httpx
|
||||
|
||||
sys.path.append(os.path.join(os.path.abspath(__file__).split('manual')[0] + 'manual'))
|
||||
|
||||
from utils.utils_send_gotify import GotifyNotifier
|
||||
|
||||
|
||||
class CheckDlt:
|
||||
def __init__(self):
|
||||
self.headers = {
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9",
|
||||
"Cache-Control": "max-age=0",
|
||||
"Priority": "u=0, i",
|
||||
"Sec-CH-UA": '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
|
||||
"Sec-CH-UA-Mobile": "?0",
|
||||
"Sec-CH-UA-Platform": '"macOS"',
|
||||
"Sec-Fetch-Dest": "document",
|
||||
"Sec-Fetch-Mode": "navigate",
|
||||
"Sec-Fetch-Site": "none",
|
||||
"Sec-Fetch-User": "?1",
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
|
||||
}
|
||||
self.my_dlt = [
|
||||
['10', '11', '16', '17', '18', '11', '12'],
|
||||
['02', '03', '11', '12', '23', '05', '06'],
|
||||
['07', '09', '15', '17', '22', '09', '11'],
|
||||
['05', '06', '07', '34', '35', '02', '09'],
|
||||
['09', '10', '11', '21', '22', '04', '05']
|
||||
]
|
||||
|
||||
async def req(self, url):
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
resp = await client.get(url, timeout=5)
|
||||
if resp.status_code != 200:
|
||||
print('state code: {}'.format(resp.status_code))
|
||||
log_detail = '访问失败, 状态码:{},url:{}'.format(resp.status_code, url)
|
||||
print(log_detail)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f'请求失败 {e}')
|
||||
return None
|
||||
|
||||
return resp.json()
|
||||
|
||||
def data_handle(self, data):
|
||||
if not data:
|
||||
print('获取数据为空')
|
||||
return None
|
||||
|
||||
value = data.get('value')
|
||||
if not value:
|
||||
print('获取数据为空')
|
||||
return None
|
||||
data_list = value.get('list')
|
||||
|
||||
if not data_list:
|
||||
print('获取数据为空')
|
||||
return None
|
||||
|
||||
result_data = []
|
||||
|
||||
for d in data_list:
|
||||
numbers = d.get('lotteryUnsortDrawresult')
|
||||
try:
|
||||
if len(numbers.split(' ')) < 7:
|
||||
continue
|
||||
except Exception as e:
|
||||
print('numbers: {}, err: {}'.format(numbers, e))
|
||||
continue
|
||||
|
||||
red_list = numbers.split(' ')[:5]
|
||||
blue_list = numbers.split(' ')[5:]
|
||||
|
||||
red_list.sort()
|
||||
blue_list.sort()
|
||||
|
||||
try:
|
||||
red1 = red_list[0]
|
||||
red2 = red_list[1]
|
||||
red3 = red_list[2]
|
||||
red4 = red_list[3]
|
||||
red5 = red_list[4]
|
||||
blue1 = blue_list[0]
|
||||
blue2 = blue_list[1]
|
||||
except Exception as e:
|
||||
print('红球或蓝球数据丢失')
|
||||
continue
|
||||
|
||||
result_data.append({
|
||||
'serial': d.get('lotteryDrawNum'),
|
||||
'red1': red1 or '',
|
||||
'red2': red2 or '',
|
||||
'red3': red3 or '',
|
||||
'red4': red4 or '',
|
||||
'red5': red5 or '',
|
||||
'blue1': blue1 or '',
|
||||
'blue2': blue2 or '',
|
||||
'drawPdfUrl': d.get('drawPdfUrl'),
|
||||
'date': d.get('lotteryDrawTime'),
|
||||
'pool': d.get('poolBalanceAfterdraw')
|
||||
})
|
||||
|
||||
if result_data:
|
||||
return result_data
|
||||
else:
|
||||
print('返回的数据为空, 获取数据失败')
|
||||
return None
|
||||
|
||||
def data_compare(self, all_data):
|
||||
if not all_data:
|
||||
return '', ''
|
||||
|
||||
data = all_data[0]
|
||||
|
||||
red_list = [data['red1'], data['red2'], data['red3'], data['red4'], data['red5']]
|
||||
blue_list = [data['blue1'], data['blue2']]
|
||||
|
||||
# 期号
|
||||
subject = '{}'.format(data['serial'])
|
||||
|
||||
# 组成每期数据的text
|
||||
serial_text = 'serial: {}\t\tlottery draw date: {}\nbonus pool: {} RMB\n{}\nlottery draw num: {} + {}\n\n'.format(
|
||||
data['serial'], data['date'], data['pool'], '*' * 90,
|
||||
red_list, blue_list)
|
||||
|
||||
for my_num in self.my_dlt:
|
||||
my_red_list = my_num[:5]
|
||||
my_blue_list = my_num[5:]
|
||||
|
||||
# 使用列表推导式找出两个列表中都存在的元素
|
||||
red_common_elements = [element for element in red_list if element in my_red_list]
|
||||
blue_common_elements = [element for element in blue_list if element in my_blue_list]
|
||||
|
||||
# 计算相等元素的数量
|
||||
red_equal_count = len(red_common_elements)
|
||||
blue_equal_count = len(blue_common_elements)
|
||||
|
||||
serial_text += 'my nums: {} + {}\nred hit: {}\nblue hit: {}\n\n'.format(my_red_list, my_blue_list,
|
||||
red_equal_count,
|
||||
blue_equal_count)
|
||||
|
||||
serial_text += '{}\n\n\n\n'.format('*' * 90)
|
||||
|
||||
return serial_text, subject
|
||||
|
||||
async def main(self):
|
||||
for no in range(3, 0, -1):
|
||||
url = f'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=1&isVerify=1&pageNo={no}'
|
||||
data_list = await self.req(url)
|
||||
result_data = self.data_handle(data_list)
|
||||
if not result_data:
|
||||
continue
|
||||
|
||||
text, subject = self.data_compare(result_data)
|
||||
print(text)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(CheckDlt().main())
|
||||
@@ -0,0 +1,247 @@
|
||||
aiodns==3.2.0
|
||||
aiofiles==24.1.0
|
||||
aiogram==3.18.0
|
||||
aiohappyeyeballs==2.4.6
|
||||
aiohttp==3.9.5
|
||||
aiohttp-socks==0.8.4
|
||||
aioquic==1.2.0
|
||||
aiosignal==1.3.2
|
||||
annotated-types==0.7.0
|
||||
anyio==4.1.0
|
||||
appdirs==1.4.4
|
||||
APScheduler==3.10.4
|
||||
asgiref==3.8.1
|
||||
async-timeout==4.0.3
|
||||
atomicwrites==1.4.1
|
||||
attrs==25.1.0
|
||||
base58==2.1.1
|
||||
beautifulsoup4==4.12.2
|
||||
bech32==1.2.0
|
||||
better-proxy==1.1.5
|
||||
bidict==0.23.1
|
||||
bitarray==3.1.0
|
||||
blessed==1.20.0
|
||||
blinker==1.9.0
|
||||
Brotli==1.1.0
|
||||
bs4==0.0.1
|
||||
cairocffi==1.7.1
|
||||
CairoSVG==2.7.1
|
||||
captchatools==1.5.0
|
||||
ccxt==4.4.75
|
||||
certifi==2025.1.31
|
||||
cffi==1.16.0
|
||||
charset-normalizer==3.4.1
|
||||
ckzg==2.0.1
|
||||
click==8.1.7
|
||||
colorama==0.4.6
|
||||
coloredlogs==15.0.1
|
||||
cryptography==36.0.1
|
||||
cssselect2==0.8.0
|
||||
curl_cffi==0.10.0
|
||||
customtkinter==5.2.2
|
||||
Cython==3.1.2
|
||||
cytoolz==1.0.1
|
||||
darkdetect==0.8.0
|
||||
dateparser==1.1.3
|
||||
ddddocr==1.5.6
|
||||
defusedxml==0.7.1
|
||||
distro==1.9.0
|
||||
dnspython==2.4.2
|
||||
docutils==0.21.2
|
||||
dukpy==0.4.0
|
||||
easy-clash-tool==0.0.3
|
||||
easy-spider-tool==1.0.16
|
||||
editor==1.6.6
|
||||
et_xmlfile==2.0.0
|
||||
eth-account==0.13.5
|
||||
eth-hash==0.7.1
|
||||
eth-keyfile==0.8.1
|
||||
eth-keys==0.6.1
|
||||
eth-rlp==2.2.0
|
||||
eth-typing==5.2.0
|
||||
eth-utils==5.2.0
|
||||
eth_abi==5.2.0
|
||||
exceptiongroup==1.2.0
|
||||
fake-useragent==1.5.1
|
||||
Faker==23.2.1
|
||||
fastapi==0.115.12
|
||||
Flask==3.1.0
|
||||
flatbuffers==25.2.10
|
||||
frozenlist==1.5.0
|
||||
greenlet==3.1.1
|
||||
h11==0.14.0
|
||||
h2==4.1.0
|
||||
hexbytes==1.3.0
|
||||
hpack==4.0.0
|
||||
httpcore==1.0.2
|
||||
httptools==0.6.4
|
||||
httpx==0.27.2
|
||||
humanfriendly==10.0
|
||||
hyperframe==6.0.1
|
||||
idna==3.10
|
||||
ifaddr==0.2.0
|
||||
importlib-metadata==7.0.0
|
||||
inquirer==3.4.0
|
||||
itsdangerous==2.2.0
|
||||
jieba==0.42.1
|
||||
Jinja2==3.1.6
|
||||
jiter==0.5.0
|
||||
jsonpath==0.82
|
||||
jsonschema==4.23.0
|
||||
jsonschema-specifications==2023.12.1
|
||||
kaitaistruct==0.10
|
||||
ldap3==2.9.1
|
||||
loguru==0.7.3
|
||||
lxml==5.3.0
|
||||
magic-filter==1.0.12
|
||||
markdown-it-py==3.0.0
|
||||
markdown2==2.5.3
|
||||
MarkupSafe==3.0.2
|
||||
matrix-client==0.4.0
|
||||
matrix-nio==0.25.0
|
||||
mdurl==0.1.2
|
||||
mitmproxy==11.0.2
|
||||
mitmproxy-macos==0.10.7
|
||||
mitmproxy_rs==0.10.7
|
||||
mnemonic==0.21
|
||||
MouseInfo==0.1.3
|
||||
mpmath==1.3.0
|
||||
msgpack==1.1.0
|
||||
multidict==6.1.0
|
||||
mutf8==1.0.6
|
||||
names==0.3.0
|
||||
nicegui==2.14.1
|
||||
numpy==1.26.4
|
||||
ollama==0.4.6
|
||||
onnxruntime==1.16.3
|
||||
openai==1.42.0
|
||||
opencv-python-headless==4.11.0.86
|
||||
openpyxl==3.1.5
|
||||
orjson==3.10.16
|
||||
outcome==1.3.0.post0
|
||||
packaging==23.2
|
||||
paho-mqtt==2.1.0
|
||||
pandas==2.2.3
|
||||
parsimonious==0.10.0
|
||||
passlib==1.7.4
|
||||
patchright==1.50.0
|
||||
pillow==11.1.0
|
||||
ping3==4.0.4
|
||||
playwright==1.46.0
|
||||
primp==0.14.0
|
||||
prompt_toolkit==3.0.50
|
||||
propcache==0.3.0
|
||||
protobuf==5.29.3
|
||||
pscript==0.7.7
|
||||
psycopg2==2.9.9
|
||||
publicsuffix2==2.20191221
|
||||
py-solc-x==2.0.3
|
||||
pyasn1==0.5.1
|
||||
pyasn1_modules==0.4.1
|
||||
PyAutoGUI==0.9.54
|
||||
pycares==4.6.0
|
||||
pycparser==2.21
|
||||
pycryptodome==3.21.0
|
||||
pydantic==2.10.6
|
||||
pydantic_core==2.27.2
|
||||
pydivert==2.1.0
|
||||
pyee==12.1.1
|
||||
PyExecJS==1.5.1
|
||||
PyGetWindow==0.0.9
|
||||
Pygments==2.19.1
|
||||
pygpt4all==1.1.0
|
||||
pygptj==2.0.3
|
||||
pyhttpx==2.10.9
|
||||
pyllamacpp==2.4.2
|
||||
pylsqpack==0.3.19
|
||||
pymongo==4.6.1
|
||||
PyMsgBox==1.0.9
|
||||
PyNaCl==1.5.0
|
||||
pynocaptcha==2.0.52
|
||||
pyobjc-core==11.0
|
||||
pyobjc-framework-Cocoa==11.0
|
||||
pyobjc-framework-Quartz==11.0
|
||||
pyOpenSSL==21.0.0
|
||||
pyparsing==3.1.1
|
||||
pyperclip==1.9.0
|
||||
pyppeteer==2.0.0
|
||||
PyRect==0.2.0
|
||||
PyRSS2Gen==1.1
|
||||
PyScreeze==1.0.1
|
||||
pyshark==0.6
|
||||
PySocks==1.7.1
|
||||
python-dateutil==2.9.0.post0
|
||||
python-dotenv==1.1.0
|
||||
python-engineio==4.12.0
|
||||
python-multipart==0.0.20
|
||||
python-socketio==5.13.0
|
||||
python-socks==2.5.1
|
||||
pytweening==1.2.0
|
||||
pytz==2025.1
|
||||
pyunormalize==16.0.0
|
||||
PyYAML==6.0.2
|
||||
questionary==2.1.0
|
||||
RandomWords==0.4.0
|
||||
readchar==4.2.1
|
||||
redis==5.0.1
|
||||
referencing==0.35.1
|
||||
regex==2024.11.6
|
||||
requests==2.32.3
|
||||
retrying==1.3.4
|
||||
rich==13.9.4
|
||||
rlp==4.1.0
|
||||
rpds-py==0.20.0
|
||||
rsa==4.8
|
||||
ruamel.yaml==0.18.6
|
||||
ruamel.yaml.clib==0.2.12
|
||||
rubicon-objc==0.5.0
|
||||
runs==1.2.2
|
||||
scapy==2.5.0
|
||||
schedule==1.2.1
|
||||
screeninfo==0.8.1
|
||||
selenium==4.16.0
|
||||
selenium-wire==5.1.0
|
||||
service-identity==24.2.0
|
||||
simple-websocket==1.1.0
|
||||
six==1.16.0
|
||||
sniffio==1.3.0
|
||||
sortedcontainers==2.4.0
|
||||
soupsieve==2.5
|
||||
SQLAlchemy==2.0.36
|
||||
starlette==0.46.2
|
||||
sui-brownie==1.2.4
|
||||
sympy==1.13.3
|
||||
tabulate==0.9.0
|
||||
tenacity==8.2.3
|
||||
termcolor==2.4.0
|
||||
tinycss2==1.4.0
|
||||
toml==0.10.2
|
||||
toolz==1.0.0
|
||||
tornado==6.4.2
|
||||
tqdm==4.66.1
|
||||
trio==0.23.1
|
||||
trio-websocket==0.11.1
|
||||
types-requests==2.32.0.20250301
|
||||
typing_extensions==4.12.2
|
||||
tzdata==2025.2
|
||||
tzlocal==5.2
|
||||
unpaddedbase64==2.1.0
|
||||
urllib3==2.3.0
|
||||
urwid==2.6.16
|
||||
uvicorn==0.29.0
|
||||
uvloop==0.21.0
|
||||
vbuild==0.8.2
|
||||
watchfiles==1.0.5
|
||||
wcwidth==0.2.13
|
||||
web3==7.8.0
|
||||
webencodings==0.5.1
|
||||
websockets==13.1
|
||||
Werkzeug==3.1.3
|
||||
win32_setctime==1.2.0
|
||||
wsproto==1.2.0
|
||||
xmltodict==0.13.0
|
||||
xmod==1.8.1
|
||||
yarl==1.18.3
|
||||
you-get==0.4.1730
|
||||
zipp==3.17.0
|
||||
zstandard==0.22.0
|
||||
@@ -0,0 +1,33 @@
|
||||
import httpx
|
||||
|
||||
content = "简单讲解一下mvc模型上下文"
|
||||
key = "sk-mepewzmlykchrjosberepdvvbnrjbhoamewefnckokitveqf"
|
||||
model = "THUDM/GLM-4.1V-9B-Thinking"
|
||||
url = "https://api.siliconflow.cn/v1/chat/completions"
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
payload = {
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": content}]
|
||||
}
|
||||
|
||||
with httpx.Client(timeout=999) as client:
|
||||
response = client.post(url, headers=headers, json=payload)
|
||||
if response.json()["choices"][0]["message"]["content"]:
|
||||
content = response.json()["choices"][0]["message"]["content"]
|
||||
content = content.split("\n")
|
||||
for i in content:
|
||||
print(i)
|
||||
else:
|
||||
print(response.json())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import time
|
||||
|
||||
import psycopg2
|
||||
from psycopg2 import Error
|
||||
|
||||
|
||||
class CreateRssRecord(object):
|
||||
def __init__(self):
|
||||
self.hostname = 'erhe.top'
|
||||
self.port = 20788
|
||||
self.database = 'freshrss'
|
||||
self.user = 'freshrss'
|
||||
self.password = 'freshrss'
|
||||
self.conn = None
|
||||
|
||||
def connect(self):
|
||||
"""连接到 PostgreSQL 数据库"""
|
||||
try:
|
||||
self.conn = psycopg2.connect(
|
||||
dbname=self.database,
|
||||
user=self.user,
|
||||
password=self.password,
|
||||
host=self.hostname,
|
||||
port=self.port
|
||||
)
|
||||
except Error as e:
|
||||
print(f"Error connecting to the database: {e}")
|
||||
else:
|
||||
print("Connected to the database successfully.")
|
||||
|
||||
if not self.conn:
|
||||
raise Exception("Database connection failed")
|
||||
|
||||
def check_and_insert(self, data):
|
||||
"""检查 URL 是否存在,如果不存在则插入整个数据字典"""
|
||||
try:
|
||||
with self.conn.cursor() as cursor:
|
||||
# 检查 URL 是否存在
|
||||
select_sql = "SELECT COUNT(*) FROM freshrsstoor_feed WHERE url = %s"
|
||||
cursor.execute(select_sql, (data['url'],))
|
||||
result = cursor.fetchone()
|
||||
if result[0] == 0:
|
||||
# URL 不存在,插入新记录
|
||||
columns = ', '.join(data.keys())
|
||||
values = ', '.join(['%s'] * len(data))
|
||||
insert_sql = """INSERT INTO freshrsstoor_feed
|
||||
(url, kind, category, "name", website, description, "lastUpdate", priority, "pathEntries", "httpAuth", "error", "ttl", attributes, "cache_nbEntries", "cache_nbUnreads")
|
||||
VALUES ('{}', {}, {}, '{}', '{}', '{}', {}, {}, '{}', '{}', {}, {}, '{}', {}, {});""".format(
|
||||
data['url'],
|
||||
data['kind'],
|
||||
data['category'],
|
||||
data['name'],
|
||||
data['website'],
|
||||
data['description'],
|
||||
data['lastUpdate'],
|
||||
data['priority'],
|
||||
data['pathEntries'],
|
||||
data['httpAuth'],
|
||||
data['error'],
|
||||
data['ttl'],
|
||||
data['attributes'],
|
||||
data['cache_nbEntries'],
|
||||
data['cache_nbUnreads']
|
||||
)
|
||||
cursor.execute(insert_sql, tuple(data.values()))
|
||||
self.conn.commit()
|
||||
print("Data inserted successfully.")
|
||||
else:
|
||||
print("URL already exists.")
|
||||
except Error as e:
|
||||
print(f"Error: {e}")
|
||||
finally:
|
||||
if self.conn is not None:
|
||||
self.conn.close()
|
||||
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
cr = CreateRssRecord()
|
||||
cr.connect()
|
||||
insert_data = {
|
||||
'url': 'https://rsshub.app/jike/topic/556688fae4b00c57d9dd46ee',
|
||||
'category': 7,
|
||||
'name': '今日份的摄影 - 即刻圈子',
|
||||
'website': 'http://finance.sina.com.cn/china/',
|
||||
'description': '爱摄影的即友都在这里~分享原创摄影作品,感受照片背后的共鸣吧! - Powered by RSSHub',
|
||||
'kind': 0,
|
||||
'lastUpdate': int(time.time()),
|
||||
'priority': 10,
|
||||
'pathEntries': '',
|
||||
'httpAuth': '',
|
||||
'error': 0,
|
||||
'ttl': 0,
|
||||
'attributes': '{"curl_params":null,"ssl_verify":null,"timeout":null}',
|
||||
'cache_nbEntries': 0,
|
||||
'cache_nbUnreads': 0
|
||||
}
|
||||
cr.check_and_insert(insert_data)
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import aiohttp
|
||||
import asyncio
|
||||
|
||||
|
||||
async def fetch(url):
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url) as response:
|
||||
return await response.text()
|
||||
|
||||
|
||||
async def main():
|
||||
url = 'http://api.ip.cc'
|
||||
content = await fetch(url)
|
||||
print(content)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
'''
|
||||
Proxy server: 175.99.17.215
|
||||
port: 6011
|
||||
username: lumi-jiege0210
|
||||
password: aaaAAA111
|
||||
'''
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import httpx
|
||||
|
||||
|
||||
def get_public_ip():
|
||||
try:
|
||||
# 使用 httpx 发起请求
|
||||
response = httpx.get("https://httpbin.org/ip", timeout=10)
|
||||
response.raise_for_status() # 检查请求是否成功
|
||||
ip_data = response.json()
|
||||
return ip_data["origin"]
|
||||
except httpx.RequestError as e:
|
||||
print(f"An error occurred while obtaining the public IP address.:{e}")
|
||||
exit(1)
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
# 青龙面板的地址
|
||||
url = "https://auto.erhe.top"
|
||||
|
||||
|
||||
# 登录青龙面板
|
||||
def login():
|
||||
response = requests.post(f"{url}/api/user/login", json={"username": "toor", "password": "!QAZ2wsx+0913"})
|
||||
print(response)
|
||||
if response.status_code != 200:
|
||||
print(response.status_code)
|
||||
print(response.text)
|
||||
exit(0)
|
||||
return response.json()['data']['token']
|
||||
|
||||
|
||||
# 获取任务列表
|
||||
def get_tasks(token):
|
||||
response = requests.get(f"{url}/api/crons", headers={"Authorization": f"Bearer {token}"})
|
||||
return response.json()['data']['data']
|
||||
|
||||
|
||||
# 创建任务
|
||||
def create_task(task_template, token):
|
||||
payload = {
|
||||
"name": task_template["name"],
|
||||
"command": task_template["command"],
|
||||
"schedule": task_template["schedule"],
|
||||
"labels": task_template["labels"]
|
||||
}
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(f"{url}/api/crons", headers=headers, json=payload)
|
||||
return response.json()
|
||||
|
||||
|
||||
# 创建视图分类
|
||||
def create_view_type(token):
|
||||
view_type_list = ['base', 'spider_common']
|
||||
for view_type in view_type_list:
|
||||
payload = {
|
||||
"name": view_type,
|
||||
"filters": {
|
||||
'property': 'labels',
|
||||
'operation': 'Reg',
|
||||
'value': view_type
|
||||
},
|
||||
'filterRelation': 'and'
|
||||
}
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(f"{url}/api/crons", headers=headers, json=payload)
|
||||
|
||||
|
||||
# 主逻辑
|
||||
def main():
|
||||
while True:
|
||||
try:
|
||||
token = login()
|
||||
print(f"已连接到 {url}")
|
||||
tasks = get_tasks(token)
|
||||
tasks_names = [task['name'] for task in tasks]
|
||||
if tasks:
|
||||
print("Current tasks name: \n{}, \ntotal: {}".format('\n'.join(tasks_names), str(len(tasks_names))))
|
||||
else:
|
||||
print("Tasks list is empty")
|
||||
|
||||
project_path = '/ql/data/scripts/auto/'
|
||||
base_path = os.path.join(project_path, 'base')
|
||||
spider_path = os.path.join(project_path, 'spider')
|
||||
message_path = os.path.join(project_path, 'message')
|
||||
manual_path = os.path.join(project_path, 'manual')
|
||||
daily_path = os.path.join(project_path, 'daily')
|
||||
tasks_template = [{
|
||||
'base_tasks': [
|
||||
{
|
||||
"name": "每天开始自动创建日志",
|
||||
"command": "python3 {}/base_daily_logs_generate.py".format(base_path),
|
||||
"schedule": "0 0 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "每天结束自动发送日志",
|
||||
"command": "python3 {}/base_daily_logs_send.py".format(base_path),
|
||||
"schedule": "58 23 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "每天自动删除旧数据",
|
||||
"command": "python3 {}/base_timing_remove_data.py".format(base_path),
|
||||
"schedule": "1 0 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "每天新闻汇总,发送到邮箱",
|
||||
"command": "python3 {}/base_news_data_collation.py".format(base_path),
|
||||
"schedule": "0 10 6,12,18 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "定时刷新 freshrss 订阅源",
|
||||
"command": "python3 {}/update_feed.py".format(base_path),
|
||||
"schedule": "0 6,22 * * *",
|
||||
"labels": ["base"]
|
||||
}
|
||||
],
|
||||
'spider': [
|
||||
{
|
||||
"name": "自动执行反斗限免爬虫",
|
||||
"command": "python3 {}/news_get_apprcn.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行chiphell爬虫",
|
||||
"command": "python3 {}/news_get_chiphell.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行hello_github爬虫",
|
||||
"command": "python3 {}/news_get_hello_github.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行Anyknew爬虫",
|
||||
"command": "python3 {}/news_get_news.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行币界网文章爬虫",
|
||||
"command": "python3 {}/spider_web3_coin_world.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "获取 web3 新闻",
|
||||
"command": "python3 {}/spider_web3_news.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行dlt爬虫",
|
||||
"command": "python3 {}/spider_get_and_check_dlt.py".format(spider_path),
|
||||
"schedule": "30 22 * * 1,3,6",
|
||||
"labels": ["spider"]
|
||||
}
|
||||
],
|
||||
'message_tasks': [
|
||||
{
|
||||
"name": "获取coin实时数据",
|
||||
"command": "python3 {}/message_coin_detail.py".format(message_path),
|
||||
"schedule": "0 * * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "对比大乐透最新一期数据,匹配已购买号码,发送消息",
|
||||
"command": "python3 {}/message_dlt.py".format(message_path),
|
||||
"schedule": "30 22 * * 1,3,6",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "获取未来 7 天的天气预报",
|
||||
"command": "python3 {}/message_get_one_week_weather.py".format(message_path),
|
||||
"schedule": "0 0 6,22 * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "从 freshrss-psql 数据库中读取数据并发送",
|
||||
"command": "python3 {}/message_rss_data_handel.py".format(message_path),
|
||||
"schedule": "30 6,9,12,18,22 * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "空投任务消息",
|
||||
"command": "python3 {}/message_airdrop_tasks.py".format(message_path),
|
||||
"schedule": "0 8,20 * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "链捕手快讯消息推送",
|
||||
"command": "python3 {}/message_chaincatcher.py".format(message_path),
|
||||
"schedule": "0 */2 * * *",
|
||||
"labels": ["message"]
|
||||
}
|
||||
],
|
||||
'manual': [
|
||||
{
|
||||
"name": "手动读取rss订阅新闻",
|
||||
"command": "python3 {}/read_news.py".format(manual_path),
|
||||
"schedule": "0 0 1 1 *",
|
||||
"labels": ["manual"]
|
||||
}
|
||||
],
|
||||
'daily': [
|
||||
{
|
||||
"name": "3dos自动签到",
|
||||
"command": "python3 {}/daily_3dos.py".format(daily_path),
|
||||
"schedule": "*/5 * * * *",
|
||||
"labels": ["daily"]
|
||||
}
|
||||
],
|
||||
}]
|
||||
|
||||
for task_template in tasks_template:
|
||||
for task_type, task_list in task_template.items():
|
||||
for task in task_list:
|
||||
task_name = task["name"]
|
||||
if task_name in tasks_names:
|
||||
print("Task {} already exists.".format(task_name))
|
||||
else:
|
||||
result = create_task(task, token)
|
||||
print("Task creation result:", result)
|
||||
|
||||
# 创建所有任务之后, 创建视图分类
|
||||
# create_view_type(token)
|
||||
break # 正常执行完成后退出循环
|
||||
|
||||
except Exception as e:
|
||||
print("An error occurred: ", e)
|
||||
print("Retrying...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print('done!')
|
||||
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import httpx
|
||||
|
||||
|
||||
class GotifyNotifier:
|
||||
def __init__(self, title, message, token_name=''):
|
||||
self.gotify_url = 'https://gotify.erhe.top'
|
||||
self.app_token = self.match_token_name(token_name)
|
||||
self.title = title
|
||||
self.message = message
|
||||
|
||||
def match_token_name(self, name):
|
||||
token_name_dict = {
|
||||
'base': 'A8EVb0Cmxnb2vfk',
|
||||
'coin': 'AgfOJESqDKftBTQ',
|
||||
'dlt': 'A3bqt9Dlbs.fPUb',
|
||||
'AirdropTasksNews': 'Aoe0VKt-kkZnm8d',
|
||||
'weather': 'A9KF--mx_12PjSu',
|
||||
'news': 'AT2QGp_vyCX4akW',
|
||||
'CheckAndRemind': 'Aw7XKE2Ppk7Dgwk',
|
||||
'test': 'A0Xg6ZE5946iBYg',
|
||||
}
|
||||
|
||||
token = token_name_dict.get(name)
|
||||
if token:
|
||||
return token
|
||||
else:
|
||||
return token_name_dict['base']
|
||||
|
||||
def send_message(self):
|
||||
# 构建POST请求的headers
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
# 构建POST请求的body
|
||||
body = {
|
||||
'title': self.title,
|
||||
'message': self.message
|
||||
}
|
||||
|
||||
# 发送POST请求
|
||||
with httpx.Client() as client:
|
||||
response = client.post(
|
||||
url=f"{self.gotify_url}/message?token={self.app_token}",
|
||||
headers=headers,
|
||||
json=body
|
||||
)
|
||||
|
||||
# 或者可以使用 curl
|
||||
# curl -k "https://gotify.erhe.top/message?token=A0Xg6ZE5946iBYg" -F "title=测试发送信息" -F "message=假装有信息,测试发送" -F "priority=5"
|
||||
|
||||
# 检查响应状态码
|
||||
if response.status_code == 200:
|
||||
print('Gotify Message sent successfully!')
|
||||
else:
|
||||
print('Failed to send message:', response.text)
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
import httpx
|
||||
import asyncio
|
||||
import json
|
||||
import random
|
||||
import logging
|
||||
from typing import List
|
||||
from fake_useragent import UserAgent # 导入 fake_useragent 模块
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 初始化 fake_useragent
|
||||
ua = UserAgent()
|
||||
|
||||
|
||||
async def send_post_request(wallet: str, timeout: float = 10.0) -> None:
|
||||
"""
|
||||
向目标网站发送 POST 请求以领取水。
|
||||
|
||||
Args:
|
||||
wallet: 钱包地址
|
||||
timeout: 请求超时时间(秒)
|
||||
"""
|
||||
url = "https://faucet.nerzo.xyz/monad"
|
||||
|
||||
headers = {
|
||||
"accept": "text/x-component",
|
||||
"accept-encoding": "gzip, deflate, br, zstd",
|
||||
"accept-language": "zh-CN,zh;q=0.9",
|
||||
"content-type": "text/plain;charset=UTF-8",
|
||||
"next-action": "405d6e23437f844564e65cdd65851724c449d7f778",
|
||||
"next-router-state-tree": '["",{"children":["(faucet)",{"children":["monad",{"children":["__PAGE__",{},"/monad","refresh"]}]}]},null,null,true]',
|
||||
"origin": "https://faucet.nerzo.xyz",
|
||||
"priority": "u=1, i",
|
||||
"referer": "https://faucet.nerzo.xyz/monad",
|
||||
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": '"Windows"',
|
||||
"sec-fetch-dest": "empty",
|
||||
"sec-fetch-mode": "cors",
|
||||
"sec-fetch-site": "same-origin",
|
||||
"user-agent": ua.random,
|
||||
"x-deployment-id": "dpl_DWgqqeB8V4ASD1aCKUqWZwcPwnVd"
|
||||
}
|
||||
payload = json.dumps([wallet])
|
||||
|
||||
async with httpx.AsyncClient(timeout=timeout, proxy={'http://': 'http://127.0.0.1:7890'}) as client:
|
||||
retry = 3
|
||||
while retry > 0: # 修复了 retry 的逻辑错误
|
||||
try:
|
||||
response = await client.post(url, headers=headers, content=payload)
|
||||
# logger.info(f"Wallet: {wallet} | Status Code: {response.status_code} | Response: {response.text}")
|
||||
logger.info(f"Wallet: {wallet} | Status Code: {response.status_code}")
|
||||
if 'message' in response.text:
|
||||
message = re.findall(r'"message":"(.*?)"', response.text)[0]
|
||||
logger.info(f"Wallet: {wallet} | Message: {message}")
|
||||
return response
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f"Wallet: {wallet} | Request failed: {e}")
|
||||
retry -= 1
|
||||
|
||||
if retry <= 0:
|
||||
return None
|
||||
|
||||
|
||||
async def main(wallet_list: List[str], min_delay: float = 5.0, max_delay: float = 8.0) -> None:
|
||||
"""
|
||||
批量处理钱包地址,发送 POST 请求,并添加随机延时。
|
||||
|
||||
Args:
|
||||
wallet_list: 钱包地址列表
|
||||
min_delay: 最小延时(秒)
|
||||
max_delay: 最大延时(秒)
|
||||
"""
|
||||
for i, wallet in enumerate(wallet_list, 1):
|
||||
logger.info(f"Processing wallet {i}/{len(wallet_list)}: {wallet}")
|
||||
await send_post_request(wallet)
|
||||
# 在最后一个钱包之前添加随机延时
|
||||
if i < len(wallet_list):
|
||||
delay = random.uniform(min_delay, max_delay)
|
||||
logger.info(f"Waiting for {delay:.2f} seconds before next request")
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
wallet_list = [
|
||||
'0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6',
|
||||
'0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55',
|
||||
'0xE8A4b0C04300154DC9B1D0e565Ba70F996614690',
|
||||
'0x1b623c5d70c93b437d93c305bf2cfa389095f636',
|
||||
'0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB',
|
||||
'0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240',
|
||||
'0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5',
|
||||
'0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8',
|
||||
'0x83173eECf3a6d9ABB79682568e16c2eAd361620e',
|
||||
'0xa401b85B4849Fc7610Bd180cc937859C78528F47',
|
||||
'0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266',
|
||||
'0x70D5EE1DfddD3726f0D71F4CD5a8Ef43aC651a75'
|
||||
]
|
||||
random.shuffle(wallet_list)
|
||||
asyncio.run(main(wallet_list))
|
||||
print("done")
|
||||
Reference in New Issue
Block a user