first commit

main
jack 4 weeks ago
commit 756cb1e7d8
  1. 65
      .gitignore
  2. 80
      clash/clash_check_now_node.py
  3. 39
      clash/clash_set_global.py
  4. 180
      message/message_dlt.py
  5. 171
      message/no_message_dlt.py
  6. 247
      requirements.txt
  7. 33
      siliconflow-api/main.py
  8. 98
      utils/utils_create_rss_record.py
  9. 25
      utils/utils_get_current_ip.py
  10. 15
      utils/utils_get_public_ip.py
  11. 236
      utils/utils_ql_create_tasks.py
  12. 58
      utils/utils_send_gotify.py
  13. 109
      web3/faucet.py

65
.gitignore vendored

@ -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…
Cancel
Save