commit
756cb1e7d8
@ -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) |
||||
@ -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") |
||||
Loading…
Reference in new issue