This commit is contained in:
2026-06-29 15:51:51 +08:00
commit 3a4ca7ccf5
612 changed files with 785341 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
.idea/
*.iml
*.iws
*.ipr
*.mp3
*.mp4
File diff suppressed because one or more lines are too long
@@ -0,0 +1,32 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/8/4 下午8:02
# @Author : cmk
# @File : movie——bilibili.py
# @Email : 15726649712@163.com
import requests
#视频合并
from moviepy.editor import *
vidor_url= 'https://upos-sz-mirrorcos.bilivideo.com/upgcxcode/50/03/1628270350/1628270350-1-30032.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1722780365&gen=playurlv2&os=cosbv&oi=2029323983&trid=7cefdb0e26b3415f91afce6fdaa1bda3u&mid=0&platform=pc&og=cos&upsig=a1b7708bfc4500ba3655eef7f6526fc6&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform,og&bvc=vod&nettype=0&orderid=0,3&buvid=18B09F3B-6AB6-4569-ABBA-98D50EE4645F34003infoc&build=0&f=u_0_0&agrr=0&bw=12942&logo=80000000'
audio_url = 'https://upos-sz-mirrorcos.bilivideo.com/upgcxcode/50/03/1628270350/1628270350-1-30280.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1722780365&gen=playurlv2&os=cosbv&oi=2029323983&trid=7cefdb0e26b3415f91afce6fdaa1bda3u&mid=0&platform=pc&og=cos&upsig=8109b2753456551bb0bb919f9a64c898&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform,og&bvc=vod&nettype=0&orderid=0,3&buvid=18B09F3B-6AB6-4569-ABBA-98D50EE4645F34003infoc&build=0&f=u_0_0&agrr=0&bw=9052&logo=80000000'
headers = {
'referer':'https://search.bilibili.com/all?vt=73072246&keyword=docker%E6%95%99%E7%A8%8B&from_source=webtop_search&spm_id_from=333.1073&search_source=2',
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
}
# vidor_data = requests.get(vidor_url, headers=headers).content
# audio_data = requests.get(audio_url, headers=headers).content
#
# with open('bilibili.mp4','wb') as f:
# f.write(vidor_data)
# with open('bilibili.mp3','wb') as f:
# f.write(audio_data)
ffmpeg_tools.ffmpeg_merge_video_audio('bilibili.mp4','bilibili.mp3','all.mp4')
@@ -0,0 +1,36 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/8/4 下午9:21
# @Author : cmk
# @File : vip_muisc.py
# @Email : 15726649712@163.com
import os
import requests
from moviepy.editor import AudioFileClip
from lxml import etree
headers = {
'referer':'https://music.163.com',
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
}
url = 'https://music.163.com/artist/mv?id=222871'
response = requests.get(url, headers=headers)
#print(response.text)
html = etree.HTML(response.text)
name_list = html.xpath('//*[@id="m-mv-module"]/li[*]/p/a/text()')
url_list = html.xpath('//*[@id="m-mv-module"]/li[*]/p/a/@href')
data = {name:url for name,url in zip(name_list,url_list)}
print(data)
for name in data:
url = f'https://music.163.com/#/{data[name]}'
response = requests.get(url, headers=headers)
with open(f'{name}.mp4', 'wb') as f:
f.write(response.content)
name = AudioFileClip(f"{name}.mp4")
name.write_audiofile(f'{name}.mp3')
os.remove(f'{name}.mp4')
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/8/5 下午9:48
# @Author : cmk
# @File : bilibili-laomo.py
# @Email : 15726649712@163.com
import re
import requests
from lxml import etree
import json
import jsonpath
from moviepy.editor import VideoFileClip
'''
video_url
audio_url
'''
url = 'https://www.bilibili.com/video/BV1gb4y1P7mV/?spm_id_from=333.788&vd_source=74f0d233d72bf26491f5540af160ff76'
headers = {
'Referer':'https://space.bilibili.com/3493290691266862/?spm_id_from=333.999.0.0',
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
}
response = requests.get(url, headers=headers)
html = etree.HTML(response.text)
html.xpath('')
@@ -0,0 +1,38 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/28 下午3:15
# @Author : cmk
# @File : 001-reuquest使用.py
# @Email : 15726649712@163.com
import random
import requests
user_agents = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60',
'Opera/8.0 (Windows NT 5.1; U; en)',
'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 ',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0) ',
]
print(random.choices(user_agents))
# url = 'https://www.baidu.com'
# #url = 'http://www.jinrizulan.top/login'
# header = {
# 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
# }
# respones = requests.get(url, headers=header)
# print(respones.text)
@@ -0,0 +1,38 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/28 下午5:47
# @Author : cmk
# @File : 002问问.py
# @Email : 15726649712@163.com
import requests
import random
# url = 'https://www.sogou.com/sogou'
# user_agents = [
# 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60',
# 'Opera/8.0 (Windows NT 5.1; U; en)',
# 'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
# 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50'
# ]
# UA = random.choice(user_agents)
# headers = {
# 'user_agents': UA
# }
# input_out = input('输入你要问的内容')
# #https://www.sogou.com/sogou?query=%E5%8C%97%E4%BA%AC&page=3
# for i in range(1,10):
# query = {
# 'query': input_out,
# 'page': i,
# }
# response = requests.get(url, headers=headers, params=query)
# if response.status_code == 200:
# with open(f'./shougou/{input_out}_{i}.html', 'w') as f:
# f.write(response.content.decode(response.encoding))
class Wenwen:
def __init__(self,url,headers):
self.url = url
self.headers = headers
@@ -0,0 +1,23 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/28 下午10:17
# @Author : cmk
# @File : 003post_requrest.py
# @Email : 15726649712@163.com
import requests
url = 'http://www.abcbiquge.com/login.htm'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
'Referer':'http://www.abcbiquge.com/login.htm'
}
from_data = {
'name': 'acctv111',
'password': '0E7517141FB53F21EE439B355B5A1D0A',
'autoLogin': 1,
'autologin': 1
}
response = requests.post(url, headers=headers, data=from_data)
print(response.text)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,50 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/29 下午9:54
# @Author : cmk
# @File : ip代理.py
# @Email : 15726649712@163.com
import requests
from retrying import retry
class aa():
def __init__(self):
self.url = 'https://myip.ipip.net'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
}
self.num_ = 0
self.ip = {'https':'http://115.239.0.204:40018'}
@retry(stop_max_attempt_number=10)
def get_ip(self):
self.num_ += 1
print(self.num_)
response = requests.get(url=self.url, headers=self.headers,proxies=self.ip,timeout=3)
return response.text
def run(self):
try:
self.get_ip()
return self.get_ip()
except Exception as e:
print(e)
if __name__ == '__main__':
aa = aa()
while True:
bb = aa.run()
if 'IP' not in bb:
break
else:
print(bb)
# proxies = {"https":"http://119.41.206.35:40015"}
# response = requests.get(url, headers=headers,proxies=proxies,timeout=5)
# print(response.text)
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,112 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="//www.sogou.com/images/logo/new/favicon.ico?v=4" type="image/x-icon">
<title>搜狗搜索</title>
<script>
(function () {
if (!window.Promise) {
document.writeln('<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"><' + '/' + 'script>');
}
})();
</script>
<link rel="stylesheet" href="static/css/anti.min.css?v=1"/>
<link rel="stylesheet" type="text/css" href="newstatic/css/verify.css">
<script src="//dlweb.sogoucdn.com/common/lib/jquery/jquery-1.11.0.min.js"></script>
<script src="static/js/antispider.min.js?v=3"></script>
<script>
var domain = getDomain();
window.imgCode = -1;
(function() {
function checkSNUID() {
var cookieArr = document.cookie.split('; '),
count = 0;
for(var i = 0, len = cookieArr.length; i < len; i++) {
if (cookieArr[i].indexOf('SNUID=') > -1) {
count++;
}
}
return count > 1;
}
if(checkSNUID()) {
var date = new Date(), expires;
date.setTime(date.getTime() -100000);
expires = date.toGMTString();
document.cookie = 'SNUID=1;path=/;expires=' + expires;
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogo.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.www.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.weixin.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.sogou.com';
document.cookie = 'SNUID=1;path=/;expires=' + expires + ';domain=.snapshot.sogoucdn.com';
sendLog('delSNUID');
}
if(getCookie('seccodeRight') === 'success') {
sendLog('verifyLoop');
setCookie('seccodeRight', 1, getUTCString(-1), location.hostname, '/');
}
@@ -0,0 +1,30 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2026/5/8 10:37
# @Author : cmk
# @File : WY-music.py
# @Email : 15726649712@163.com
'''
简单暴力获取网易云音乐照片或者mv
简单测试,无法大批量下载,vip歌曲无法下载
'''
import requests
from fake_useragent import UserAgent
class music():
def __init__(self):
self.headers = {
'User-Agent': UserAgent().random,
}
def get_data(self,name,url):
res = requests.get(url, headers=self.headers)
with open(name, 'wb') as f:
f.write(res.content)
if __name__ == '__main__':
music_ = music()
name = input("输入音乐 or mv or 照片的名称以及格式.mp3,jpg,mp4:")
url = input('输入F12抓包的url:')
music_.get_data(name,url)
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/8/3 下午4:14
# @Author : cmk
# @File : test_xapth.py
# @Email : 15726649712@163.com
import requests
from lxml import etree
url ='https://movie.douban.com/top250'
headers = {
'User_Agents': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
'Referer':'https://movie.douban.com/subject/1292052/'
}
response = requests.get(url, headers=headers)
print(response.status_code)
print(response.content.decode(response.encoding))
# str类型无法直接被xpath语法处理,需要转换成html对象
# HTML_data = etree.HTML(response.text)
#
# HTML_data.xpath('//*[@id="root"]/div[2]/div[1]/div[1]/div[1]/a/text()')
@@ -0,0 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/18
# File : 1.py
# 脚本作用 :
# 项目名称 :
# ------------------------------------
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/18 上午9:47
# File : js加密.py
# 脚本作用 :
# 项目名称 :
# ------------------------------------
import hashlib
# import base64
#
# data = '程明坤'
#
# base64_data = base64.b64encode(data.encode()).decode('GBK')
# '56iL5piO5Z2k'
# print(base64_data)
# base64_d1 = base64.b64decode(base64_data).decode()
# print(base64_d1)
#md5不可逆
# import hashlib
# data = '程明坤'
# #hexdigest()获取加密后的密文
# hash = hashlib.md5(data.encode()).hexdigest()
# print(hash)
import hmac
@@ -0,0 +1,40 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/31 下午8:54
# @Author : cmk
# @File : 豆瓣.py
# @Email : 15726649712@163.com
import requests
import pymongo
import time
import jsonpath
'''
要求:取产地和排名
'''
mongo_client = pymongo.MongoClient('mongodb://localhost:27017/')
mongo_db = mongo_client['movie']
mongo_collection = mongo_db['movie']
nums = input('请输入你要获取的页数:')
for num in range(int(nums)):
url = f'https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&start={num * 20}&limit=20'
heraders = {
'Host': 'movie.douban.com',
'Origin': 'http://movie.douban.com',
'Referer': 'http://movie.douban.com/j/chart/top_list',
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
}
response = requests.get(url, headers=heraders)
json_data = response.json()
mongo_collection.insert_many(json_data)
time.sleep(3)
for i in mongo_collection.find():
print(i)
# for i in range(len(json_data)):
# mongo_collection.insert_many(json_data[i])
@@ -0,0 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/8/4 下午7:01
# @Author : cmk
# @File : db_mongodb.py
# @Email : 15726649712@163.com
import pymongo
cline = pymongo.MongoClient('localhost', 27017)
# 安全验证
#cline.authenticate('admin', 'admin')
db = cline['cmk']
c1 = db['cmk']
#需要用循环提取
# a = c1.find()
# for i in a:
# print(i)
# 只能查看一条数据,不用转换
c1.find_one()
# 添加一条数据
#c1.insert_one({'_id': 11, 'age': 18.0, 'name': 'cctv11'})
#修改数据
#c1.update_one({'name': 'cctv11'},{'$set':{'name': 'cmk'}})
c1.delete_one({'name': 'cmk'})
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2025/1/2
# File : 4k.py
# 脚本作用 : 批量下载https://pic.netbian.com图片
# 项目名称 :
# ------------------------------------
import requests
def my_headers(url):
headers = {
'Referer': 'https://pic.netbian.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'sec-ch-ua-arch': '"x86"',
'sec-ch-ua-bitness': '"64"',
'sec-ch-ua-full-version': '"131.0.6778.205"',
'sec-ch-ua-full-version-list': '"Google Chrome";v="131.0.6778.205", "Chromium";v="131.0.6778.205", "Not_A Brand";v="24.0.0.0"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-model': '""',
'sec-ch-ua-platform': '"Windows"',
'sec-ch-ua-platform-version': '"15.0.0"',
}
response = requests.get(url, headers=headers)
return response
if __name__ == '__main__':
url = 'https://pic.netbian.com'
a = input('输入你要获取的内容"4kfengjing":')
print(my_headers(url).text)
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2025/1/1
# File : 百度.py
# 脚本作用 :
# 项目名称 :
# ------------------------------------
import requests
import re
import json
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-Language': 'zh,zh-CN;q=0.9',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
# 'Cookie': 'BIDUPSID=D972F42DA92BDE42EE76DC23E23EF94D; PSTM=1732951044; BAIDUID=D972F42DA92BDE425BD1E54B14510FFE:FG=1; BD_UPN=12314753; BAIDUID_BFESS=D972F42DA92BDE425BD1E54B14510FFE:FG=1; MAWEBCUID=web_uMpwvXBHFXRmTYmsjlzyiMoLsZiFOKOBmGcXUlfDyoEwqNWQpq; __bid_n=193f9404ffd3728f638fc8; ZFY=8ygVtyGYPKpdeQvvwWRkEK0Sj:BrcvpoB3fhY1QjSVz8:C; RT="z=1&dm=baidu.com&si=9d655702-d58a-47db-b1da-aefcaab93deb&ss=m58rm2qx&sl=2&tt=2i4&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=hnmw"; newlogin=1; B64_BOT=1; H_WISE_SIDS=61027_61390_61445_60853_61491_61430_61494_61530_61521_61613; H_WISE_SIDS_BFESS=61027_61390_61445_60853_61491_61430_61494_61530_61521_61613; BDRCVFR[77Ms7oRaB-6]=mk3SLVN4HKm; H_PS_PSSID=61027_61390_61445_60853_61491_61494_61530_61521_61613; delPer=0; BD_CK_SAM=1; PSINO=1; BA_HECTOR=a080a0a00g8l8h2g042524ak0e77un1jn9dl01v; baikeVisitId=1d8b54e9-6dba-4cec-8ae1-1ad59b8c2303; COOKIE_SESSION=45_0_7_4_5_7_0_0_7_3_0_3_47_0_8_0_1735702499_0_1735702491%7C9%230_0_1735702491%7C1; BD_HOME=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGlcv8RcA1xQKfriWJVc7a+LGEimjy3MrXEpSuItnI4KDw0lcp9gYlNeIi8lCW52aQjdXPm3tCosQ5WOQK5BipRU/MX8cKJjK8bCUsEqWG541oOswVAInEL977Gkc4LGHFurc6cZOQiWpdWZFfM9cCLuTBuECl+tiP++NCHKpXEMdWH1SPBXDyoMbf9Ga3EX3JChPqbqXCynz2/zX5KTmKXkQbeCqJ91LNPfk1CUv8oZVqpjmQL+qAV8IsF/o1nhFAyZ9KUZywDhnDu1Pi1I0y9kFgpvN5wsxOF4OWHNx5obqb9HgVrRCzW8F/grF+qG2/fHZFO3SaB4GS7zlBrG2cLm8lTRl19JYcYcqvy3P/50mxpWDwUUC4pvKOF9e+pwNq7l6HzKEZyCMUDd+W6AiaksYiu+4AAz72OnMQfgAyNUbW3IyzL5c+UBht87WUigOY9alcIuR+n1gwn+Dmf3unATYGtv0zKmAog3Ny9wFYiQ/gdKSrR9D25HSwrLQyIe5QKTkKSlY6nVev8MhaT3AUPwNqYIvWCQZXWkhuuU0ZXLMYAKJSeHY7mTrwwSSKC3ZaJ1ws01+N7+ZYRSV0hfkzrW2tjIBQevKFs86lIavrkFVLBPKHcPBGk0StntFSLi18x91rSPWb2eeCt263/A+EJVR/A8+3BQ92SIDoXabq8Wb8ZGN9BAsC9g5OdjE6lhwzTadptHqT7mZN901gDzA4lMYEG/kekC+0J5/N5yVy+ei7UKhQHejRjxCO2+98Bn9oZFiDSnLA6b6enRLnlcjd/V5Lrc1iQJ5vVqzr55rpErNdd7jPkj5hbBFquQKM4S+tDJ34jmplOTrqqKT7PPVfrdgd4OkK13pEy86BsJ8M0gKXgtivUgM8Bjl1m/pkg0SuDyntWLdrmMxcZYvgySvSSwQ2Qtm8EkKHIMyR/XgfHnpX5vadGpRMro2qaE8u+x8w1gJHIRKib2u6Q1JtQiZE1Rde/vRx8xKfg6uYR37n0BvfgJE5+KbeuwCyAvJRGUA2fpt0VClIfV0m2PRG7bvH00OODKY6cFi7NgWAK6Jc1G4bJvJ++n215hSNvqitQjGGwIBF37aBhyiPWPAOeYXBqA; BDUSS=FdZSVd6allRNmpyVXVzWnZjSXYxNWhTQm5oLTdkc1V0TnJ4bndYTWhhcnZTWnhuRVFBQUFBJCQAAAAAAAAAAAEAAAAG38eed2luZHnM9NW9yMvJ-gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO-8dGfvvHRnc; BDUSS_BFESS=FdZSVd6allRNmpyVXVzWnZjSXYxNWhTQm5oLTdkc1V0TnJ4bndYTWhhcnZTWnhuRVFBQUFBJCQAAAAAAAAAAAEAAAAG38eed2luZHnM9NW9yMvJ-gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO-8dGfvvHRnc',
'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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
response = requests.get('https://www.baidu.com/',headers=headers)
html = response.text
print(html)
data = re.findall(r'<script type="application/json" id="placeholder-data" data-for="result-data">(.*?)</script>', html)
print(data)
@@ -0,0 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/8/14 上午9:56
# @Author : cmk
# @File : 自动化测试.py
# @Email : 15726649712@163.com
from selenium import webdriver
wd = webdriver.Chrome()
wd.get('http://tieba.baidu.com')
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2025/4/6
# File : 002-Blibli.py
# 脚本作用 :
# 项目名称 :
# ------------------------------------
'''
#闭包
def outer(n):
m = 10
def a(e):
nonlocal m # 告诉解释器,此处使用的是外部变量M
m = 100 # 修改m值,如果没有nonlocal 无法修改
data = f'我是a:{n * m *e}'
return data
def b(e):
m = 100
data = f'我是b:{n * m *e}'
return data
def c(e):
data = f'我是c:{n * m *e}'
return data
if n < 5:
return a
elif 5<= n < 10:
return b
elif 10<= n < 20:
return c
print(outer(4)(6))
'''
'''
装饰器
'''
##没有参数
# def outer(fn):
# def a():
# print('你好11111')
# fn()
# return a
#
#
# def c():
# print('aaaa')
#
#
# outer(c)()
#
# #语法糖
# @outer
# def b():
# print('哈哈哈')
# b()
#有参数
def outer(fn1):
def inner(*args, **kwargs):
print('我是outer')
fn1(*args, **kwargs)
return inner
def outer2(fn1):
def inner(*args, **kwargs):
print(f'我是outer2')
fn1(*args, **kwargs)
return inner
@outer2
@outer
def c1(a,b):
print(a+b)
c1(1,2,3)
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2025/4/1
# File : 01课堂作业.py
# 脚本作用 :
# 项目名称 :
# ------------------------------------
'''
课堂作业:https://www.sogou.com/sogou?query=%E7%BE%8E%E9%A3%9F&ie=utf8&insite=wenwen.sogou.com 保存页面内容
'''
import requests
from fake_useragent import FakeUserAgent
url_ = 'https://www.sogou.com/'
headers = {
'User-Agent': FakeUserAgent().random,
}
data = {
'query': '美食',
'ie': 'utf8',
'insite': 'wenwen.sogou.com',
}
res = requests.get(url_, headers=headers,data=data)
print(res.text)
+109
View File
@@ -0,0 +1,109 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/25 下午1:42
# @Author : cmk
# @File : DingDing_tools.py
# @Email : 15726649712@163.com
import time
import hmac
import hashlib
import base64
import requests
import json
import urllib.parse
class DingDingTools:
def __init__(self, webhook, secret=None):
self.webhook = webhook
self.secret = secret
def timestamp_sign(self):
timestamp = str(round(time.time() * 1000))
if self.secret:
secret_enc = self.secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, self.secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, hashlib.sha256).digest()
sign = base64.b64encode(hmac_code)
sign = urllib.parse.quote_plus(sign)
return timestamp, sign
else:
return timestamp, None
#消息类型https://open.dingtalk.com/document/orgapp/custom-bot-send-message-type#66407430cd5xr
def text(self,memages):
timestamp,sign = self.timestamp_sign()
if 'https://oapi.dingtalk.com/robot/send?access_token=' in self.webhook:
url = self.webhook + '&timestamp=' + timestamp + '&sign=' + sign
else:
url = 'https://oapi.dingtalk.com/robot/send?access_token=' + self.webhook + '&timestamp=' + timestamp + '&sign=' + sign
headers = {
'Content-Type': 'application/json;charset=utf-8'
}
data = {
#消息类型
"msgtype": "text",
"text":{
#消息内容
"content": memages
},
#被圈的人,非必填项
"at": {
#被@人的手机号
"atMobile": ['15726649712'],
#被@人的用户userId
"atUserIds":['程明坤'],
#是否@所有人。
"isAtAll": True
}
}
respones = requests.post(url,headers=headers,data=json.dumps(data))
return respones.text
def link(self,title,text,messageUrl,picUrl=None):
data = {
"msgtype": "link",
"link": {
"title": title,
"text": text,
"messageUrl": messageUrl,
"picUrl": picUrl
}
}
timestamp,sign = self.timestamp_sign()
if 'https://oapi.dingtalk.com/robot/send?access_token=' in self.webhook:
url = self.webhook + '&timestamp=' + timestamp + '&sign=' + sign
else:
url = 'https://oapi.dingtalk.com/robot/send?access_token=' + self.webhook + '&timestamp=' + timestamp + '&sign=' + sign
headers = {
'Content-Type': 'application/json;charset=utf-8'
}
respones = requests.post(url,headers=headers,data=json.dumps(data))
return respones.text
def Marddown(self,title,mesage):
data = {
"msgtype": "markdown",
"markdown": {
"title": title,
"text": mesage
},
"at": {
"atMobiles": [],
"isAtAll": False
}
}
timestamp, sign = self.timestamp_sign()
if 'https://oapi.dingtalk.com/robot/send?access_token=' in self.webhook:
url = self.webhook + '&timestamp=' + timestamp + '&sign=' + sign
else:
url = 'https://oapi.dingtalk.com/robot/send?access_token=' + self.webhook + '&timestamp=' + timestamp + '&sign=' + sign
headers = {
'Content-Type': 'application/json;charset=utf-8'
}
respones = requests.post(url, headers=headers, data=json.dumps(data))
return respones.text
# if __name__ == '__main__':
# webhook = '3922b5bec47e2e34c9cd965e9088902826b4a0abd71212ae2feb17df09aabb38'
# secret = 'SEC58bfd29aab7dab71eae40558e1b41306e58e63b9974f5eff7bd4b518f47c6189'
# Ding_reboot = DingDingTools(webhook,secret)
+333
View File
@@ -0,0 +1,333 @@
ChatbotMessage(message_type=text, text=TextContent(content=验证码), sender_nick=程明坤, conversation_title=None)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=程明坤, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 哇哦这尼玛), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= ), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= ), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=南涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证吗), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=程明坤, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
ChatbotMessage(message_type=text, text=TextContent(content= 验证码), sender_nick=岳振涛, conversation_title=萝卜头)
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@@ -0,0 +1,98 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/5/9 9:33
# @Author : cmk
# @File : Class_Dingding.py
# @Email : 15726649712@163.com
import time
import hmac
import hashlib
import base64
import requests
import json
import urllib.parse
class DingTalkRobot:
def __init__(self, webhook, secret=None):
self.webhook = webhook
self.secret = secret
def _generate_timestamp_and_sign(self):
timestamp = str(round(time.time() * 1000))
if self.secret:
secret_enc = self.secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, self.secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, hashlib.sha256).digest()
sign = base64.b64encode(hmac_code)
sign = urllib.parse.quote_plus(sign)
return timestamp, sign
else:
return timestamp, None
def _send_request(self, data):
headers = {'Content-Type': 'application/json;charset=utf-8'}
response = requests.post(self.webhook, headers=headers, data=json.dumps(data))
return response.json()
def send_text(self, content, at_mobiles=None, is_at_all=False):
timestamp, sign = self._generate_timestamp_and_sign()
data = {
"msgtype": "text",
"text": {
"content": content
},
"at": {
"atMobiles": at_mobiles if at_mobiles else [],
"isAtAll": is_at_all
}
}
if sign:
data['timestamp'] = timestamp
data['sign'] = sign
return self._send_request(data)
def send_markdown(self, title, text, at_mobiles=None, is_at_all=False):
timestamp, sign = self._generate_timestamp_and_sign()
data = {
"msgtype": "markdown",
"markdown": {
"title": title,
"text": text
},
"at": {
"atMobiles": at_mobiles if at_mobiles else [],
"isAtAll": is_at_all
}
}
if sign:
data['timestamp'] = timestamp
data['sign'] = sign
return self._send_request(data)
# Add more message types as needed...
'''
使用案例
# 创建机器人实例
webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=your_access_token"
secret = "your_secret" # 如果没有加签验证,可以设为None
robot = DingTalkRobot(webhook_url, secret)
# 发送文本消息
response = robot.send_text("Hello, this is a 00test message!")
print(response)
# 发送带@的文本消息
response = robot.send_text("Hello, this is a 00test message with @!", at_mobiles=["18888888888"], is_at_all=False)
print(response)
# 发送Markdown消息
markdown_title = "Test Markdown Message"
markdown_text = "# This is a 00test Markdown message\n- Item 1\n- Item 2\n[Link](https://www.example.com)"
response = robot.send_markdown(markdown_title, markdown_text)
print(response)
'''
@@ -0,0 +1,139 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023/7/16 22:32
# @Author : cmk
# @File : reboot_dingding.py
# @Email : 15726649712@163.com
import requests
import json
import time
import hmac
import hashlib
import base64
import socket
from multiprocessing import Process
import os
#from conversation.info import *
def handle_client(client_socket):
# 获取socket
request_data = client_socket.recv(20000)
post_userid, post_sign, post_timestamp, post_mes = getPost(request_data)
# 回应socket
initKey(post_userid, post_sign, post_timestamp, post_mes)
# 关闭socket
client_socket.close()
def getPost(request_data):
request_data = str(request_data, encoding="utf8").split('\r\n')
items = []
for item in request_data[1:-2]:
items.append(item.split(':'))
post_useful = {}
for i in items:
post_useful.update({i[0]: i[1]})
if post_useful.get('sign') == None:
print('other connect')
return 0
else:
post_sign = post_useful.get('sign').strip()
post_timestamp = post_useful.get('timestamp').strip()
post_mes = json.loads(request_data[-1])
post_userid = post_mes.get('senderId').strip()
post_mes = post_mes.get('text').get('content').strip()
return post_userid, post_sign, post_timestamp, post_mes
def initKey(post_userid, post_sign, post_timestamp, post_mes):
# 配置token
# 得到当前时间戳
timestamp = str(round(time.time() * 1000))
# 计算签名
#app_secret = '_XhYNZ45qor2DsnNRqXyCGINypH669XzN2jK0hvtfem-1rfziLuafeq82xbmmj53'
app_secret = 'X1s04VcwlxhO7JLEUkCFYbxAW9aTvuWUQrUeyDTqkLbr9GQ_tJ6jG0732S87ayvY'
app_secret_enc = app_secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(post_timestamp, app_secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code).decode('utf-8')
# 验证是否来自钉钉的合法请求
if (abs(int(post_timestamp) - int(timestamp)) < 3600000 and post_sign == sign):
#webhook="https://oapi.dingtalk.com/robot/send?access_token=88327cd1bfcb3fb9d3186fcf1bf8b15a82ac3475c271a8c74600b6431e9e6929"
#webhook='https://oapi.dingtalk.com/robot/send?access_token=caaca475c58e8789d85826130271c9e9da7d3837cc65504ef2534fee0b134506'
#webhook='https://oapi.dingtalk.com/robot/send?access_token=00f64174519e59edc9a274f5f3792c3b24c16486bad2031ce80a54baf30840ed'
webhook='https://oapi.dingtalk.com/robot/send?access_token=78c04c1b2254083a9c90f12a191170499ee274f92aa551a00abd9349db85cc05'
header = {
"Content-Type": "application/json",
"Charset": "UTF-8"
}
# 发送消息
message_json = json.dumps(selectMes(post_userid, post_mes))
# 返回发送状态
info = requests.post(url=webhook, data=message_json, headers=header)
print(info.text)
else:
print("Warning:Not DingDing's post")
def selectMes(post_userid, post_mes):
print(post_userid)
# 判断指令选择对应回复
if (post_mes == '值班'):
mes = os.popen('python zhiban_dingding_robot_api.py').read()
send_mes = '@{} \n\n {}'.format(post_userid,mes)
return sendMarkdown(post_userid, send_mes)
else:
#cmd = 'python tongyiqianwen.py {}'.forman(post_mes)
mes = os.popen('python tongyiqianwen.py {}'.format(post_mes)).read()
send_mes = '@{} \n\n {}'.format(post_userid,mes)
return sendText(post_userid, send_mes)
def sendText(post_userid, send_mes):
# 发送文本形式
message = {
"msgtype": "text",
"text": {
"content": send_mes
},
"at": {
"atDingtalkIds": [post_userid],
"isAtAll": False
}
}
return message
def sendMarkdown(post_userid, send_mes):
# 发送Markdown形式
message = {
"msgtype": "markdown",
"markdown": {
"title": "智能运维信息",
"text": send_mes
},
"at": {
"atDingtalkIds": [post_userid],
"isAtAll": False
}
}
return message
if __name__ == "__main__":
# 启动服务,端口9000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 8090))
server_socket.listen(120)
while True:
print("已启动")
client_socket, client_address = server_socket.accept()
print(f"{client_address},用户连接上了")
handle_client_process = Process(target=handle_client, args=(client_socket,))
handle_client_process.start()
client_socket.close()
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/5/11 9:54
# @Author : cmk
# @File : 00test.py
# @Email : 15726649712@163.com
import Class_Dingding
# 创建机器人实例
webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=3922b5bec47e2e34c9cd965e9088902826b4a0abd71212ae2feb17df09aabb38"
secret = "SEC58bfd29aab7dab71eae40558e1b41306e58e63b9974f5eff7bd4b518f47c6189" # 如果没有加签验证,可以设为None
robot = Class_Dingding.DingTalkRobot(webhook_url, secret)
# 发送文本消息
# response = robot.send_text("Hello, this is a 00test message!")
# print(response)
#
# # 发送带@的文本消息
# response = robot.send_text("Hello, this is a 00test message with @!", at_mobiles=["18888888888"], is_at_all=False)
# print(response)
# 发送Markdown消息
markdown_title = "Test Markdown Message"
markdown_text = "# This is a 00test Markdown message\n- Item 1\n- Item 2\n[Link](https://github.com/chengmingkun/images/blob/master/infinity-1349967.jpg)"
response = robot.send_markdown(markdown_title, markdown_text)
print(response)
@@ -0,0 +1,132 @@
import requests
import json
import time
import hmac
import hashlib
import base64
import socket
from multiprocessing import Process
# from conversation.info import *
def handle_client(client_socket):
# 获取socket
request_data = client_socket.recv(20000)
post_userid, post_sign, post_timestamp, post_mes = getPost(request_data)
# 回应socket
initKey(post_userid, post_sign, post_timestamp, post_mes)
# 关闭socket
client_socket.close()
def getPost(request_data):
request_data = str(request_data, encoding="utf8").split('\r\n')
items = []
for item in request_data[1:-2]:
items.append(item.split(':'))
post_useful = {}
for i in items:
post_useful.update({i[0]: i[1]})
if post_useful.get('sign') == None:
print('other connect')
return 0
else:
post_sign = post_useful.get('sign').strip()
post_timestamp = post_useful.get('timestamp').strip()
post_mes = json.loads(request_data[-1])
post_userid = post_mes.get('senderId').strip()
post_mes = post_mes.get('text').get('content').strip()
return post_userid, post_sign, post_timestamp, post_mes
def initKey(post_userid, post_sign, post_timestamp, post_mes):
# 配置token
# 得到当前时间戳
timestamp = str(round(time.time() * 1000))
# 计算签名
app_secret = ''
app_secret_enc = app_secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(post_timestamp, app_secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code).decode('utf-8')
# 验证是否来自钉钉的合法请求
if (abs(int(post_timestamp) - int(timestamp)) < 3600000 and post_sign == sign):
webhook="https://oapi.dingtalk.com/robot/send?access_token="
header = {
"Content-Type": "application/json",
"Charset": "UTF-8"
}
# 发送消息
message_json = json.dumps(selectMes(post_userid, post_mes))
# 返回发送状态
info = requests.post(url=webhook, data=message_json, headers=header)
print(info.text)
else:
print("Warning:Not DingDing's post")
def selectMes(post_userid, post_mes):
print(post_userid)
# 判断指令选择对应回复
if (post_mes == '你好'):
send_mes = '@{} \n\n 哈喽,你好啊!'.format(post_userid)
return sendText(post_userid, send_mes)
if (post_mes == '你的名字'):
send_mes = '@{} \n\n 您好,我是智能运维助手~,目前正在学习中~'.format(post_userid)
return sendMarkdown(post_userid, send_mes)
try:
if eval(post_mes):
send_mes = "@{} \n\n > {}中文名称为: {}".format(post_userid, post_mes, eval(post_mes))
return sendMarkdown(post_userid, send_mes)
except:
return sendMarkdown(post_userid, '@{} \n\n 感谢您的反馈,正在学习新知识中~'.format(post_userid))
else:
return sendMarkdown(post_userid, '@{} \n\n 感谢您的反馈,正在学习新知识中~'.format(post_userid))
def sendText(post_userid, send_mes):
# 发送文本形式
message = {
"msgtype": "text",
"text": {
"content": send_mes
},
"at": {
"atDingtalkIds": [post_userid],
"isAtAll": False
}
}
return message
def sendMarkdown(post_userid, send_mes):
# 发送Markdown形式
message = {
"msgtype": "markdown",
"markdown": {
"title": "智能运维信息",
"text": send_mes
},
"at": {
"atDingtalkIds": [post_userid],
"isAtAll": False
}
}
return message
if __name__ == "__main__":
# 启动服务,端口9000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 9000))
server_socket.listen(120)
while True:
print("已启动")
client_socket, client_address = server_socket.accept()
print(f"{client_address},用户连接上了")
handle_client_process = Process(target=handle_client, args=(client_socket,))
handle_client_process.start()
client_socket.close()
+230
View File
@@ -0,0 +1,230 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/23 上午11:08
# File : dingding_rebot.py
# 脚本作用 : 使用钉钉机器人发送消息
# ------------------------------------
'''
测试使用机器人
https://oapi.dingtalk.com/robot/send?access_token=d7e8be9866a981d899e38aa27005e264f47d1f913816caa1001f9d5229f7d074
SEC6872ee8ddf8e72bf97f4b5f641f1cdbaf28185013d52e45b6b2a2b8c8675b959
'''
import time
import hmac
import hashlib
import base64
import requests
import json
def signs(secret):
timestamp = str(round(time.time() * 1000))
string_to_sign = '{}\n{}'.format(timestamp, secret)
hmac_code = hmac.new(secret.encode('utf-8'), string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code).decode('utf-8')
return timestamp,sign
def req(tokin,secret,data):
timestamp,sign = signs(secret)
url = f'https://oapi.dingtalk.com/robot/send?access_token={tokin}&timestamp={timestamp}&sign={sign}'
response = requests.post(url=url,data=json.dumps(data),headers={'Content-Type': 'application/json'})
if response.status_code == 200:
mes = "消息发送成功"
else:
mes = f"消息发送失败,状态码:{response.status_code}"
print(mes)
class mes_type():
def text(self,mes):
'''
文本类型
"text": {
"content":"我就是我, @014728255240768602 是不一样的烟火"
},
"msgtype":"text"
}
'''
data = {
"msgtype": "text",
"text": {
"content": mes
}
}
return data
def link(self,mes):
'''
{
"msgtype": "link",
"link": {
"text": "这个即将发布的新版本,创始人xx称它为红树林。而在此之前,每当面临重大升级,产品经理们都会取一个应景的代号,这一次,为什么是红树林",
"title": "时代的火车向前开",
"picUrl": "",
"messageUrl": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI"
}
}
'''
data = {
"msgtype": "link",
"link": mes
}
return data
def marddown(self,mes):
'''
{
"msgtype": "markdown",
"markdown": {
"title":"杭州天气",
"text": "#### 杭州天气 @150XXXXXXXX \n > 9度,西北风1级,空气良89,相对温度73%\n > ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n > ###### 10点20分发布 [天气](https://www.dingtalk.com) \n"
}}
'''
data = {
"msgtype": "markdown",
"markdown": mes
}
return data
def ActionCard(self,mes):
'''
整体调整
{
"actionCard": {
"title": "乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身",
"text": "![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png)
### 乔布斯 20 年前想打造的苹果咖啡厅
Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
"btnOrientation": "0",
"singleTitle" : "阅读全文",
"singleURL" : "https://www.dingtalk.com/"
},
"msgtype": "actionCard"
}
单独跳转
{
"msgtype": "actionCard",
"actionCard": {
"title": "我 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身",
"text": "![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png) \n\n #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
"btnOrientation": "0",
"btns": [
{
"title": "内容不错",
"actionURL": "https://www.dingtalk.com/"
},
{
"title": "不感兴趣",
"actionURL": "https://www.dingtalk.com/"
}
]
}
}
'''
data = {
"actionCard": mes,
"msgtype": "actionCard"
}
return data
def FeedCard(self,mes):
'''
{
"msgtype":"feedCard",
"feedCard": {
"links": [
{
"title": "时代的火车向前开1",
"messageURL": "https://www.dingtalk.com/",
"picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
},
{
"title": "时代的火车向前开2",
"messageURL": "https://www.dingtalk.com/",
"picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
}
]
}
}
'''
data = {
"msgtype": "feedCard",
"feedCard": {
"links": mes
}
}
return data
if __name__ == '__main__':
token = '5c2777357a4aa5960799d01a02588c19fa90c3f498783376075dafda7d5d706a'
secret = 'SEC058dab30c973edc0dd70b2a7e97eddfd33f20b45a5117b7c5d55c8f2d0dec474'
mes = mes_type()
# text_data = '文本类型消息测试'
# req(token,secret,mes.text(text_data))
# link_data = {
# "title": "链接类型消息测试标题",
# "text": "链接类型消息测试消息内容",
# "messageUrl": "https://www.baidu.com",
# "picUrl": "https://iknow-pic.cdn.bcebos.com/a71ea8d3fd1f4134a1175ce3371f95cad1c85e0e"
# }
# req(token,secret,mes.link(link_data))
# markdown_data = {
# "title": "Marddown类型消息测试",
# "text": "[百度](https://www.baidu.com) \n\t **文本加粗**\n\t *文字倾斜*\n\t***加粗倾斜***\n\t![不知道](https://iknow-pic.cdn.bcebos.com/a71ea8d3fd1f4134a1175ce3371f95cad1c85e0e)\n- item1\n- item2\n 1. item1\n 2. item2"
# }
# req(token,secret,mes.marddown(markdown_data))
# ActionCard_data_all = {
# "title": "ActionCard整体跳转消息",
# "text": """
# 乔布斯 20 年前想打造的苹果咖啡厅Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到20年前苹果一个建立咖啡馆的计划
# ![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png)
# """,
# "btnOrientation": "0",
# "singleTitle": "阅读全文",
# "singleURL": "https://www.dingtalk.com/"
# }
# req(token, secret, mes.ActionCard(ActionCard_data_all))
# ActionCard_data = {
# "title": "ActionCard独立跳转消息",
# "text": "![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png) \n\n #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
# "btnOrientation": "0",
# "btns": [
# {
# "title": "内容不错",
# "actionURL": "https://www.dingtalk.com/"
# },
# {
# "title": "不感兴趣",
# "actionURL": "https://www.dingtalk.com/"
# }
# ]
# }
# req(token, secret, mes.ActionCard(ActionCard_data))
# FeedCard_data = [
# {
# "title": "时代的火车向前开1",
# "messageURL": "https://www.dingtalk.com/",
# "picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
# },
# {
# "title": "时代的火车向前开2",
# "messageURL": "https://www.dingtalk.com/",
# "picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
# },
# {
# "title": "时代的火车向前开2",
# "messageURL": "https://www.dingtalk.com/",
# "picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
# },
# {
# "title": "时代的火车向前开2",
# "messageURL": "https://www.dingtalk.com/",
# "picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
# },
# {
# "title": "时代的火车向前开2",
# "messageURL": "https://www.dingtalk.com/",
# "picURL": "https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"
# }
# ]
# req(token,secret,mes.FeedCard(FeedCard_data))
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/10/18 上午10:41
# File : echo_text.py.py
# 脚本作用 : 钉钉消息自动回复
# 项目名称 : 测试
# ------------------------------------
import argparse
import logging
from dingtalk_stream import AckMessage
import dingtalk_stream
import MFA
def setup_logger():
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s [%(filename)s:%(lineno)d]'))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
return logger
def define_options():
parser = argparse.ArgumentParser()
parser.add_argument(
'--client_id', dest='client_id', required=True,
help='app_key or suite_key from https://open-dev.digntalk.com'
)
parser.add_argument(
'--client_secret', dest='client_secret', required=True,
help='app_secret or suite_secret from https://open-dev.digntalk.com'
)
options = parser.parse_args()
return options
class EchoTextHandler(dingtalk_stream.ChatbotHandler):
def __init__(self, logger: logging.Logger = None):
super(dingtalk_stream.ChatbotHandler, self).__init__()
if logger:
self.logger = logger
async def process(self, callback: dingtalk_stream.CallbackMessage):
#消息发送人
incoming_message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
print(incoming_message)
#接收到的消息
text = incoming_message.text.content.strip()
if text == '验证码':
data = MFA.calGoogleCode('2FO6PJ4O7S67RXHH')
self.reply_text(f'验证码:\t {data}', incoming_message)
else:
self.reply_text('不好意思,我还没有学会',incoming_message)
#消息返回
return AckMessage.STATUS_OK, 'OK'
def main():
logger = setup_logger()
options = define_options()
credential = dingtalk_stream.Credential(options.client_id, options.client_secret)
client = dingtalk_stream.DingTalkStreamClient(credential)
client.register_callback_handler(dingtalk_stream.chatbot.ChatbotMessage.TOPIC, EchoTextHandler(logger))
client.start_forever()
if __name__ == '__main__':
main()
+170
View File
@@ -0,0 +1,170 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/10/18 上午10:41
# File : mfa.py
# 脚本作用 : 钉钉消息自动回复(支持设备验证码、账号信息及帮助查询)
# 项目名称 : 测试
# ------------------------------------
import logging
from dingtalk_stream import AckMessage
import dingtalk_stream
import time
import base64
import struct
import hmac
import sys
import hashlib
from logging.handlers import RotatingFileHandler # 用于日志轮转
def calGoogleCode(secretKey):
"""生成Google验证码的工具函数"""
input = int(time.time()) // 30
key = base64.b32decode(secretKey)
msg = struct.pack(">Q", input)
googleCode = hmac.new(key, msg, hashlib.sha1).digest()
# 版本兼容判断
o = googleCode[19] & 15 if (sys.version_info > (2, 7)) else ord(googleCode[19]) & 15
googleCode = str((struct.unpack(">I", googleCode[o:o + 4])[0] & 0x7fffffff) % 1000000)
# 补全6位验证码(若首位为0会被省略,需补全)
return googleCode.zfill(6)
class EchoTextHandler(dingtalk_stream.ChatbotHandler):
def __init__(self, logger: logging.Logger = None):
super(dingtalk_stream.ChatbotHandler, self).__init__()
self.logger = logger
# 定义支持的指令与对应配置
self.command_config = {
"堡垒机": {
"secret_key": "2FO6PJ4O7S67RXHH",
"user": None,
"pwd": None,
"desc": "仅返回堡垒机验证码"
},
"笔记本": {
"secret_key": "IVWRJD2IYB3OUIXU7X7ZK7WEKWOVNQEQTB3MBJ2S2KDG6UP2AYHMLELXCAVIHLG6",
"user": "B_tongyi@1411305101097388.onaliyun.com",
"pwd": "Admin@123",
"desc": "返回笔记本登录账号、密码及验证码"
},
"台式机": {
"secret_key": "72RVB6TBNP35D674H45MGDXKQD6HML4DZ7WJLR3NXDGQYAY2DMDIKWOPTKZINIXB",
"user": "T_tongyi@1411305101097388.onaliyun.com",
"pwd": "Admin@123",
"desc": "返回台式机登录账号、密码及验证码"
},
"工单": {
"secret_key": "2D3IRWIFK63PCTLQ5IK4X7JOVESELCHQGCBGBLAI5OFCJSNWC72XK463I44DIFJC",
"user": "gwL2-sub02@1759775427129703.onaliyun.com",
"pwd": "Yun@sgit2023",
"desc": "返回工单系统登录账号、密码及验证码"
},
"帮助": {
"desc": "查看所有支持的指令及说明"
}
}
async def process(self, callback: dingtalk_stream.CallbackMessage):
# 打印完整消息结构(便于调试,稳定后可注释)
if self.logger:
self.logger.info(f"完整消息结构:{callback.data}")
# 解析消息内容
incoming_message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
user_command = incoming_message.text.content.strip()
# 修复:从日志中发现用户名称在'senderNick'字段
sender_nick = callback.data.get("senderNick", "未知用户")
# 日志记录收到的消息
if self.logger:
self.logger.info(f"收到[{sender_nick}]的消息:{user_command}")
# 生成并发送回复
reply_content = await self.get_reply_content(user_command)
self.reply_text(reply_content, incoming_message)
return AckMessage.STATUS_OK, 'OK'
async def get_reply_content(self, command):
"""根据用户指令生成对应回复内容"""
if command == "帮助":
return self.generate_help_text()
config = self.command_config.get(command)
if config:
mfa = calGoogleCode(config["secret_key"])
if config["user"] and config["pwd"]:
return (f"{command}】登录信息\n"
f"账号:{config['user']}\n"
f"密码:{config['pwd']}\n"
f"验证码:{mfa}")
else:
return f"{command}】验证码:{mfa}"
return "不好意思,我还未支持该指令~\n发送「帮助」可查看所有可用功能"
def generate_help_text(self):
"""生成帮助文本"""
help_text = "目前支持以下指令,直接发送指令即可获取对应信息:\n"
for cmd, info in self.command_config.items():
help_text += f"• 「{cmd}」:{info['desc']}\n"
help_text += "\n提示:验证码有效期为30秒,获取后请尽快使用~"
return help_text
def setup_logger():
"""配置日志:仅写入文件,不输出到控制台,支持日志轮转"""
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置日志级别
# 移除已有的处理器(防止默认控制台输出)
if logger.hasHandlers():
logger.handlers.clear()
# 配置日志文件轮转
# 文件名:mfa.log,最大5MB,保留3个备份
file_handler = RotatingFileHandler(
'mfa.log',
maxBytes=5*1024*1024, # 5MB
backupCount=3,
encoding='utf-8' # 确保中文正常写入
)
# 设置日志格式
formatter = logging.Formatter(
'%(asctime)s %(name)-8s %(levelname)-8s %(message)s [%(filename)s:%(lineno)d]'
)
file_handler.setFormatter(formatter)
# 添加文件处理器
logger.addHandler(file_handler)
return logger
def main():
# 初始化日志(仅写入文件)
logger = setup_logger()
# 钉钉客户端配置
client_id = 'dinge1p7abma50df9uh7'
client_secret = '63p0_GNh1mrfXK7pxUkpIWrzX6gyT1Ot_adwgAxyo27qpbcR2h9l6YYG2DbA4yoK'
credential = dingtalk_stream.Credential(client_id, client_secret)
client = dingtalk_stream.DingTalkStreamClient(credential)
# 注册消息处理器并启动
client.register_callback_handler(
dingtalk_stream.chatbot.ChatbotMessage.TOPIC,
EchoTextHandler(logger)
)
logger.info("钉钉机器人已启动,等待接收消息...")
client.start_forever()
if __name__ == '__main__':
main()
@@ -0,0 +1,53 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/27 下午4:40
# File : MFA.py
# 脚本作用 : MFS动态验证码
# 项目名称 : 工具
# ------------------------------------
import time
import base64
import struct
import hmac
import sys
import hashlib
def calGoogleCode(secretKey):
input = int(time.time()) // 30
key = base64.b32decode(secretKey)
msg = struct.pack(">Q", input)
googleCode = hmac.new(key, msg, hashlib.sha1).digest()
# 版本判断
if (sys.version_info > (2, 7)):
o = googleCode[19] & 15
else:
o = ord(googleCode[19]) & 15
googleCode = str((struct.unpack(">I", googleCode[o:o + 4])[0] & 0x7fffffff) % 1000000)
if len(googleCode) == 5: # 如果验证码的第一位是0,则不会显示。此处判断若是5位码,则在第一位补上0
googleCode = '0' + googleCode
return googleCode
if __name__ == "__main__":
#阿里云工单maf密钥
FortressSecret = '2D3IRWIFK63PCTLQ5IK4X7JOVESELCHQGCBGBLAI5OFCJSNWC72XK463I44DIFJC'
#国网内网堡垒机动态码---王维
#FortressSecret = '2FO6PJ4O7S67RXHH'
data = calGoogleCode(FortressSecret)
print(f'阿里云工单MFA验证码:{data}')
i = 0
while i < 5:
if data != calGoogleCode(FortressSecret):
print(f'阿里云工单MFA验证码:{calGoogleCode(FortressSecret)}')
data = calGoogleCode(FortressSecret)
i+=1
else:
pass
time.sleep(1)
@@ -0,0 +1,72 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/10/18 上午10:41
# File : echo_text.py.py
# 脚本作用 : 钉钉消息自动回复
# 项目名称 : 测试
# ------------------------------------
import argparse
import logging
from dingtalk_stream import AckMessage
import dingtalk_stream
import MFA
def setup_logger():
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s [%(filename)s:%(lineno)d]'))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
return logger
def define_options():
parser = argparse.ArgumentParser()
parser.add_argument(
'--client_id', dest='client_id', required=True,
help='app_key or suite_key from https://open-dev.digntalk.com'
)
parser.add_argument(
'--client_secret', dest='client_secret', required=True,
help='app_secret or suite_secret from https://open-dev.digntalk.com'
)
options = parser.parse_args()
return options
class EchoTextHandler(dingtalk_stream.ChatbotHandler):
def __init__(self, logger: logging.Logger = None):
super(dingtalk_stream.ChatbotHandler, self).__init__()
if logger:
self.logger = logger
async def process(self, callback: dingtalk_stream.CallbackMessage):
#消息发送人
incoming_message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
print(incoming_message)
#接收到的消息
text = incoming_message.text.content.strip()
if text == '验证码':
data = MFA.calGoogleCode('2FO6PJ4O7S67RXHH')
self.reply_text(f'验证码{data}', incoming_message)
else:
self.reply_text('不好意思,我还没有学会',incoming_message)
#消息返回
return AckMessage.STATUS_OK, 'OK'
def main():
logger = setup_logger()
options = define_options()
credential = dingtalk_stream.Credential(options.client_id, options.client_secret)
client = dingtalk_stream.DingTalkStreamClient(credential)
client.register_callback_handler(dingtalk_stream.chatbot.ChatbotMessage.TOPIC, EchoTextHandler(logger))
client.start_forever()
if __name__ == '__main__':
main()
+1
View File
@@ -0,0 +1 @@
/usr/local/bin/python3.9 /opt/dingding/echo_text.py --client_id="dinge5z8v7iufyknqiow" --client_secret="NstaxHjjSJK2ZPX5bIQf4qhNlaeh6vrYXu71K04xs9lJ1axKk6WzeyVRlynyaYXA" >>/opt/dingding/dingding.sh&
@@ -0,0 +1,178 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/1/10 下午4:14
# @Author : cmk
# @File : 钉钉发送消息.py
# @Email : 15726649712@163.com
'''
测试使用机器人
https://oapi.dingtalk.com/robot/send?access_token=d7e8be9866a981d899e38aa27005e264f47d1f913816caa1001f9d5229f7d074
SEC6872ee8ddf8e72bf97f4b5f641f1cdbaf28185013d52e45b6b2a2b8c8675b959
'''
import time
import hmac
import hashlib
import base64
import requests
import json
import pymysql
# 消息发送
class res_dingding():
def __init__(self, tokin, secret=None, ip=None, guanjianchi=None):
self.tokin = tokin
self.secret = secret
self.ip = ip
self.guanjianchi = guanjianchi
def sign(self):
timestamp = str(round(time.time() * 1000))
string_to_sign = '{}\n{}'.format(timestamp, self.secret)
hmac_code = hmac.new(self.secret.encode('utf-8'), string_to_sign.encode('utf-8'),
digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code).decode('utf-8')
return timestamp, sign
def req(self, data):
timestamp, sign = self.sign()
url = f'https://oapi.dingtalk.com/robot/send?access_token={self.tokin}&timestamp={timestamp}&sign={sign}'
response = requests.post(url=url, data=json.dumps(data), headers={'Content-Type': 'application/json'})
print(response.text)
if response.status_code == 200:
mes = "消息发送成功"
else:
mes = f"消息发送失败,状态码:{response.status_code}"
print(mes)
class mes_type():
def text(self, mes):
'''
文本类型
"text": {
"content":"我就是我, @014728255240768602 是不一样的烟火"
},
"msgtype":"text"
}
'''
data = {
"msgtype": "text",
"text": {
"content": mes
}
}
return data
def link(self, mes,title,messageUrl):
'''
{
"msgtype": "link",
"link": {
"text": "这个即将发布的新版本,创始人xx称它为红树林。而在此之前,每当面临重大升级,产品经理们都会取一个应景的代号,这一次,为什么是红树林",
"title": "时代的火车向前开",
"picUrl": "",
"messageUrl": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI"
}
}
'''
data = {
"msgtype": "link",
"link": {
"text": mes,
"title": title,
"picUrl": "",
"messageUrl": messageUrl
}
}
return data
def marddown(self, title,mes):
'''
{
"msgtype": "markdown",
"markdown": {
"title":"杭州天气",
"text": "#### 杭州天气 @150XXXXXXXX \n > 9度,西北风1级,空气良89,相对温度73%\n > ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n > ###### 10点20分发布 [天气](https://www.dingtalk.com) \n"
}}
'''
data = {
"msgtype": "markdown",
"markdown": {
"title":title,
'text': mes
}
}
return data
class MySql():
def __init__(self, host, port, user, passwd, db):
self.host = host
self.port = port
self.user = user
self.password = passwd
self.db = db
self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, password=self.password,
database=self.db)
self.cursor = self.conn.cursor()
def select(self, sql):
self.cursor.execute(sql)
return self.cursor.fetchall()
if __name__ == '__main__':
db = MySql('127.0.0.1', 3306, 'root', 'password', 'zucai')
sql= '''
SELECT
A.new AS '数据写入时间',
A.changci AS '比赛场次',
A.bisai_date AS '比赛时间',
A.bisai_type AS '比赛类型',
A.master AS '主队',
A.slave AS '客队',
A.jieguo AS '平均赔率',
B.jieguo AS '立博',
C.jieguo AS 'Bet365',
D.jieguo AS '澳门',
E.jieguo AS '韦德',
F.jieguo AS 'snai',
G.jieguo AS '威廉',
H.jieguo AS '平博'
FROM
-- 以平均赔率对应的子查询结果作为主表(这里用左连接举例,你可以根据实际需求调整连接方式)
(SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = '平均赔率' ORDER BY `new` DESC LIMIT 14) A
-- 通过左连接关联立博对应的子查询结果,关联条件基于相同的new、master、slave字段值,同时按照时间排序取最新的一条记录
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = '立博' ORDER BY `new` DESC LIMIT 14) B
ON A.new = B.new AND A.master = B.master AND A.slave = B.slave
-- 继续通过左连接关联Bet365对应的子查询结果,关联条件同上,且按时间排序取最新记录
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = 'Bet365' ORDER BY `new` DESC LIMIT 14) C
ON A.new = C.new AND A.master = C.master AND A.slave = C.slave
-- 依次按照这样的方式连接其他公司对应的子查询结果,并按时间取最新记录
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = '澳门' ORDER BY `new` DESC LIMIT 14) D
ON A.new = D.new AND A.master = D.master AND A.slave = D.slave
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = '韦德' ORDER BY `new` DESC LIMIT 14) E
ON A.new = E.new AND A.master = E.master AND A.slave = E.slave
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = 'snai' ORDER BY `new` DESC LIMIT 14) F
ON A.new = F.new AND A.master = F.master AND A.slave = F.slave
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = '威廉' ORDER BY `new` DESC LIMIT 14) G
ON A.new = G.new AND A.master = G.master AND A.slave = G.slave
LEFT JOIN (SELECT `new`, `changci`, `bisai_type`, `bisai_date`, `master`, `slave`, `data_s`, `data_p`, `data_f`, `jieguo`, `gongshi` FROM o_pei WHERE gongshi = '平博' ORDER BY `new` DESC LIMIT 14) H
ON A.new = H.new AND A.master = H.master AND A.slave = H.slave;
'''
data_list = db.select(sql)
data = ''
c = "==" * 10
print(c)
for i in data_list:
a = f'''{c}\n## 场次:{i[1]} {i[4]} vs {i[5]} \n## 数据获取时间: {i[0]}\n### 购买推荐:{list(i[6:14])}\n'''
print(a)
data +=a
token = '5c2777357a4aa5960799d01a02588c19fa90c3f498783376075dafda7d5d706a'
secret = 'SEC058dab30c973edc0dd70b2a7e97eddfd33f20b45a5117b7c5d55c8f2d0dec474'
Ding = res_dingding(token, secret)
Mes = mes_type()
Ding.req(Mes.marddown('足彩',data))
@@ -0,0 +1,32 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/6/16 11:42
# @Author : cmk
# @File : 动态验证码.py
# @Email : 15726649712@163.com
import time
import base64
import struct
import hmac
import hashlib
import sys
def calGoogleCode(secretKey):
input = int(time.time()) // 30
key = base64.b32decode(secretKey)
msg = struct.pack(">Q", input)
googleCode = hmac.new(key, msg, hashlib.sha1).digest()
# 版本判断
if (sys.version_info > (2, 7)):
o = googleCode[19] & 15
else:
o = ord(googleCode[19]) & 15
googleCode = str((struct.unpack(">I", googleCode[o:o + 4])[0] & 0x7fffffff) % 1000000)
if len(googleCode) == 5: # 如果验证码的第一位是0,则不会显示。此处判断若是5位码,则在第一位补上0
googleCode = '0' + googleCode
return googleCode
if __name__ == '__main__':
FortressSecret = "HZKUXZZNEJX35JUVKVU7OF6F33CSV5LU"
print(calGoogleCode(FortressSecret))
@@ -0,0 +1,16 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/7/24 下午10:32
# @Author : cmk
# @File : 生成密钥.py
# @Email : 15726649712@163.com
import pyotp
import time
totp = pyotp.random_base32()
print(totp)
totp = pyotp.TOTP('HZKUXZZNEJX35JUVKVU7OF6F33CSV5LU').now()
print(totp)
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/27 下午4:40
# File : MFA.py
# 脚本作用 :
# 项目名称 : 阿里云平台
# ------------------------------------
import time
import base64
import struct
import hmac
import sys
import hashlib
def calGoogleCode(secretKey):
input = int(time.time()) // 30
key = base64.b32decode(secretKey)
msg = struct.pack(">Q", input)
googleCode = hmac.new(key, msg, hashlib.sha1).digest()
# 版本判断
if (sys.version_info > (2, 7)):
o = googleCode[19] & 15
else:
o = ord(googleCode[19]) & 15
googleCode = str((struct.unpack(">I", googleCode[o:o + 4])[0] & 0x7fffffff) % 1000000)
if len(googleCode) == 5: # 如果验证码的第一位是0,则不会显示。此处判断若是5位码,则在第一位补上0
googleCode = '0' + googleCode
return googleCode
if __name__ == "__main__":
#阿里云工单maf密钥
FortressSecret = '2D3IRWIFK63PCTLQ5IK4X7JOVESELCHQGCBGBLAI5OFCJSNWC72XK463I44DIFJC'
#国网内网堡垒机动态码---王维
#FortressSecret = '2FO6PJ4O7S67RXHH'
data = calGoogleCode(FortressSecret)
print(f'阿里云工单MFA验证码:{data}')
i = 0
while i < 5:
if data != calGoogleCode(FortressSecret):
print(f'阿里云工单MFA验证码:{calGoogleCode(FortressSecret)}')
data = calGoogleCode(FortressSecret)
i+=1
else:
pass
time.sleep(1)
+5
View File
@@ -0,0 +1,5 @@
import pandas as pd
df = pd.read_excel('国网内网云版本2605.xlsx',sheet_name='部署情况')
print(df.head())
Binary file not shown.
+497
View File
@@ -0,0 +1,497 @@
"""
图形化自动处理:
1. Word -> PDF -> 图片版PDF
2. PDF -> 图片版PDF
依赖:
pip install pymupdf pywin32
说明:
- 支持 .doc / .docx / .pdf
- 支持一次选择多个文件
- 输出图片版 PDF
- 自动清理临时文件
"""
import os
import time
import shutil
import threading
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import fitz
import win32com.client
# =========================
# 核心转换函数
# =========================
def word_to_pdf_by_wps(word_path, pdf_path, log_func=print):
"""
WPS 转 PDF
"""
wps = None
doc = None
try:
try:
wps = win32com.client.Dispatch("KWPS.Application")
except Exception:
wps = win32com.client.Dispatch("wps.Application")
wps.Visible = False
doc = wps.Documents.Open(os.path.abspath(word_path))
time.sleep(1)
# 17 = PDF
doc.ExportAsFixedFormat(os.path.abspath(pdf_path), 17)
log_func(f"[OK] Word 转 PDF 完成: {pdf_path}")
finally:
try:
if doc:
doc.Close(False)
except Exception:
pass
try:
if wps:
wps.Quit()
except Exception:
pass
def pdf_to_images(pdf_path, image_dir, zoom=2, log_func=print):
"""
PDF 每页转图片
"""
os.makedirs(image_dir, exist_ok=True)
doc = fitz.open(pdf_path)
image_paths = []
try:
for i in range(len(doc)):
page = doc.load_page(i)
pix = page.get_pixmap(
matrix=fitz.Matrix(zoom, zoom),
alpha=False
)
img_path = os.path.join(
image_dir,
f"page_{i + 1}.png"
)
pix.save(img_path)
image_paths.append(img_path)
log_func(f"[OK] 截图完成: {img_path}")
finally:
doc.close()
return image_paths
def images_to_pdf(image_paths, output_pdf_path, log_func=print):
"""
图片重新合成 PDF
"""
pdf = fitz.open()
try:
for img_path in image_paths:
img = fitz.open(img_path)
try:
rect = img[0].rect
page = pdf.new_page(
width=rect.width,
height=rect.height
)
page.insert_image(rect, filename=img_path)
finally:
img.close()
pdf.save(output_pdf_path, deflate=True)
finally:
pdf.close()
log_func(f"[OK] 图片版 PDF 已生成: {output_pdf_path}")
def safe_delete(path, log_func=print):
"""
删除文件或目录
"""
if not os.path.exists(path):
return
try:
if os.path.isfile(path):
os.remove(path)
log_func(f"[OK] 文件已删除: {path}")
elif os.path.isdir(path):
shutil.rmtree(path)
log_func(f"[OK] 文件夹已删除: {path}")
except Exception as e:
log_func(f"[警告] 删除失败: {path}")
log_func(f"原因: {e}")
def convert_one_file(input_path, output_dir, zoom=2, log_func=print):
"""
处理单个文件
"""
input_path = os.path.abspath(input_path)
if not os.path.exists(input_path):
raise FileNotFoundError(f"文件不存在: {input_path}")
ext = os.path.splitext(input_path)[1].lower()
base_name = os.path.splitext(os.path.basename(input_path))[0]
work_dir = output_dir if output_dir else os.path.dirname(input_path)
os.makedirs(work_dir, exist_ok=True)
image_dir = os.path.join(
work_dir,
base_name + "_images"
)
output_pdf_path = os.path.join(
work_dir,
base_name + "_图片版.pdf"
)
temp_pdf_path = os.path.join(
work_dir,
base_name + "_temp.pdf"
)
generated_temp_pdf = False
try:
if ext in [".doc", ".docx"]:
log_func("=" * 80)
log_func(f"[1] 检测到 Word 文档: {input_path}")
word_to_pdf_by_wps(
input_path,
temp_pdf_path,
log_func
)
pdf_path = temp_pdf_path
generated_temp_pdf = True
elif ext == ".pdf":
log_func("=" * 80)
log_func(f"[1] 检测到 PDF 文件: {input_path}")
pdf_path = input_path
else:
raise ValueError(f"不支持的文件类型: {ext}")
log_func("[2] 正在按页截图...")
image_paths = pdf_to_images(
pdf_path,
image_dir,
zoom=zoom,
log_func=log_func
)
if not image_paths:
raise RuntimeError("PDF 没有成功生成任何图片")
log_func("[3] 正在生成图片版 PDF...")
images_to_pdf(
image_paths,
output_pdf_path,
log_func=log_func
)
log_func("[4] 清理临时文件...")
safe_delete(image_dir, log_func)
if generated_temp_pdf:
safe_delete(temp_pdf_path, log_func)
log_func(f"[完成] 最终文件: {output_pdf_path}")
return output_pdf_path
except Exception as e:
log_func(f"[失败] {input_path}")
log_func(f"原因: {e}")
raise
# =========================
# 图形化界面
# =========================
class PdfImageApp:
def __init__(self, root):
self.root = root
self.root.title("Word / PDF 转图片版 PDF 工具")
self.root.geometry("900x600")
self.selected_files = []
self.output_dir = ""
self.build_ui()
def build_ui(self):
title_label = tk.Label(
self.root,
text="需要本地有wps \nWord / PDF 转图片版 PDF 工具",
font=("微软雅黑", 18, "bold")
)
title_label.pack(pady=10)
desc_label = tk.Label(
self.root,
text="支持 .doc / .docx / .pdf,可一次选择多个文件,自动生成图片版 PDF",
font=("微软雅黑", 10)
)
desc_label.pack()
button_frame = tk.Frame(self.root)
button_frame.pack(pady=10)
select_file_btn = tk.Button(
button_frame,
text="选择文件",
width=18,
command=self.select_files
)
select_file_btn.grid(row=0, column=0, padx=10)
select_output_btn = tk.Button(
button_frame,
text="选择输出目录",
width=18,
command=self.select_output_dir
)
select_output_btn.grid(row=0, column=1, padx=10)
start_btn = tk.Button(
button_frame,
text="开始转换",
width=18,
bg="#4CAF50",
fg="white",
command=self.start_convert
)
start_btn.grid(row=0, column=2, padx=10)
clear_btn = tk.Button(
button_frame,
text="清空日志",
width=18,
command=self.clear_log
)
clear_btn.grid(row=0, column=3, padx=10)
self.file_label = tk.Label(
self.root,
text="当前未选择文件",
fg="blue",
wraplength=850,
justify="left"
)
self.file_label.pack(pady=5)
self.output_label = tk.Label(
self.root,
text="输出目录:默认输出到原文件所在目录",
fg="purple",
wraplength=850,
justify="left"
)
self.output_label.pack(pady=5)
zoom_frame = tk.Frame(self.root)
zoom_frame.pack(pady=5)
# tk.Label(
# zoom_frame,
# text="清晰度 zoom"
# ).pack(side=tk.LEFT)
#
# self.zoom_var = tk.StringVar(value="2")
#
# zoom_entry = tk.Entry(
# zoom_frame,
# textvariable=self.zoom_var,
# width=8
# )
# zoom_entry.pack(side=tk.LEFT)
#
# tk.Label(
# zoom_frame,
# text="建议:2 正常,3 更清晰但文件更大"
# ).pack(side=tk.LEFT, padx=10)
self.log_box = scrolledtext.ScrolledText(
self.root,
width=110,
height=25,
font=("Consolas", 10)
)
self.log_box.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
def log(self, msg):
self.log_box.insert(tk.END, msg + "\n")
self.log_box.see(tk.END)
self.root.update_idletasks()
def clear_log(self):
self.log_box.delete("1.0", tk.END)
def select_files(self):
files = filedialog.askopenfilenames(
title="请选择 Word 或 PDF 文件",
filetypes=[
("支持的文件", "*.doc *.docx *.pdf"),
("Word 文件", "*.doc *.docx"),
("PDF 文件", "*.pdf"),
("所有文件", "*.*")
]
)
if files:
self.selected_files = list(files)
self.file_label.config(
text=f"已选择 {len(self.selected_files)} 个文件:\n" +
"\n".join(self.selected_files)
)
self.log(f"[选择文件] 共选择 {len(self.selected_files)} 个文件")
def select_output_dir(self):
output_dir = filedialog.askdirectory(
title="请选择输出目录"
)
if output_dir:
self.output_dir = output_dir
self.output_label.config(
text=f"输出目录:{self.output_dir}"
)
self.log(f"[输出目录] {self.output_dir}")
def start_convert(self):
if not self.selected_files:
messagebox.showwarning(
"提示",
"请先选择一个或多个 Word / PDF 文件"
)
return
try:
zoom = float(self.zoom_var.get())
if zoom <= 0:
raise ValueError
except Exception:
messagebox.showwarning(
"提示",
"zoom 必须是大于 0 的数字,例如 2 或 3"
)
return
t = threading.Thread(
target=self.convert_files_thread,
args=(zoom,),
daemon=True
)
t.start()
def convert_files_thread(self, zoom):
success_files = []
failed_files = []
self.log("")
self.log("========== 开始批量转换 ==========")
for index, file_path in enumerate(self.selected_files, start=1):
self.log("")
self.log(f"[任务 {index}/{len(self.selected_files)}] {file_path}")
try:
output_pdf = convert_one_file(
input_path=file_path,
output_dir=self.output_dir,
zoom=zoom,
log_func=self.log
)
success_files.append(output_pdf)
except Exception as e:
failed_files.append((file_path, str(e)))
self.log("")
self.log("========== 批量转换结束 ==========")
self.log(f"[成功] {len(success_files)}")
self.log(f"[失败] {len(failed_files)}")
if success_files:
self.log("")
self.log("生成的图片版 PDF")
for f in success_files:
self.log(f)
if failed_files:
self.log("")
self.log("失败文件:")
for f, reason in failed_files:
self.log(f"{f} -> {reason}")
if failed_files:
messagebox.showwarning(
"转换完成",
f"处理完成。\n\n成功:{len(success_files)}\n失败:{len(failed_files)}\n\n请查看日志。\n\n请使用生成的“图片版 PDF”文件。"
)
else:
messagebox.showinfo(
"转换完成",
f"全部处理完成。\n\n成功生成 {len(success_files)} 个图片版 PDF。\n\n请使用生成的“图片版 PDF”文件。"
)
def main():
root = tk.Tk()
app = PdfImageApp(root)
root.mainloop()
if __name__ == "__main__":
main()
@@ -0,0 +1,248 @@
"""
自动处理:
1. Word -> PDF -> 图片版PDF
2. PDF -> 图片版PDF
依赖:
pip install pymupdf pywin32
"""
import os
import sys
import time
import shutil
import fitz
import win32com.client
def word_to_pdf_by_wps(word_path, pdf_path):
"""
WPS 转 PDF
"""
try:
wps = win32com.client.Dispatch("KWPS.Application")
except Exception:
wps = win32com.client.Dispatch("wps.Application")
wps.Visible = False
doc = wps.Documents.Open(os.path.abspath(word_path))
time.sleep(1)
# 17 = PDF
doc.ExportAsFixedFormat(os.path.abspath(pdf_path), 17)
doc.Close(False)
wps.Quit()
print(f"[OK] Word 转 PDF 完成: {pdf_path}")
def pdf_to_images(pdf_path, image_dir, zoom=2):
"""
PDF 每页转图片
"""
os.makedirs(image_dir, exist_ok=True)
doc = fitz.open(pdf_path)
image_paths = []
for i in range(len(doc)):
page = doc.load_page(i)
pix = page.get_pixmap(
matrix=fitz.Matrix(zoom, zoom),
alpha=False
)
img_path = os.path.join(
image_dir,
f"page_{i + 1}.png"
)
pix.save(img_path)
image_paths.append(img_path)
print(f"[OK] 截图完成: {img_path}")
doc.close()
return image_paths
def images_to_pdf(image_paths, output_pdf_path):
"""
图片重新合成 PDF
"""
pdf = fitz.open()
for img_path in image_paths:
img = fitz.open(img_path)
rect = img[0].rect
page = pdf.new_page(
width=rect.width,
height=rect.height
)
page.insert_image(rect, filename=img_path)
img.close()
pdf.save(output_pdf_path, deflate=True)
pdf.close()
print(f"[OK] 图片版 PDF 已生成: {output_pdf_path}")
def safe_delete(path):
"""
自动删除:
- 文件
- 空目录
- 非空目录
"""
if not os.path.exists(path):
return
try:
if os.path.isfile(path):
os.remove(path)
print(f"[OK] 文件已删除: {path}")
elif os.path.isdir(path):
shutil.rmtree(path)
print(f"[OK] 文件夹已删除: {path}")
except Exception as e:
print(f"[警告] 删除失败: {path}")
print(f"原因: {e}")
def main():
if len(sys.argv) < 2:
print("用法:")
print("python auto_pdf_image.py 文件")
return
input_path = os.path.abspath(sys.argv[1])
if not os.path.exists(input_path):
print("文件不存在:", input_path)
return
ext = os.path.splitext(input_path)[1].lower()
base_dir = os.path.dirname(input_path)
base_name = os.path.splitext(os.path.basename(input_path))[0]
image_dir = os.path.join(
base_dir,
base_name + "_images"
)
output_pdf_path = os.path.join(
base_dir,
base_name + "_图片版.pdf"
)
temp_pdf_path = os.path.join(
base_dir,
base_name + "_temp.pdf"
)
generated_temp_pdf = False
try:
# =========================
# Word 文档
# =========================
if ext in [".doc", ".docx"]:
print("[1] 检测到 Word 文档")
word_to_pdf_by_wps(
input_path,
temp_pdf_path
)
pdf_path = temp_pdf_path
generated_temp_pdf = True
# =========================
# PDF 文件
# =========================
elif ext == ".pdf":
print("[1] 检测到 PDF 文件")
pdf_path = input_path
else:
print("仅支持:")
print(".doc")
print(".docx")
print(".pdf")
return
# =========================
# PDF -> 图片
# =========================
print("[2] 正在按页截图...")
image_paths = pdf_to_images(
pdf_path,
image_dir,
zoom=2
)
# =========================
# 图片 -> PDF
# =========================
print("[3] 正在生成图片版 PDF...")
images_to_pdf(
image_paths,
output_pdf_path
)
# =========================
# 删除临时文件
# =========================
print("[4] 清理临时文件...")
time.sleep(1)
safe_delete(image_dir)
# 删除临时 PDF
if generated_temp_pdf:
safe_delete(temp_pdf_path)
print()
print("[完成]")
print("最终文件:", output_pdf_path)
except Exception as e:
print("[失败]", e)
print()
print("请确认:")
print("1. WPS 已安装")
print("2. 文档能正常打开")
print("3. 文件未被占用")
if __name__ == "__main__":
main()
@@ -0,0 +1,49 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/4/22 17:05
# @Author : cmk
# @File : check_perf_jiankong.py
import os
import sys
import json
import requests
def get_vm_name(sr):
url = 'http://localhost:7070/api/v3/column/m.ip?m.sr.id={}%23'.format(sr)
data = requests.get(url=url).text
data = json.loads(data) # 列表
sr_ip_list = []
for i in range(len(data)):
sr_ip_list.append(data[i]['m.ip'])
return sr_ip_list
def get_vm_docker_id(sr):
vm_docker_list = []
for ip in get_vm_name(sr):
cmd = '''ssh %s -o ConnectTimeout=5 -o ConnectionAttempts=3 -o PasswordAuthentication=no -o StrictHostKeyChecking=no docker ps |grep %s |awk '{print $1}' ''' % (
ip, sr)
docker_id = os.popen(cmd).readlines()[0].replace('\n', '')
vm_docker_dise = []
vm_docker_dise.append(ip)
vm_docker_dise.append(docker_id)
vm_docker_list.append(vm_docker_dise)
return vm_docker_list
if __name__ == '__main__':
sr = 'redline-perf.PerfWorker'
rds_id = sys.argv[1]
for docker_id in get_vm_docker_id(sr):
cmd = '''ssh %s docker exec -i %s ifconfig|grep inet|grep broadcast|awk '{print $2}' ''' % (docker_id[0],docker_id[1])
ip = os.popen(cmd).readlines()[0].replace('\n', '')
#curl -L "http://127.0.0.1:8080/v1/api/timeSeries/mysql_perf?insName=rm-sj55xtw8hapf4848x&targetMetrics=avg.cpu_usage"
url = "http://{}:8080/v1/api/timeSeries/mysql_perf?insName={}&targetMetrics=avg.cpu_usage".format(ip,rds_id)
data = json.loads(requests.get(url).text)
keys = data[0].keys()
key_list = list(keys)
if 'success' in key_list:
print '\033[91m服务:{}ip信息:{},性能监控异常,服务异常,需要排查app.log日志\033[0m'.format(sr,docker_id[0])
else:
print '\033[92m服务:{}ip信息:{},性能监控正常\033[0m'.format(sr,docker_id[0])
+71
View File
@@ -0,0 +1,71 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Time : 2024/4/18 19:25
# @Author : cmk
# @File : check_perf_jiya.py
import json
import os
import requests
'''
date &&
curl "http://localhost:7070/api/v3/column/m.ip?m.sr.id=redline-perf.PerfMaster%23"| grep ip | awk -F '"' '{print $(NF-1)}' > masterhosts
curl "http://localhost:7070/api/v3/column/m.ip?m.sr.id=redline-perf.PerfWorker%23" | grep ip | awk -F '"' '{print $(NF-1)}' > perfworkerhosts
curl "http://localhost:7070/api/v3/column/m.ip?m.sr.id=redline-perf.LogWorker%23"| grep ip | awk -F '"' '{print $(NF-1)}' > logworkerhosts
&& cat perfworkerhosts > allhosts && cat logworkerhosts >> allhosts && cat masterhosts >> allhosts && sort allhosts | uniq > allhosts2
pssh -P -i -p 10 -h perfworkerhosts "cd /cloud/data/redline-perf/PerfWorker#/perf-worker/home/admin/redline-perf;tail -n 300 ./log/app.log | grep processing | tail -n 10 "
pssh -P -i -p 10 -h logworkerhosts "cd /cloud/data/redline-perf/LogWorker#/log-worker/home/admin/redline-perf; tail -n 300 ./log/app.log | grep processing | tail -n 10 "
grep processing /home/admin/redline-perf/log/app.log | tail -n 10
'''
def get_vm_name(sr):
url = 'http://localhost:7070/api/v3/column/m.ip?m.sr.id={}%23'.format(sr)
data = requests.get(url=url).text
data = json.loads(data) # 列表
sr_ip_list = []
for i in range(len(data)):
sr_ip_list.append(data[i]['m.ip'])
return sr_ip_list
def get_vm_docker_id(sr):
vm_docker_list = []
for ip in get_vm_name(sr):
cmd = '''ssh %s -o ConnectTimeout=5 -o ConnectionAttempts=3 -o PasswordAuthentication=no -o StrictHostKeyChecking=no docker ps |grep %s |awk '{print $1}' ''' % (
ip, sr)
docker_id = os.popen(cmd).readlines()[0].replace('\n', '')
vm_docker_dise = []
vm_docker_dise.append(ip)
vm_docker_dise.append(docker_id)
vm_docker_list.append(vm_docker_dise)
return vm_docker_list
if __name__ == '__main__':
sr_list = ['redline-perf.PerfWorker', 'redline-perf.PerfMaster', 'redline-perf.LogWorker']
for sr in sr_list:
vm_docker_id = get_vm_docker_id(sr)
for i in range(len(vm_docker_id)):
ip = vm_docker_id[i][0]
docker_id = vm_docker_id[i][1]
# 需要添加判断,可能存在多个异常
cmd = '''ssh %s docker exec -i %s 'grep processed-received /home/admin/redline-perf/log/app.log | tail -n 1' ''' % (
ip, docker_id)
#data_list = os.popen(cmd).readlines()
#for data in data_list:
data = os.popen(cmd).readline()
data = data.rsplit(':')
data_int = int(data[-1])
mes_list = []
if data_int < int(-100):
print "\033[91m 服务是:{}ip是:{},服务当前值是:{},当前服务存在积压,需要重启异常sr\033[0m".format(sr, ip, data_int)
# data = raw_input('当前节点存在积压影响管控使用,是否重启,重启输入:Y,不重启输入N,其他默认不重启:\n')
# if data.lower() == 'y':
# os.system('ssh {} docker restart {}'.format(ip,docker_id))
# else:
# pass
else:
print "\033[92m 服务是:{}ip是:{},服务当前值是:{},当前服务正常\033[0m".format(sr, ip, data_int)
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/4/22 17:05
# @Author : cmk
# @File : check_perf_jiankong.py
import os
import sys
import json
import random
import requests
def get_vm_name(sr):
url = 'http://localhost:7070/api/v3/column/m.ip?m.sr.id={}%23'.format(sr)
data = requests.get(url=url).text
data = json.loads(data) # 列表
sr_ip_list = []
for i in range(len(data)):
sr_ip_list.append(data[i]['m.ip'])
return sr_ip_list
def get_vm_docker_id(sr):
vm_docker_list = []
for ip in get_vm_name(sr):
cmd = '''ssh %s -o ConnectTimeout=5 -o ConnectionAttempts=3 -o PasswordAuthentication=no -o StrictHostKeyChecking=no docker ps |grep %s |awk '{print $1}' ''' % (
ip, sr)
docker_id = os.popen(cmd).readlines()[0].replace('\n', '')
vm_docker_dise = []
vm_docker_dise.append(ip)
vm_docker_dise.append(docker_id)
vm_docker_list.append(vm_docker_dise)
return vm_docker_list
if __name__ == '__main__':
sr = 'redline-perf.LogWorker'
rds_id = sys.argv[1]
number = random.randint(0,len(get_vm_docker_id(sr))-1)
docker_id = get_vm_docker_id(sr)[number]
cmd = '''ssh %s docker exec -i %s ifconfig|grep inet|grep broadcast|awk '{print $2}' ''' % (docker_id[0],docker_id[1])
ip = os.popen(cmd).readlines()[0].replace('\n', '')
# 慢sql信息(一个节点)
#curl - L "http://127.0.0.1:8080/v2/api/log/slowlog/detail?dbType=mysql&insName=rm-9uryw9o566n148lc4&pageCount=1&pageSize=30&reverseOrderQuery=true&currentPage=1"
url = "http://{}:8080/v2/api/log/slowlog/detail?dbType=mysql&insName={}&pageCount=1&pageSize=30&reverseOrderQuery=true&currentPage=1".format(ip,rds_id)
data = json.loads(requests.get(url).text)
keys = data.keys()
key_list = list(keys)
if 'success' in key_list:
if data.get('success') == True:
print '\033[92m服务:{}ip信息:{},慢sql审计功能正常\033[0m'.format(sr, docker_id[0])
print data
else:
print '\033[91m服务:{}ip信息:{},慢sql审计功能异常,需要排查app.log日志\033[0m'.format(sr, docker_id[0])
print data
else:
print '\033[91m服务:{}ip信息:{},慢sql审计功能异常,需要排查app.log日志\033[0m'.format(sr, docker_id[0])
print data
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/4/22 17:05
# @Author : cmk
# @File : check_perf_jiankong.py
import os
import sys
import json
import requests
def get_vm_name(sr):
url = 'http://localhost:7070/api/v3/column/m.ip?m.sr.id={}%23'.format(sr)
data = requests.get(url=url).text
data = json.loads(data) # 列表
sr_ip_list = []
for i in range(len(data)):
sr_ip_list.append(data[i]['m.ip'])
return sr_ip_list
def get_vm_docker_id(sr):
vm_docker_list = []
for ip in get_vm_name(sr):
cmd = '''ssh %s -o ConnectTimeout=5 -o ConnectionAttempts=3 -o PasswordAuthentication=no -o StrictHostKeyChecking=no docker ps |grep %s |awk '{print $1}' ''' % (
ip, sr)
docker_id = os.popen(cmd).readlines()[0].replace('\n', '')
vm_docker_dise = []
vm_docker_dise.append(ip)
vm_docker_dise.append(docker_id)
vm_docker_list.append(vm_docker_dise)
return vm_docker_list
if __name__ == '__main__':
sr = 'redline-perf.LogWorker'
rds_id = sys.argv[1]
for docker_id in get_vm_docker_id(sr):
cmd = '''ssh %s docker exec -i %s ifconfig|grep inet|grep broadcast|awk '{print $2}' ''' % (docker_id[0],docker_id[1])
ip = os.popen(cmd).readlines()[0].replace('\n', '')
#curl -L "http://127.0.0.1:8080/v1/api/log/auditlog/detail?dbType=mysql&identityLogGroup=rm-9uryw9o566n148lc4&pageCount=1&pageSize=30&reverseOrderQuery=true"
url = "http://{}:8080/v1/api/log/auditlog/detail?dbType=mysql&identityLogGroup={}&pageCount=1&pageSize=30&reverseOrderQuery=true".format(ip,rds_id)
data = json.loads(requests.get(url).text)
keys = data[0].keys()
key_list = list(keys)
if 'success' in key_list:
print '\033[91m服务:{}ip信息:{},sql审计功能服务异常,需要排查app.log日志\033[0m'.format(sr,docker_id[0])
else:
print '\033[92m服务:{}ip信息:{}sql审计功能服务正常\033[0m'.format(sr,docker_id[0])
+10
View File
@@ -0,0 +1,10 @@
perf链路积压巡检
/home/tops/bin/python /apsarapangu/shujuku/001_zongbu_jiaoben_shell_python/check_perf/check_perf_jiya.py
perf性能监控巡检,rds需要随机写一个
/home/tops/bin/python /apsarapangu/shujuku/001_zongbu_jiaoben_shell_python/check_perf/check_perf_jiankong.py rm-9uryw9o566n148lc4
# 查看每个logwork节点处理sql数据量
go_sr exec redline-perf.PerfMaster "grep -E 'MASTER_INFO_LOG|TOTAL_DATASIZE_PER_TICK_TOK' /home/admin/redline-perf/log/master.log"
#log审计(全部节点)
curl -L "http://127.0.0.1:8080/v1/api/log/auditlog/detail?dbType=mysql&identityLogGroup=rm-9uryw9o566n148lc4&pageCount=1&pageSize=30&reverseOrderQuery=true"
#慢sql信息(一个节点)
curl -L "http://127.0.0.1:8080/v2/api/log/slowlog/detail?dbType=mysql&insName=rm-9uryw9o566n148lc4&pageCount=1&pageSize=30&reverseOrderQuery=true&currentPage=1"
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/5/28 14:12
# @Author : cmk
# @File : Class_db.py
import MySQLdb
class MySQL:
def __init__(self, host,port, user, password, database):
self.host = host
self.port = port
self.user = user
self.password = password
self.database = database
self.conn = None
self.cursor = None
def connect(self):
self.conn = MySQLdb.connect(host=self.host,port=self.port,user=self.user,passwd=self.password,db=self.database)
self.cursor = self.conn.cursor()
print "Login %s successful!"%self.database
def commit(self): #提交事务
self.conn.commit()
def rollback(self): #回滚事务
self.conn.rollback()
def close(self): # 关闭数据库连接和游标
if self.conn:
self.conn.close()
print "Connection closed."
#简单的sql,不存在传参,直接查询
def select(self,sql):
self.connect()
print sql
self.cursor.execute(sql)
self.close()
return self.cursor.fetchall()
# insert
def add_delete_inster(self,sql):
self.connect()
print sql
self.cursor.execute(sql)
self.commit()
print 'Execution insert successful!'
self.close()
# insert表的列比较长的
def insert_json(self,table,data):
self.connect()
keys = ', '.join(data.keys())
values = ', '.join(['"{}"'.format(k) for k in data.values()])
sql = 'insert into %s(%s) values(%s)' %(table,keys,values)
print sql
self.cursor.execute(sql)
self.commit()
print 'Execution insert_json successful!'
self.close()
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/6/12 10:32
# @Author : cmk
# @File : db_dwphoenix.py
import datetime
import json
import requests
import Class_db
from time import sleep
import put_sms
url = "http://localhost:7070/api/v3/column/service.res.result,service.res.serverrole?service.res.type=db&service.res.name={}".format('dwphoenix');
data = requests.get(url=url).text
data_all = json.loads(data)[0].get('service.res.result')
data_all = json.loads(data_all)
host = data_all.get('db_host')
port = int(data_all.get('db_port'))
user = data_all.get('db_user')
password = data_all.get('db_password')
database = data_all.get('dbName')
now = datetime.datetime.now()
date = now.strftime('%Y-%m-%d')
db = Class_db.MySQL(host=host,port=port,user=user,password=password,database=database)
#sql_phoenix_task_transfer_flow = 'select gmt_create,stage from phoenix_task_transfer_flow where gmt_create like "2024-06-11%" order by id desc limit 1'
sql_phoenix_task_transfer_flow = 'select gmt_create,stage from phoenix_task_transfer_flow where gmt_create like "{}%" order by id desc limit 1'.format(date)
sql_phoenix_task_inst = 'select bizdate,count(1) from phoenix_task_inst where dag_type = 0 and bizdate > current_date - 2 group by bizdate'
count = 0
while count < 60:
data_phoenix_task_transfer_flow = db.select(sql_phoenix_task_transfer_flow)
#if len(data_phoenix_task_transfer_flow[0]) >=2:
if data_phoenix_task_transfer_flow[0][1] == 70:
data_phoenix_task_inst = db.select(sql_phoenix_task_inst)
mes = '转实例stage时间:{}\n转实例stage状态:{}\n昨日转实例数量:{}-{}\n今日转实例数量:{}-{}'.format(data_phoenix_task_transfer_flow[0][0],data_phoenix_task_transfer_flow[0][1],data_phoenix_task_inst[0][0],data_phoenix_task_inst[0][1],data_phoenix_task_inst[1][0],data_phoenix_task_inst[1][1])
print mes
put_sms.SLS_PORT('13552923180',mes).sms()
break
count+=1
sleep(60)
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/6/12 9:19
# @Author : cmk
# @File : put_sms.py
import requests
import json
class SLS_PORT:
def __init__(self,phone,manages):
self.phone = phone
self.manages = manages
def sms(self):
headers = {
'User-Agent': 'Apipost client Runtime/+https://www.apipost.cn/',
'Content-Type': 'application/json',
}
params = (
('token', 'DiEmKwjle8ZXI3V4zAn1cyRq0s2CdbhN'),
)
data = {"flag": "test", "text": self.manages, "phone": self.phone}
# ecs接口
#res = requests.post('http://26.0.3.55:15000/app/slsNotify/', headers=headers, params=params,data=json.dumps(data))
# 物理机接口http:20.1.60.195:34982
res = requests.post('http://20.1.60.195:34982/app/slsNotify/', headers=headers, params=params,data=json.dumps(data))
return res.text
+168
View File
@@ -0,0 +1,168 @@
import sys,time,os,base64
from pywinauto.application import Application
import ddddocr
from selenium import webdriver
from selenium.webdriver.common.by import By
import hmac, base64, struct, hashlib
from PIL import Image
url = 'https://bastionhost.res.sgmc.sgcc.com.cn/index.php/login'
username = "chengmingkun"#设置堡垒机账号
#password = 'AliOS%1688' #上一次 2
#password = '1234sheng!WSS' #最近一次 3
#password = '123sheng!WSS' 1
#FortressSecret = "C4L2SFCFLSCPQPEC6LVN6D3PTTCUZKMB" #堡垒机口令秘钥
password = 'Admin@123'
FortressSecret = "YHETDNUGNRO323Z6XQDQVJMQ4JMEYYS5"
search_host = "20.1.216.139" #设置主机运维中搜素ip,如果为空则跳过搜索
#"20.1.216.139"
SHUTDOWN_TIME = 600 #设置堡垒机页面保留时间
#设置chromedriver路径
if os.path.exists(os.path.join(os.path.join(os.environ["HOMEPATH"],"Desktop"),"chromedriver.exe")):
webdriverpath = os.path.join(os.path.join(os.environ["HOMEPATH"],"Desktop"),"chromedriver.exe")
else:
webdriverpath = os.path.join(sys.exec_prefix + '\\lib','chromedriver.exe')
def calGoogleCode(secretKey):
input = int(time.time()) // 30
key = base64.b32decode(secretKey)
msg = struct.pack(">Q", input)
googleCode = hmac.new(key, msg, hashlib.sha1).digest()
# 版本判断
if (sys.version_info > (2, 7)):
o = googleCode[19] & 15
else:
o = ord(googleCode[19]) & 15
googleCode = str((struct.unpack(">I", googleCode[o:o + 4])[0] & 0x7fffffff) % 1000000)
if len(googleCode) == 5: # 如果验证码的第一位是0,则不会显示。此处判断若是5位码,则在第一位补上0
googleCode = '0' + googleCode
return googleCode
class Login_Agent():
def __init__(self,url,username,password):
self.url = url
self.username = username
self.password = password
opt = webdriver.ChromeOptions() # 创建浏览
opt.add_argument('--ignore-certificate-errors')
opt.add_argument('--disable-extensions')
opt.add_argument('--disable-web-security')
opt.add_argument('--all-running-insecure-content')
opt.add_experimental_option("excludeSwitches", ["enable-automation"]) # 隐藏浏览器会有“Chrome提示受到自动软件控制”的提示
opt.add_experimental_option('useAutomationExtension', False)
opt.add_experimental_option('detach', True)
caps = opt.to_capabilities()
caps['goog:chromeOptions'] = {'agrs': ['--disable-features=CrossSiteDocumentNlockingIfIsolating']}
# 不自动关闭浏览器
self.driver = webdriver.Chrome(webdriverpath, options=opt) # 创建浏览器对象
def login_run(self):
self.driver.get(self.url) # 打开网页0
self.driver.maximize_window()#最大化浏览器页面
if "密码" in self.driver.find_element(By.XPATH, r'//*[@id="sign-box"]/ul').text:
self.driver.find_element(By.ID, "pwd_username").send_keys(self.username)#输入账号
self.driver.find_element(By.ID, "pwd_pwd").send_keys(self.password)#输入密码
self.img_path = r'//*[@id="sign-box"]/form[1]/div[3]/div/div/img'
self.yzm = 'pwd_captcha'
self.login = r'//*[@id="sign-box"]/form[1]/div[4]/button'
else:
self.driver.find_element(By.XPATH, r'//*[@id="sign-box"]/ul/li[2]').click()#切换为手机口令页面
self.driver.find_element(By.LINK_TEXT, '手机APP口令').click()#切换为手机口令页面
self.driver.find_element(By.ID, "ga_username").send_keys(self.username)#输入账号
self.driver.find_element(By.ID, "ga_pwd").send_keys(self.password)#输入密码
self.driver.find_element(By.ID, "ga_totp").send_keys(calGoogleCode(FortressSecret))#输入口令
self.img_path = r'//*[@id="sign-box"]/form[5]/div[4]/div/div/img'
self.yzm = 'ga_captcha'
self.login = r'//*[@id="sign-box"]/form[5]/div[5]/button'
#刷新一下验证码,第一次获取验证码无法登录
self.driver.find_element(By.XPATH, self.img_path).click()
self.image_code()#解析图片验证码
for i in range(6):#循环5次,判断验证码是否正确,如果验证码错误,重新调用image_code()
time.sleep(0.1)
try:
if self.driver.find_element(By.XPATH, r'//*[@id="sign-box"]/div[2]/span').text == "验证码错误":
self.image_code()
elif self.driver.find_element(By.XPATH, r'//*[@id="sign-box"]/div[2]/span').text == "动态口令错误":
self.driver.find_element(By.ID, "ga_pwd").send_keys(self.password)#输入密码
self.driver.find_element(By.ID, "ga_totp").send_keys(calGoogleCode(FortressSecret))#输入口令
self.image_code()
else:
break
except Exception as e:
pass
time.sleep(0.2)
try:#防止遇到登录成功,但是需要强制修改密码
self.driver.find_element(By.XPATH, r'/html/body/div/div[2]/div[1]/ul/li[3]/a/i').click()#点击运维菜单
os.remove("web_screen.png")
os.remove("checkcode.png")
except Exception as e:
print(e)
sys.exit(1)#//*[@id="table-om-asset"]/tbody/tr[1]/td[5]/select
#//*[@id="table-om-asset"]/tbody/tr[1]/td[5]/select
self.driver.find_element(By.XPATH, r'/html/body/div/div[2]/div[1]/ul/li[3]/ul/li[1]/a').click()#点击运维下主机运维菜单
if search_host: # 如果存在ip则搜索列表
time.sleep(0.5)
self.search_host()
user_root = self.driver.find_element(By.XPATH, r'//*[@id="table-om-asset"]/tbody/tr[1]/td[5]/select')
if "opsae" not in user_root.text.splitlines()[0]:#判断账号是否是root
self.driver.find_element(By.XPATH, r'//*[@id="table-om-asset"]/tbody/tr[1]/td[5]/select').click() #如果不是root,点击切换为root
self.driver.find_element(By.XPATH, r'//*[@id="table-om-asset"]/tbody/tr[1]/td[5]/select/option[2]').click()
#self.driver.find_element(By.XPATH, r'//*[@id="table-om-asset"]/tbody/tr[1]/td[6]/div/i').click() #点击登录xshell
self.driver.find_element(By.XPATH, r'//*[@id="table-om-asset"]/tbody/tr[1]/td[6]/div/i').click() #点击登录xshell
xshell_auto()
time.sleep(SHUTDOWN_TIME)
self.driver.quit()
def image_code(self):
time.sleep(0.18)
self.driver.save_screenshot("web_screen.png")
page_snap_obj = Image.open("web_screen.png")
img = self.driver.find_element(By.XPATH, self.img_path)
location = img.location
size = img.size
left = location['x']
top = location['y']
right = left + size['width']
bottom = top + size['height']
image_obj = page_snap_obj.crop((left,top,right,bottom))
img_code = image_obj.save('checkcode.png')
with open("checkcode.png","rb") as file_jpg:
f_res = file_jpg.read()
ocr = ddddocr.DdddOcr(show_ad=False)
res = ocr.classification(f_res)
if len(res) != 4:
self.driver.find_element(By.XPATH, self.img_path).click() #如果识别验证码不足4位,则重新刷新验证码
self.image_code()
#time.sleep(0.1)
else:
self.driver.find_element(By.ID, self.yzm).send_keys(res) #输入验证码
#self.driver.find_element(By.LINK_TEXT, '验证码').send_keys(res) #输入验证码
#time.sleep(0.1)
self.driver.find_element(By.XPATH, self.login).click() #登录按钮
def search_host(self):
self.driver.find_element(By.XPATH, r'//*[@id="filter-search"]/form/div/div[2]/input').send_keys(search_host) #搜索列表
print(search_host)
#time.sleep(0.5)
self.driver.find_element(By.XPATH, r'//*[@id="filter-search"]/form/div/div[2]/button/i').click() #点击搜索
def xshell_auto():#except测试时使用,正常走的是try
try:
app = Application('uia').connect(title = r'要打开 USM Single Sign-On Plugin 吗?')
dig = app[r'要打开 USM Single Sign-On Plugin 吗?'].window(title="打开 USM Single Sign-On Plugin", control_type="Button")
except:
app = Application('uia').connect(title = r'主机运维 - Google Chrome')#连接浏览器
dig = app[r'主机运维 - Google Chrome'] #定位到浏览器页面
time.sleep(1.8)
dig.wait("visible").click()
try:#有时候可能会卡住,导致wait无法点击,此方法兜底
time.sleep(1.8)
app = Application('uia').connect(title = r'要打开 USM Single Sign-On Plugin 吗?')
dig = app[r'要打开 USM Single Sign-On Plugin 吗?']
dig.child_window(title="打开 USM Single Sign-On Plugin", control_type="Button").click()
except Exception as e:
print(e)
if __name__ == "__main__":
Login_Agent(url,username,password).login_run()
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023/7/29 23:27
# @Author : cmk
# @File : __init__.py.py
# @Email : 15726649712@163.com
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023/7/28 13:21
# @Author : cmk
# @File : check_db_host.py
import os
import datetime
import random
now = datetime.datetime.now()
date = now.strftime("%Y%m%d")
os.system('chattr -a /u01/shenjilog/Command_history.log')
os.system('mv /u01/shenjilog/Command_history.log /u01/shenjilog/Command_history.log_{}'.format(date))
os.system('touch /u01/shenjilog/Command_history.log')
os.system('chmod 777 /u01/shenjilog/Command_history.log&&chattr +a /u01/shenjilog/Command_history.log')
os.system('find /u01/shenjilog/ -name "Command_history" -mtime +1 -exec rm -rf {} \;')
file = '/u01/shenjilog/Command_history.log_{}'.format(date)
host = '127.0.0.1'
with open(file, 'r') as f:
data = f.readlines()
for i in range(len(data)):
data_list = data[i].split('#')
if int(len(data_list)) < 2:
continue
else:
print(data_list)
date = data_list[0]
user = data_list[1].split(':')[-1]
ip = data_list[2].split(':')[-1].split(' ')[0]
cmd = data_list[3].split(']')[-1]
sql = "insert into check_minirds_host VALUES ('{}','{}','{}','{}','{}')".format(host,date,user,ip,cmd)
os.system('mysql -h152.136.143.185 -ucmk -P3306 -pAdmin@123 -Dzhiban -e "{}"'.format(sql))
+7
View File
@@ -0,0 +1,7 @@
date=`date +"%Y%m%d"`
chattr -a /u01/shenjilog/Command_history.log
mv /u01/shenjilog/Command_history.log /u01/shenjilog/Command_history.log_$date
touch /u01/shenjilog/Command_history.log
chmod 777 /u01/shenjilog/Command_history.log
chattr +a /u01/shenjilog/Command_history.log
find /u01/shenjilog/ -name 'Command_history' -mtime +1 -exec rm -rf {} \;
+3
View File
@@ -0,0 +1,3 @@
#记录历史命令
export HISTORY_FILE="/u01/shenjilog/Command_history.log"
export PROMPT_COMMAND='{ date "+%Y-%m-%d %T # USER:$USER # IP:$SSH_CLIENT # $(history 1 | { read x cmd;echo "$cmd"; })";} >>$HISTORY_FILE'
+6
View File
@@ -0,0 +1,6 @@
# 脚本目录说明
- check_minirds_bak.py :minirds备份巡检,连续5天没有备份集提示异常
- check_minirds_instance_performance.py : minirds性能巡检,cpu,内存,连接数,iops,磁盘
- utils: 公共模块,主要存放一些公共模块。
- get_db: 获取云平台数据库连接信息
+211
View File
@@ -0,0 +1,211 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/10/29 下午12:08
# File : check_bakowner_status.py
# 脚本作用 : 风险-检查服务状态
# 项目名称 : 阿里云平台
# ------------------------------------
import os
import json
import requests
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_bakowner_bak')
type_list = [
{
"name": "ftp",
"type": 23
},
{
"name": "aurora-cluster",
"type": 3
},
{
"name": "task-dispatcher",
"type": 6
},
{
"name": "stat-jobworker",
"type": 7
},
{
"name": "stat-jobworker",
"type": 59
},
{
"name": "stat-jobworker",
"type": 60
},
{
"name": "api",
"type": 9
},
{
"name": "redis",
"type": 24
},
{
"name": "redis",
"type": 61
},
{
"name": "stat-jobschedule",
"type": 35
},
{
"name": "bak-master",
"type": 37
},
{
"name": "bak-master",
"type": 28
},
{
"name": "message-center",
"type": 39
},
{
"name": "tengine",
"type": 57
},
{
"name": "resmanager",
"type": 96
},
{
"name": "check-ins",
"type": 101
},
{
"name": "secgroup",
"type": 115
},
{
"name": "bifrost",
"type": 117
},
{
"name": "bifrost",
"type": 118
},
{
"name": "robot",
"type": 128
},
{
"name": "dboss",
"type": 187
},
{
"name": "pengine-master",
"type": 200
},
{
"name": "pengine-mysql",
"type": 260
},
{
"name": "pengine-tsdb",
"type": 261
},
{
"name": "pengine-mongodb",
"type": 3717
},
{
"name": "pengine-redis",
"type": 6379
},
{
"name": "bakapi",
"type": 222
},
{
"name": "backend_location",
"type": 126
},
{
"name": "tender-api",
"type": 306
},
{
"name": "name-service",
"type": 999
}
]
# 获取集群和服务
def get_project_clusterlist():
'''
{
u'integrator-B-20220325-2c26': {'services': set([u'minirds-integrator']), 'idc': u'am28'},
u'maotai_7u-A-20191123-1ecc': {'services': set([u'minirds-maotai', u'minirds-portal', u'srs-client']), 'idc': u'am779'},
u'maotai_7u-B-20220325-2c25': {'services': set([u'minirds-maotai', u'minirds-portal', u'srs-client']), 'idc': u'am28'},
u'integrator-A-20191123-1ecd': {'services': set([u'minirds-integrator']), 'idc': u'am779'}
}
'''
url= 'http://127.0.0.1:7070/api/v3/column/m.cluster,m.sr.id,m.idc?m.project=minirds-mt'
res = requests.get(url)
c_map = {}
for c in res.json():
if not c.get("m.sr.id") or c['m.sr.id'].startswith("tianji") or c['m.sr.id'].startswith('hids-client'):
continue
service_name = c['m.sr.id'].split('.')[0]
c_map.setdefault(c['m.cluster'], {}).setdefault("idc", c['m.idc'])
c_map.setdefault(c['m.cluster'], {}).setdefault("services", set()).add(service_name)
return c_map
# 获取集群服务和服务实际ip
def get_service_res_info(cluster_name, service_name):
res_map = {}
url = 'http://localhost:7070/api/v5/GetClusterSRInfo?cluster=%s&serverrole=%s&attr=service_registration' % (cluster_name, service_name)
res = requests.get(url)
data = res.json()
if data and 'data' in data.keys() and 'service_registration' in data['data']:
for name, value in json.loads(data['data']['service_registration']).iteritems():
if name.endswith("_iplist") and 'iplist' in name:
res_map.setdefault(name, value)
return res_map
#
def bakowner_status():
check_state = True
err_tip = ""
all_sr_info = {}
sql_db = db('dbaas_db')
clusterlist = get_project_clusterlist()
for cluster, service in clusterlist.items():
a = get_service_res_info(cluster, list(service.get("services"))[0])
all_sr_info.update(a)
for sr in type_list:
for sr_info in all_sr_info:
if sr.get("name") in sr_info:
ip_tmp = all_sr_info.get(sr_info).split(",")
ip_list = ['"{}"'.format(ip) for ip in ip_tmp]
ip_addr = ",".join(ip_list)
sql = "select ip,status from bakowner where type=%s and ip in (%s)" % (sr.get("type"), ip_addr)
cmd = "{} -Ne '{}'".format(sql_db, sql)
datas = os.popen(cmd).readlines()
data_list = [data.strip().split('\t') for data in datas]
for data in data_list:
if data[1] == '1':
check_state = False
print(sr.get('name'),sr.get('type'),data[0],data[1])
log.error('\033[31m服务:{}ip地址:{},类型:{},状态:{},异常\033[0m'.format(sr.get('name'),data[0],sr.get('type'),data[1]))
err_tip += '服务:{}ip地址:{},类型:{},状态:{}\n'.format(sr.get('name'),data[0],sr.get('type'),data[1])
else:
log.info('\033[42m服务:{}ip地址:{},类型:{},状态:{},正常\033[0m'.format(sr.get('name'),data[0],sr.get('type'),data[1]))
str_separator()
return check_state, err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
main(bakowner_status())
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午2:28
# File : check_minirds_bak.py
# 脚本作用 : 检查minirds实例备份是否存在异常:连续5天没有备份的情况
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_minirds_bak')
#获取实例备份异常
def get_bak_data(DB):
log.info('开始实例备份异常巡检...........')
sql_db = db(DB)
log.debug('数据库的连接:{}'.format(sql_db))
sql = '''select * from m_baknotice_custins'''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.info('开始执行sql命令获取数据.....')
data = os.popen(cmd).readlines()
check_state = True
err_tip = []
if len(data) == 0:
log.info('平台没有实例超过5天没有备份的')
else:
check_state = False
err_tip = ""
for line in data:
files = line.strip().split('\t')
log.error('实例:{}备份异常,最后一次备份失败时间是{},连续5天没有备份'.format(files[2],files[4]))
err_tip += '实例:{}备份异常\n'.format(files[2])
log.info('实例备份异常巡检完成,开始分析...........')
str_separator()
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
#检查备份异常
main(get_bak_data('dukang_db'))
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/6 下午5:58
# File : check_minirds_cluster.py
# 脚本作用 : 检查minirds集群信息,判断集群内存分配率小于80%
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_minirds_cluster')
'''
集群实例全是空的情况下资源使用率报错
'''
#获取集群信息
def get_cluster_name(DB):
sql_db = db(DB)
log.debug('数据库的连接:{}'.format(sql_db))
sql = '''
select hi.cluster_name,hi.db_type,count(hi.ip) as host_num,sum(hp.cpu_cores-4) as cpu_total,
sum(round(hp.mem_size/1024,2)-30) as 'mem_total',sum(round(hp.data_space_total/1024,2)) as 'disk_data_total'
from hostinfo hi,host_perf hp where hi.status=1 and hi.id = hp.host_id group by cluster_name
'''
cmd = '{} -Ne "{}"'.format(sql_db, sql)
log.debug('需要执行的sql命令:{}'.format(sql))
datas = os.popen(cmd).readlines()
data_list = [data.strip().split('\t') for data in datas]
log.info('获取集群总量资源,预留cpu4核,内存30G:{}'.format(data_list))
return data_list
#通过集群名称获取计算集群资源
def get_cluster_data(DB):
check_state = True
err_tip = ""
cluster_name_lines = get_cluster_name(DB)
for cluster in cluster_name_lines:
log.info('开始获取{}集群集群资源使用量'.format(cluster[0]))
sql = '''
select sum(ins_num),sum(cpu_sold_num),round(sum(mem_sold)),round(sum(disk_sold)) from (
SELECT COUNT(hi.id) AS ins_num,SUM(ist.cpu_cores) AS cpu_sold_num,SUM(ist.mem_size) / 1024 AS 'mem_sold',
SUM(ci.disk_size) / 1024 AS 'disk_sold' FROM instance i,instance_stat ist,cust_instance ci,custins_hostins_rel chr,hostinfo hi WHERE
ist.ins_id = i.id AND i.is_deleted = 0 AND ci.is_deleted = 0 AND i.id = chr.hostins_id AND ci.id = chr.custins_id
AND i.host_id = hi.id AND hi.cluster_name = '{}' GROUP BY hi.id) t
'''.format(cluster[0])
sql_db = db(DB)
cmd = '{} -Ne "{}"'.format(sql_db, sql)
datas = os.popen(cmd).readlines()
log.info('开始分析{}集群信息'.format(cluster[0]))
data_list = [data.strip().split('\t') for data in datas][0]
cluster_data = cluster + data_list
mes = '''数据库集群:{},数据库类型:{},集群机器数量:{},集群实例节点数据:{},集群cpu总量:{},集群cpu售卖量:{},集群内存总量:{}G,集群内存售卖量:{}G,集群磁盘总量:{}G,集群磁盘售卖量:{}G
'''.format(cluster_data[0],cluster_data[1],cluster_data[2],cluster_data[6],cluster_data[3],cluster_data[7],cluster_data[4],cluster_data[8],cluster_data[5],cluster_data[9])
if cluster_data[8] != 'NULL':
f_num = round(float(cluster_data[8]) / float(cluster_data[4]), 2)
if f_num > 0.8:
check_state = False
log.info(mes)
log.error("集群资源紧张,当前分配率是{},内存分配率大于80%".format(f_num))
err_tip += '集群:{},当前分配率是{},内存使用率大于80%\n'.format(cluster_data[0], f_num)
else:
log.info(mes)
else:
log.info('集群:{},当前机器上面没有实例'.format(cluster[0]))
str_separator()
return check_state, err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
main(get_cluster_data('dbaas_db'))
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/6 下午6:01
# File : check_minirds_host.py
# 脚本作用 : 检查minirds物理机分配情况,物理机内存分配率小于80%,磁盘不允许超卖
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_minirds_host')
def get_hosts_data(DB):
check_state = True
err_tip = ""
sql_db = db(DB)
'''
cluster_name:集群,db_type:数据库类型,
isolate_host:主机支持数据库类型(0 查共享1 查独占2 查独享3 查空机器),total:总量,sold:售卖量
instance:主机实例列表,instance_stat:实例状态,cust_instance:实例列表
custins_hostins_rel:用户实例,与主机实例 关系表 (一般1:2)
hostinfo:主机列表,host_perf:主机资源和性能报表
'''
sql = '''
select hi.cluster_name,hi.db_type,hi.ip,hi.host_name,i.isolate_host,count(hi.id) as ins_num,
(hp.cpu_cores-4) as cpu_total,sum(ist.cpu_cores) as cpu_sold,
(round(hp.mem_size/1024,2) - 30) as 'mem_total',round(sum(ist.mem_size)/1024,2) as 'mem_sold',
round(hp.data_space_total/1024,2) as 'disk_data_total',round(sum(ci.disk_size)/1024,2) as 'disk_sold'
from instance i,instance_stat ist,cust_instance ci,custins_hostins_rel chr,hostinfo hi,host_perf hp
where ist.ins_id=i.id and i.is_deleted=0 and ci.is_deleted=0 and i.id =chr.hostins_id
and ci.id=chr.custins_id and i.host_id =hi.id and hi.id=hp.host_id group by hi.id
'''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.info('开始获取机器资源数据......')
datas = os.popen(cmd).readlines()
data_lists = [data.strip().split('\t') for data in datas]
for data_list in data_lists:
#cpu售卖率
cpu = round(float(data_list[7])/float(data_list[6]),2)
#内存售卖率
mem = round(float(data_list[9])/float(data_list[8]),2)
#磁盘售卖率
disk = round(float(data_list[11])/float(data_list[10]),2)
if data_list[4] == '2':
if cpu >0.8:
log.error('主机:{}是独享型机器,cpu分配率是{}%,大于资源总量的80%'.format(data_list[3],cpu*100))
err_tip += '主机:{},cpu分配率大于80%\n'.format(data_list[3])
if mem > 0.8:
log.error('主机:{}是独享型机器,内存分配率是{}%,大于资源总量的80%'.format(data_list[3],mem*100))
err_tip += '主机:{},内存分配率大于80%\n'.format(data_list[3])
if disk > 1:
log.error('主机:{}是独享型机器,磁盘分配率是{},超卖了'.format(data_list[3],disk*100))
err_tip += '主机:{},磁盘超卖了\n'.format(data_list[3])
elif data_list[4] == '0':
if mem > 0.8:
log.error('主机:{}是共享型机器,内存分配率是{}%,大于资源总量的80%'.format(data_list[3],mem*100))
err_tip += '主机:{},内存分配率大于80%\n'.format(data_list[3])
if disk > 1:
log.error('主机:{}是共享型机器,磁盘分配率是{}%,超卖了'.format(data_list[3],disk*100))
err_tip += '主机:{},磁盘超卖了\n'.format(data_list[3])
str_separator()
if len(err_tip):
check_state = False
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
main(get_hosts_data('dbaas_db'))
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/27 下午3:07
# File : check_minirds_ins_dr.py
# 脚本作用 : 检查环境是否是容灾环境,数据库是否符合容灾逻辑(主备实例在不通的机房)
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_ins_dr')
#检查容灾环境主备实例是否在同一机房
def get_bak_data(DB):
sql_db = db(DB)
sql = '''select ins_name,master_site_name from dr_service_instance_check where single_site = 1 and custins_id in (select id from cust_instance where cluster_name in (select clustername from clusters where is_multi_site = 1));
'''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.info('开始执行sql命令获取数据.....')
check_state = True
err_tip = ""
data = os.popen(cmd).readlines()
if len(data) >0:
check_state = False
for lines in data:
line = lines.strip().split('\t')
log.debug('{}:实例不符合容灾逻辑,主备实例都在{}机房'.format(line[0],line[1]))
err_tip += '{}实例主备节点都在{}机房\n'.format(line[0],line[1])
else:
log.info('环境里面的容灾实例主备节点符合容灾要求')
str_separator()
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
#检查备份异常
main(get_bak_data('dbaas_db'))
@@ -0,0 +1,74 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/21 下午4:05
# File : check_minirds_instance_performance.py
# 脚本作用 : minirds实例性能巡检
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_minirds_instance_performance')
#获取数据
def get_minirds_data(file):
sql = '''select ins_name,cpu_ratio,mem_ratio,iops_ratio,conn_ratio,slave_lag,disk_ratio from instance_list_page'''
log.info("需要执行的sql:{}".format(sql))
sql_db = main('dukang_db')
log.info("开始获取数据....")
cmd = "{} -Ne '{}' >{}".format(sql_db, sql,file)
log.info("数据获取完成,保存到当前目录{}文件中".format(file))
os.system(cmd)
cpu_list = []
mem_list = []
iops_list = []
conn_list = []
slave_list = []
disk_list = []
with open(file,'r') as f:
lines = f.readlines()
log.info('开始分析数据......')
for line in lines:
pages = line.strip().split()
if float(pages[1]) > float(80):
cpu_list.append({pages[0]:pages[1]})
if float(pages[2]) > float(80):
mem_list.append({pages[0]:pages[2]})
if float(pages[3]) > float(90):
iops_list.append({pages[0]:pages[3]})
if float(pages[4]) > float(80):
conn_list.append({pages[0]:pages[4]})
if float(pages[5]) > float(100):
slave_list.append({pages[0]:pages[5]})
if float(pages[6]) > float(100):
disk_list.append({pages[0]:pages[6]})
data = {
'cpu':cpu_list,
'mem':mem_list,
'iops':iops_list,
'conn':conn_list,
'slave':slave_list,
'disk':disk_list
}
str_separator()
return data
#判断列表长度,确认巡检结果
def return_data():
data = get_minirds_data('check_minirds.txt')
for i in data:
if len(data.get(i)) == 0:
print('minirds性能巡检{}通过'.format(i))
json_print(success_msg())
else:
mes = 'minirds性能巡检{}不通过,异常实例和当前的性能数据如下:{}'.format(i,data.get(i))
json_print(error_msg(mes))
str_separator()
if __name__ == "__main__":
return_data()
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/6 下午5:55
# File : check_minirds_task.py
# 脚本作用 : 检查minirds是否存在中断任务
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_rds')
#获取rds任务运行失败的数据
def get_task_data(DB):
sql_db = db(DB)
log.debug('数据库的连接:{}'.format(sql_db))
sql = '''select id,target_id,task_begin,task_end,task_key,action from task_queue where status = '8' '''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.debug('需要执行的sql命令:{}'.format(sql))
log.info('开始执行sql命令获取数据.....')
data = os.popen(cmd).readlines()
check_state = True
err_tip = ""
if len(data) == 0:
log.info('当前平台没有中断任务')
else:
check_state = False
for lines in data:
line = lines.strip().split('\t')
log.error('平台存在中断任务,中断任务id:{},实例id:{},任务开始时间:{},任务中断时间:{},任务类型:{},任务名称:{}'.format(line[0],line[1],line[2],line[3],line[4],line[5]))
err_tip += '平台存在中断任务,实例id:{},任务类型:{},任务名称:{}'.format(line[1],line[4],line[5])
str_separator()
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
#检查任务异常
main(get_task_data('dbaas_db'))
+231
View File
@@ -0,0 +1,231 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午3:02
# File : get_db.py
# 脚本作用 : 获取数据库连接信息
# 项目名称 : 阿里云平台
# ------------------------------------
import sys
import json
import yaml
import base64
import traceback
import subprocess
minirds_db_list = ["bak_db", "dbaas_db", "drds_metadata_db", "dukang_db", "perf_db", "rds_perf_db", "robot_db"]
def exec_client(cmd, ip=None):
if ip:
cmd = """ssh -t {} {} """.format(ip, cmd)
p = subprocess.Popen(cmd, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
code, out, err = p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
out.replace("Connection to {} closed.".format(ip), "") # 去除退出提示信息
if code != 0:
raise ValueError(str(err))
return out.strip()
def fuzzy_search_dict(key, data):
""" 模糊搜索字典值 """
return [d for d in data if any(key in v for v in d.values())]
def base64_to_str(bs64):
return base64.b64decode(bs64)
def search_minirds(db_name, data):
_data = json.loads(data)
_db_name = db_name.replace("_db", "")
original_db_name = db_name
db_host = ""
db_port = ""
db_password = ""
db_user = ""
db_name = ""
instance_name = ""
if original_db_name == "drds_metadata_db":
db_host = _data["db_drds_db_host"]
db_port = _data["db_drds_db_port"]
db_password = _data["db_drds_db_password"]
db_user = _data["db_drds_db_user"]
db_name = _data["db_drds_db_name"]
elif original_db_name == "rds_perf_db":
db_host = _data["db_rdsperf_db_host"]
db_port = _data["db_rdsperf_db_port"]
db_password = _data["db_rdsperf_db_password"]
db_user = _data["db_rdsperf_db_user"]
db_name = _data["db_rdsperf_db_name"]
else:
for key, value in _data.items():
if "db_{}_db_host".format(_db_name) == key:
db_host = value
elif "db_{}_db_port".format(_db_name) == key:
db_port = value
elif "db_{}_db_password".format(_db_name) == key:
db_password = value
elif "db_{}_db_user".format(_db_name) == key:
db_user = value
elif "db_{}_db_name".format(_db_name) == key:
db_name = value
elif "db_{}_instance_name".format(_db_name) == key:
instance_name = value
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n',' ')
def search_tianji(data):
_data = json.loads(data)
db_host = _data["minirds.host"]
db_port = _data["minirds.port"]
db_password = _data["minirds.password"]
db_user = _data["minirds.username"]
db_name = _data["minirds.database"]
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n',' ')
def search_ark(data):
_data = json.loads(data)
db_host = _data["db.aiops.host"]
db_port = _data["db.aiops.port"]
db_password = _data["db.aiops.password"]
db_user = _data["db.aiops.user"]
db_name = _data["db.aiops.name"]
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n',' ')
def print_db_connect(data):
try:
if isinstance(data, dict):
sql_str = "mysql -h{db_host} -u{db_user} -p{db_port} -P{db_passwd} -D{db_name}".format(
db_host=data["db_host"],
db_user=data["db_user"],
db_port=data["db_passwd"],
db_passwd=data["db_port"],
db_name=data["db_name"]
)
#print ("{}".format(sql_str))
return sql_str.replace('\n',' ')
except Exception as error:
msg = traceback.format_exc()
print(msg)
def db_resource_api():
api = "http://localhost:7070/api/v3/column/service.res.result,service.res.serverrole?service.res.type=db"
cmd = "curl -s {}".format(api)
out = exec_client(cmd=cmd)
data = json.loads(out)
return data
def get_minirds_db_resource(db_name):
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=minirds-maotai"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_minirds(db_name, register_data)
return _data
def get_tianji_db_resource():
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=tianjimon"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_tianji(register_data)
return _data
def get_ark_db_resource():
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=ark-aiops-datacollector"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_ark(register_data)
return _data
def get_paas_db_resource(db_name):
result = []
if "_" in db_name:
db_name = db_name.replace("_", "-")
cmd = "kubectl get secret -A |grep minirds |grep {} |awk '{{print $1,$2}}' ".format(db_name)
out = exec_client(cmd=cmd)
data = out.split("\n")
if len(data) < 1:
# print("没有找到对应的paas侧元数据库,请确认是否输入正确")
exit(1)
for i in data:
_data = i.split()
result.append({"namespace": _data[0], "name": _data[1]})
return result
def get_paas_db_info(name):
paas_db_resource = get_paas_db_resource(name)
for paas in paas_db_resource:
cmd = "kubectl get secret {} -n {} -oyaml".format(paas["name"], paas["namespace"])
out = exec_client(cmd=cmd)
data = yaml.safe_load(out)
db_host = base64_to_str(data["data"]["db_host"])
db_name = base64_to_str(data["data"]["db_name"])
db_password = base64_to_str(data["data"]["db_password"])
db_port = base64_to_str(data["data"]["db_port"])
db_user = base64_to_str(data["data"]["db_user"])
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n', ' ')
def new_db_resource():
db_resource = []
resource = db_resource_api()
for db in resource:
db_res = json.loads(db["service.res.result"])
db_data = {
"db_user": db_res["db_user"],
"db_host": db_res["db_host"],
"db_port": db_res["db_port"],
"db_name": db_res["db_name"],
"db_passwd": db_res["db_password"]
}
db_resource.append({"db_res": json.dumps(db_data)})
return db_resource
def main(db_name):
db_info = ""
if db_name in minirds_db_list:
db_info = get_minirds_db_resource(db_name)
return db_info
if db_name == "tianjimon0":
db_info = get_tianji_db_resource()
return db_info
if db_name == "aiops":
db_info = get_ark_db_resource()
return db_info
db_data = fuzzy_search_dict(db_name, new_db_resource())
if len(db_data) < 1 and not db_info:
db_info = get_paas_db_info(db_name)
return db_info
for db in db_data:
db_info = print_db_connect(json.loads(db["db_res"]))
return db_info
# if __name__ == "__main__":
# main()
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/10/29 下午4:41
# File : 00test.py
# 脚本作用 :
# 项目名称 : 阿里云平台
# ------------------------------------
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Project: inspectioncode
# @Time: 2024/7/29 16:48
# @File: utils.py
# @Describe:
import json
import logging
import subprocess
from datetime import datetime
def exec_client(cmd, hostname=None, log=None):
if hostname:
cmd = """ssh -t {} {} """.format(hostname, cmd)
p = subprocess.Popen(cmd, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
code, out, err = p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
log.debug("cmd: [{}], out: [{}], err: [{}], code: {}".format(cmd, out.strip(), err, code))
# if code != 0:
# logging.error("[error: {}, out: {}, code: {}]".format(err, out, code))
# exit(code)
return out.strip(), err, code
def logger(name):
"""
所有场景,公共日志入口
:param name:
:return:
"""
# 根据场景,区分日志
log = logging.getLogger(name)
log.setLevel(logging.DEBUG)
fmt_str = '%(asctime)s [%(levelname)2s] [%(filename)s:%(lineno)d:%(funcName)s] %(message)s'
fmt = logging.Formatter(fmt_str)
stream_h = logging.StreamHandler()
stream_h.setFormatter(fmt)
stream_h.setLevel(logging.DEBUG)
log.addHandler(stream_h)
return log
def success_msg():
return {
"message": "success",
"details": {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"code": "200",
"message": "巡检通过"
}
}
def error_msg(msg):
return {
"message": "failed",
"details": {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"code": "500",
"message": msg
}
}
def str_separator():
print("=" * 30)
def json_print(data):
print(json.dumps(data, ensure_ascii=False, indent=2))
+48
View File
@@ -0,0 +1,48 @@
脚本路径: /home/mysql/backup/data/cmk/work/cmk/work_python/rds/check_rds_bak.py
脚本作用: 检查rds实例备份是否存在异常:连续5天没有备份的情况
==============================
{
"message": "failed",
"details": {
"timestamp": "2025-08-01 09:38:41",
"message": "实例:rm-9urk7o461mu83350l备份异常\n实例:rm-9ur951u1ilsy3wqsp备份异常\n实例:rm-9urv0jm29a6ex5u62备份异常\n实例:rm-9ur7164re689awq52备份异常\n实例:rm-9ur95td400406x134备份异常\n实例:rm-9ur9u77v4i73375z2备份异常\n实例:rm-9ure9279601942823备份异常\n实例:rm-9ur0r6kxctwhgk6fp备份异常\n实例:rm-9ur0d3rj7504f2j1p备份异常\n实例:rm-9ur5s851960k552xy备份异常\n实例:rm-9ur4ip58r0f263u4u备份异常\n实例:rm-9ur61h23wazm78l62备份异常\n实例:rm-9urb5o4u4n93mn3b9备份异常\n实例:rm-9ur5y9ep1l65k7jsk备份异常\n实例:rm-9ur3dq9vq0620j31s备份异常\n",
"code": "500"
}
}
脚本路径: /home/mysql/backup/data/cmk/work/cmk/work_python/rds/check_rds_cluster.py
脚本作用: 获取rds集群信息,判断集群内存分配率小于80%
==============================
{
"message": "failed",
"details": {
"timestamp": "2025-08-01 09:38:46",
"message": "集群:cluster-analyticdb30-xk3r8d,当前分配率是0.91,内存使用率大于80%\n集群:cluster-maxscale-xi4rz7,当前分配率是0.89,内存使用率大于80%\n",
"code": "500"
}
}
脚本路径: /home/mysql/backup/data/cmk/work/cmk/work_python/rds/check_rds_host.py
脚本作用: 检查rds物理机分配情况,物理机内存分配率小于80%,磁盘不允许超卖
脚本路径: /home/mysql/backup/data/cmk/work/cmk/work_python/rds/check_rds_ins_disk.py
脚本作用: 检查数据库实例磁盘大小,磁盘使用量小于总量的80%
==============================
{
"message": "failed",
"details": {
"timestamp": "2025-08-01 09:38:47",
"message": "实例id:rm-9ur53114w79grgtkh,实例磁盘使用率80.03\n实例id:rm-9urgnbdeu8og71f2q,实例磁盘使用率80.17\n实例id:rr-9uru3o52w7yrfpbs5,实例磁盘使用率80.36\n实例id:rr-9ure45hk1v1e0d869,实例磁盘使用率81.32\n实例id:rm-9ur46gxx4fs0frc4w,实例磁盘使用率81.70\n实例id:rr-9ur6l3a5kyjhr0qs1,实例磁盘使用率81.86\n实例id:rm-9urb5o4u4n93mn3b9,实例磁盘使用率82.00\n实例id:rr-9urql03m7303yl3u7,实例磁盘使用率82.41\n实例id:rr-9urmm8w58li62sziu,实例磁盘使用率82.71\n实例id:rr-9ur97z6110cczv7o9,实例磁盘使用率82.74\n实例id:rm-9urv6wp8t8i53gezl,实例磁盘使用率82.86\n实例id:rm-9urw0zfa4v41v5if5,实例磁盘使用率82.89\n实例id:rm-9ur1687t7k7789ehj,实例磁盘使用率83.18\n实例id:rm-9urcm2w4l6r9ereqk,实例磁盘使用率83.63\n实例id:rm-9ur04d7yl13e7imhs,实例磁盘使用率83.68\n实例id:rm-9ur9695u1f45i9z0p,实例磁盘使用率83.98\n实例id:rm-9uru5m57vuev517z4,实例磁盘使用率84.04\n实例id:rm-9urqxb52u884s1uyq,实例磁盘使用率84.09\n实例id:rm-9urkm7h98580l7u7k,实例磁盘使用率84.12\n实例id:rm-9ur5y9ep1l65k7jsk,实例磁盘使用率84.45\n实例id:rm-9urbjw4yz324k5l3q,实例磁盘使用率84.46\n实例id:rm-9urqi5dt5h6876u2u,实例磁盘使用率85.07\n实例id:rm-9urji72eo21hr8rb1,实例磁盘使用率85.35\n实例id:rm-9urpb726e6v1gpk9k,实例磁盘使用率85.59\n实例id:rm-9urrgbe12kp6w1d8w,实例磁盘使用率86.82\n实例id:rm-9urrau77a8fwd77vv,实例磁盘使用率87.07\n实例id:rm-9url7zi3nswd8gk2m,实例磁盘使用率88.12\n实例id:rm-9ur888m949y09x935,实例磁盘使用率88.17\n实例id:rm-9ur4l1hktqen8wm76,实例磁盘使用率89.90\n实例id:rm-9ur53guln849ny2z4,实例磁盘使用率89.99\n实例id:rm-9ur386yw8b61ri6ez,实例磁盘使用率90.17\n实例id:rm-9urye4yz7t83as84p,实例磁盘使用率91.96\n实例id:rm-9ury2i0da2m13277y,实例磁盘使用率93.83\n实例id:rm-9urrgelzqxzhr57pe,实例磁盘使用率93.95\n实例id:rm-9ur9x3h625u5a0efr,实例磁盘使用率95.22\n实例id:rm-9ur5s851960k552xy,实例磁盘使用率96.04\n实例id:rm-9ur3316f4hyy20u4s,实例磁盘使用率97.06\n实例id:rm-9ur17h00iy41x2vyb,实例磁盘使用率102.02\n实例id:rm-9urtebuzro7abcwgn,实例磁盘使用率102.36\n",
"code": "500"
}
}
脚本路径: /home/mysql/backup/data/cmk/work/cmk/work_python/rds/check_rds_task.py
脚本作用: 检查rds是否存在中断任务
==============================
{
"message": "success",
"details": {
"timestamp": "2025-08-01 09:38:49",
"message": "巡检通过",
"code": "200"
}
}
脚本路径: /home/mysql/backup/data/cmk/work/cmk/work_python/rds/utils.py
No script description found in /home/mysql/backup/data/cmk/work/cmk/work_python/rds/utils.py.
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午2:59
# File : check_rds_bak.py
# 脚本作用 : 检查rds实例备份是否存在异常:连续5天没有备份的情况
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_rds_bak')
#获取实例备份异常
def get_bak_data():
log.info('开始实例备份异常巡检...........')
sql_db = db('dukang')
log.debug('数据库的连接:{}'.format(sql_db))
sql = '''select * from m_baknotice_custins'''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.debug('需要执行的sql命令:{}'.format(sql))
log.info('开始执行sql命令获取数据.....')
data = os.popen(cmd).readlines()
check_state = True
err_tip = []
if len(data) == 0:
log.info('平台没有实例超过5天没有备份的')
else:
check_state = False
err_tip = ""
for line in data:
files = line.strip().split('\t')
log.error('实例:{}备份异常,最后一次备份失败时间是{},连续5天没有备份'.format(files[2],files[4]))
err_tip += '实例:{}备份异常\n'.format(files[2])
log.info('实例备份异常巡检完成,开始分析...........')
str_separator()
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
#检查备份异常
main(get_bak_data())
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/3 上午10:39
# File : check_rds_cluster.py
# 脚本作用 : 获取rds集群信息,判断集群内存分配率小于80%
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_rds_cluster')
#获取集群信息
def get_cluster_name(DB):
sql_db = db(DB)
log.debug('数据库的连接:{}'.format(sql_db))
sql = '''
select hi.cluster_name,hi.db_type,count(hi.ip) as host_num,sum(hp.cpu_cores-4) as cpu_total,
sum(round(hp.mem_size/1024,2)-30) as 'mem_total',sum(round(hp.data_space_total/1024,2)) as 'disk_data_total'
from hostinfo hi,host_perf hp where hi.status=1 and hi.id = hp.host_id group by cluster_name
'''
cmd = '{} -Ne "{}"'.format(sql_db, sql)
log.debug('需要执行的sql命令:{}'.format(sql))
datas = os.popen(cmd).readlines()
data_list = [data.strip().split('\t') for data in datas]
log.info('获取集群总量资源,预留cpu4核,内存30G:{}'.format(data_list))
return data_list
#通过集群名称获取计算集群资源
def get_cluster_data(DB):
check_state = True
err_tip = ""
cluster_name_lines = get_cluster_name(DB)
for cluster in cluster_name_lines:
log.info('开始获取{}集群集群资源使用量'.format(cluster[0]))
sql = '''
select sum(ins_num),sum(cpu_sold_num),round(sum(mem_sold)),round(sum(disk_sold)) from (
SELECT COUNT(hi.id) AS ins_num,SUM(ist.cpu_cores) AS cpu_sold_num,SUM(ist.mem_size) / 1024 AS 'mem_sold',
SUM(ci.disk_size) / 1024 AS 'disk_sold' FROM instance i,instance_stat ist,cust_instance ci,custins_hostins_rel chr,hostinfo hi WHERE
ist.ins_id = i.id AND i.is_deleted = 0 AND ci.is_deleted = 0 AND i.id = chr.hostins_id AND ci.id = chr.custins_id
AND i.host_id = hi.id AND hi.cluster_name = '{}' GROUP BY hi.id) t
'''.format(cluster[0])
sql_db = db(DB)
cmd = '{} -Ne "{}"'.format(sql_db, sql)
datas = os.popen(cmd).readlines()
log.info('开始分析{}集群信息'.format(cluster[0]))
data_list = [data.strip().split('\t') for data in datas][0]
cluster_data = cluster + data_list
mes = '''数据库集群:{},数据库类型:{},集群机器数量:{},集群实例节点数据:{},集群cpu总量:{},集群cpu售卖量:{},集群内存总量:{}G,集群内存售卖量:{}G,集群磁盘总量:{}G,集群磁盘售卖量:{}G
'''.format(cluster_data[0],cluster_data[1],cluster_data[2],cluster_data[6],cluster_data[3],cluster_data[7],cluster_data[4],cluster_data[8],cluster_data[5],cluster_data[9])
if cluster_data[8] != 'NULL':
f_num = round(float(cluster_data[8]) / float(cluster_data[4]), 2)
if f_num > 0.8:
check_state = False
log.info(mes)
log.error("集群资源紧张,当前分配率是{},内存分配率大于80%".format(f_num))
err_tip += '集群:{},当前分配率是{},内存使用率大于80%\n'.format(cluster_data[0], f_num)
else:
log.info(mes)
str_separator()
return check_state, err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
main(get_cluster_data('dbaas'))
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/4 下午2:43
# File : check_rds_host.py
# 脚本作用 : 检查rds物理机分配情况,物理机内存分配率小于80%,磁盘不允许超卖
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_rds_host')
def get_hosts_data(DB):
check_state = True
err_tip = ""
sql_db = db(DB)
'''
cluster_name:集群,db_type:数据库类型,
isolate_host:主机支持数据库类型(0 查共享1 查独占2 查独享3 查空机器),total:总量,sold:售卖量
instance:主机实例列表,instance_stat:实例状态,cust_instance:实例列表
custins_hostins_rel:用户实例,与主机实例 关系表 (一般1:2)
hostinfo:主机列表,host_perf:主机资源和性能报表
'''
sql = '''
select hi.cluster_name,hi.db_type,hi.ip,hi.host_name,i.isolate_host,count(hi.id) as ins_num,
(hp.cpu_cores-4) as cpu_total,sum(ist.cpu_cores) as cpu_sold,
(round(hp.mem_size/1024,2) - 30) as 'mem_total',round(sum(ist.mem_size)/1024,2) as 'mem_sold',
round(hp.data_space_total/1024,2) as 'disk_data_total',round(sum(ci.disk_size)/1024,2) as 'disk_sold'
from instance i,instance_stat ist,cust_instance ci,custins_hostins_rel chr,hostinfo hi,host_perf hp
where ist.ins_id=i.id and i.is_deleted=0 and ci.is_deleted=0 and i.id =chr.hostins_id
and ci.id=chr.custins_id and i.host_id =hi.id and hi.id=hp.host_id group by hi.id
'''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.info('开始获取机器资源数据......')
datas = os.popen(cmd).readlines()
data_lists = [data.strip().split('\t') for data in datas]
for data_list in data_lists:
#cpu售卖率
cpu = round(float(data_list[7])/float(data_list[6]),2)
#内存售卖率
mem = round(float(data_list[9])/float(data_list[8]),2)
#磁盘售卖率
disk = round(float(data_list[11])/float(data_list[10]),2)
if data_list[4] == '2':
if cpu >0.8:
log.error('主机:{}是独享型机器,cpu分配率是{}%,大于资源总量的80%'.format(data_list[3],cpu*100))
err_tip += '主机:{},cpu分配率大于80%\n'.format(data_list[3])
if mem > 0.8:
log.error('主机:{}是独享型机器,内存分配率是{}%,大于资源总量的80%'.format(data_list[3],mem*100))
err_tip += '主机:{},内存分配率大于80%\n'.format(data_list[3])
if disk > 1:
log.error('主机:{}是独享型机器,磁盘分配率是{},超卖了'.format(data_list[3],disk))
err_tip += '主机:{},磁盘超卖了\n'.format(data_list[3])
elif data_list[4] == '0':
if mem > 0.8:
log.error('主机:{}是共享型机器,内存分配率是{}%,大于资源总量的80%'.format(data_list[3],mem*100))
err_tip += '主机:{},内存分配率大于80%\n'.format(data_list[3])
if disk > 1:
log.error('主机:{}是共享型机器,磁盘分配率是{}%,超卖了'.format(data_list[3],disk))
err_tip += '主机:{},磁盘超卖了\n'.format(data_list[3])
str_separator()
if len(err_tip):
check_state = False
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
main(get_hosts_data('dbaas'))
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/9/6 上午10:14
# File : check_rds_ins_disk.py
# 脚本作用 : 检查数据库实例磁盘大小,磁盘使用量小于总量的80%
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_rds_ins_disk')
def get_ins_disk_data(DB):
check_state = True
err_tip = ""
sql_db = db(DB)
sql = '''select ins_name,disk_ratio from instance_list_page where ins_name not like 'bak%' and db_type='mysql' and disk_ratio >'80';'''
cmd = '{} -Ne "{}"'.format(sql_db, sql)
log.info('开始获取磁盘使用率大于80%的实例......')
datas = os.popen(cmd).readlines()
data_lists = [data.strip().split('\t') for data in datas]
if len(data_lists) > 0:
check_state = False
for data_list in data_lists:
log.error('实例id:{},实例磁盘使用率{},磁盘使用率大于80%'.format(data_list[0], data_list[1]))
err_tip += '实例id:{},实例磁盘使用率{}\n'.format(data_list[0], data_list[1])
str_separator()
return check_state, err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
main(get_ins_disk_data('dukang'))
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午2:59
# File : check_rds_task.py
# 脚本作用 : 检查rds是否存在中断任务
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
log = logger('check_rds')
#获取rds任务运行失败的数据
def get_task_data():
sql_db = db('dbaas')
log.debug('数据库的连接:{}'.format(sql_db))
sql = '''select id,target_id,task_begin,task_end,task_key,action from task_queue where status = '8' '''
cmd = "{} -Ne '{}'".format(sql_db, sql)
log.debug('需要执行的sql命令:{}'.format(sql))
log.info('开始执行sql命令获取数据.....')
data = os.popen(cmd).readlines()
check_state = True
err_tip = ""
if len(data) == 0:
log.info('当前平台没有中断任务')
else:
check_state = False
for lines in data:
line = lines.strip().split('\t')
log.error('平台存在中断任务,中断任务id:{},实例id:{},任务开始时间:{},任务中断时间:{},任务类型:{},任务名称:{}'.format(line[0],line[1],line[2],line[3],line[4],line[5]))
err_tip += '平台存在中断任务,实例id:{},任务类型:{},任务名称:{}'.format(line[1],line[4],line[5])
str_separator()
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
#检查任务异常
main(get_task_data())
+238
View File
@@ -0,0 +1,238 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午3:02
# File : get_db.py
# 脚本作用 : 获取数据库连接信息
# 项目名称 : 阿里云平台
# ------------------------------------
import sys
import json
import yaml
import base64
import traceback
import subprocess
minirds_db_list = ["bak_db", "dbaas_db", "drds_metadata_db", "dukang_db", "perf_db", "rds_perf_db", "robot_db"]
def exec_client(cmd, ip=None):
if ip:
cmd = """ssh -t {} {} """.format(ip, cmd)
p = subprocess.Popen(cmd, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
code, out, err = p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
out.replace("Connection to {} closed.".format(ip), "") # 去除退出提示信息
if code != 0:
raise ValueError(str(err))
return out.strip()
def fuzzy_search_dict(key, data):
""" 模糊搜索字典值 """
return [d for d in data if any(key in v for v in d.values())]
def base64_to_str(bs64):
return base64.b64decode(bs64)
def search_minirds(db_name, data):
_data = json.loads(data)
_db_name = db_name.replace("_db", "")
original_db_name = db_name
db_host = ""
db_port = ""
db_password = ""
db_user = ""
db_name = ""
instance_name = ""
if original_db_name == "drds_metadata_db":
db_host = _data["db_drds_db_host"]
db_port = _data["db_drds_db_port"]
db_password = _data["db_drds_db_password"]
db_user = _data["db_drds_db_user"]
db_name = _data["db_drds_db_name"]
elif original_db_name == "rds_perf_db":
db_host = _data["db_rdsperf_db_host"]
db_port = _data["db_rdsperf_db_port"]
db_password = _data["db_rdsperf_db_password"]
db_user = _data["db_rdsperf_db_user"]
db_name = _data["db_rdsperf_db_name"]
else:
for key, value in _data.items():
if "db_{}_db_host".format(_db_name) == key:
db_host = value
elif "db_{}_db_port".format(_db_name) == key:
db_port = value
elif "db_{}_db_password".format(_db_name) == key:
db_password = value
elif "db_{}_db_user".format(_db_name) == key:
db_user = value
elif "db_{}_db_name".format(_db_name) == key:
db_name = value
elif "db_{}_instance_name".format(_db_name) == key:
instance_name = value
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
return sql_str.replace('\n',' ')
def search_tianji(data):
_data = json.loads(data)
db_host = _data["minirds.host"]
db_port = _data["minirds.port"]
db_password = _data["minirds.password"]
db_user = _data["minirds.username"]
db_name = _data["minirds.database"]
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
return sql_str.replace('\n',' ')
def search_ark(data):
_data = json.loads(data)
db_host = _data["db.aiops.host"]
db_port = _data["db.aiops.port"]
db_password = _data["db.aiops.password"]
db_user = _data["db.aiops.user"]
db_name = _data["db.aiops.name"]
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
return sql_str.replace('\n',' ')
def print_db_connect(data):
try:
if isinstance(data, dict):
sql_str = "mysql -h{db_host} -u{db_user} -p{db_port} -P{db_passwd} -D{db_name}".format(
db_host=data["db_host"],
db_user=data["db_user"],
db_port=data["db_passwd"],
db_passwd=data["db_port"],
db_name=data["db_name"]
)
#print ("{}".format(sql_str))
return sql_str.replace('\n',' ')
except Exception as error:
msg = traceback.format_exc()
print(msg)
def db_resource_api():
'''获取tianji接口上面所有db信息'''
api = "http://localhost:7070/api/v3/column/service.res.result,service.res.serverrole?service.res.type=db"
cmd = "curl -s {}".format(api)
out = exec_client(cmd=cmd)
data = json.loads(out)
return data
def get_minirds_db_resource(db_name):
'''获取minirds源数据库数据'''
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=minirds-maotai"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_minirds(db_name, register_data)
return _data
def get_tianji_db_resource():
'''获取tianjimon数据'''
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=tianjimon"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_tianji(register_data)
return _data
def get_ark_db_resource():
'''获取ark-aiops-datacollector数据库'''
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=ark-aiops-datacollector"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_ark(register_data)
return _data
def get_paas_db_resource(db_name):
'''获取passsecret服务'''
result = []
if "_" in db_name:
db_name = db_name.replace("_", "-")
cmd = "kubectl get secret -A |grep minirds |grep {} |awk '{{print $1,$2}}' ".format(db_name)
out = exec_client(cmd=cmd)
data = out.split("\n")
if len(data) < 1:
# print("没有找到对应的paas侧元数据库,请确认是否输入正确")
exit(1)
for i in data:
_data = i.split()
result.append({"namespace": _data[0], "name": _data[1]})
return result
def get_paas_db_info(name):
'''获取pass侧数据库信息'''
paas_db_resource = get_paas_db_resource(name)
for paas in paas_db_resource:
cmd = "kubectl get secret {} -n {} -oyaml".format(paas["name"], paas["namespace"])
out = exec_client(cmd=cmd)
data = yaml.safe_load(out)
db_host = base64_to_str(data["data"]["db_host"])
db_name = base64_to_str(data["data"]["db_name"])
db_password = base64_to_str(data["data"]["db_password"])
db_port = base64_to_str(data["data"]["db_port"])
db_user = base64_to_str(data["data"]["db_user"])
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
if name == db_name:
return sql_str.replace('\n', ' ')
else:
print(sql_str)
return "没有找到一样的数据库名称,上面可能是你需要的"
def new_db_resource():
db_resource = []
resource = db_resource_api()
for db in resource:
db_res = json.loads(db["service.res.result"])
db_data = {
"db_user": db_res["db_user"],
"db_host": db_res["db_host"],
"db_port": db_res["db_port"],
"db_name": db_res["db_name"],
"db_passwd": db_res["db_password"]
}
db_resource.append({"db_res": json.dumps(db_data)})
return db_resource
def main():
db_name = sys.argv[1]
# def main(db_name):
db_info = ""
if db_name in minirds_db_list:
db_info = get_minirds_db_resource(db_name)
return db_info
if db_name == "tianjimon0":
db_info = get_tianji_db_resource()
return db_info
if db_name == "aiops":
db_info = get_ark_db_resource()
return db_info
db_data = fuzzy_search_dict(db_name, new_db_resource())
if len(db_data) < 1 and not db_info:
db_info = get_paas_db_info(db_name)
return db_info
for db in db_data:
db_info = print_db_connect(json.loads(db["db_res"]))
return db_info
if __name__ == "__main__":
print(main())
+236
View File
@@ -0,0 +1,236 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午3:02
# File : get_db.py
# 脚本作用 : 获取数据库连接信息
# 项目名称 : 阿里云平台
# ------------------------------------
import sys
import json
import yaml
import base64
import traceback
import subprocess
# config = ConfigParser.ConfigParser()
# config.read("/apsarapangu/disk2/lei/cron/conf/app.ini")
# ops_ip = config.get("sys_config", "ops1_ip")
minirds_db_list = ["bak_db", "dbaas_db", "drds_metadata_db", "dukang_db", "perf_db", "rds_perf_db", "robot_db"]
def exec_client(cmd, ip=None):
if ip:
cmd = """ssh -t {} {} """.format(ip, cmd)
p = subprocess.Popen(cmd, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
code, out, err = p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
out.replace("Connection to {} closed.".format(ip), "") # 去除退出提示信息
if code != 0:
raise ValueError(str(err))
return out.strip()
def fuzzy_search_dict(key, data):
""" 模糊搜索字典值 """
return [d for d in data if any(key in v for v in d.values())]
def base64_to_str(bs64):
return base64.b64decode(bs64)
def search_minirds(db_name, data):
_data = json.loads(data)
_db_name = db_name.replace("_db", "")
original_db_name = db_name
db_host = ""
db_port = ""
db_password = ""
db_user = ""
db_name = ""
instance_name = ""
if original_db_name == "drds_metadata_db":
db_host = _data["db_drds_db_host"]
db_port = _data["db_drds_db_port"]
db_password = _data["db_drds_db_password"]
db_user = _data["db_drds_db_user"]
db_name = _data["db_drds_db_name"]
elif original_db_name == "rds_perf_db":
db_host = _data["db_rdsperf_db_host"]
db_port = _data["db_rdsperf_db_port"]
db_password = _data["db_rdsperf_db_password"]
db_user = _data["db_rdsperf_db_user"]
db_name = _data["db_rdsperf_db_name"]
else:
for key, value in _data.items():
if "db_{}_db_host".format(_db_name) == key:
db_host = value
elif "db_{}_db_port".format(_db_name) == key:
db_port = value
elif "db_{}_db_password".format(_db_name) == key:
db_password = value
elif "db_{}_db_user".format(_db_name) == key:
db_user = value
elif "db_{}_db_name".format(_db_name) == key:
db_name = value
elif "db_{}_instance_name".format(_db_name) == key:
instance_name = value
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n',' ')
def search_tianji(data):
_data = json.loads(data)
db_host = _data["minirds.host"]
db_port = _data["minirds.port"]
db_password = _data["minirds.password"]
db_user = _data["minirds.username"]
db_name = _data["minirds.database"]
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n',' ')
def search_ark(data):
_data = json.loads(data)
db_host = _data["db.aiops.host"]
db_port = _data["db.aiops.port"]
db_password = _data["db.aiops.password"]
db_user = _data["db.aiops.user"]
db_name = _data["db.aiops.name"]
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n',' ')
def print_db_connect(data):
try:
if isinstance(data, dict):
sql_str = "mysql -h{db_host} -u{db_user} -p{db_port} -P{db_passwd} -D{db_name}".format(
db_host=data["db_host"],
db_user=data["db_user"],
db_port=data["db_passwd"],
db_passwd=data["db_port"],
db_name=data["db_name"]
)
#print ("{}".format(sql_str))
return sql_str.replace('\n',' ')
except Exception as error:
msg = traceback.format_exc()
print(msg)
def db_resource_api():
api = "http://localhost:7070/api/v3/column/service.res.result,service.res.serverrole?service.res.type=db"
cmd = "curl -s {}".format(api)
out = exec_client(cmd=cmd)
data = json.loads(out)
return data
def get_minirds_db_resource(db_name):
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=minirds-maotai"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_minirds(db_name, register_data)
return _data
def get_tianji_db_resource():
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=tianjimon"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_tianji(register_data)
return _data
def get_ark_db_resource():
api = "http://localhost:7070/api/v3/column/c.sr.service_registration?c.sr.id=ark-aiops-datacollector"
out = exec_client(cmd="curl -s {}".format(api))
data = json.loads(out)
register_data = data[0]["c.sr.service_registration"]
_data = search_ark(register_data)
return _data
def get_paas_db_resource(db_name):
result = []
if "_" in db_name:
db_name = db_name.replace("_", "-")
cmd = "kubectl get secret -A |grep minirds |grep {} |awk '{{print $1,$2}}' ".format(db_name)
out = exec_client(cmd=cmd)
data = out.split("\n")
if len(data) < 1:
# print("没有找到对应的paas侧元数据库,请确认是否输入正确")
exit(1)
for i in data:
_data = i.split()
result.append({"namespace": _data[0], "name": _data[1]})
return result
def get_paas_db_info(name):
paas_db_resource = get_paas_db_resource(name)
for paas in paas_db_resource:
cmd = "kubectl get secret {} -n {} -oyaml".format(paas["name"], paas["namespace"])
out = exec_client(cmd=cmd)
data = yaml.safe_load(out)
db_host = base64_to_str(data["data"]["db_host"])
db_name = base64_to_str(data["data"]["db_name"])
db_password = base64_to_str(data["data"]["db_password"])
db_port = base64_to_str(data["data"]["db_port"])
db_user = base64_to_str(data["data"]["db_user"])
sql_str = "mysql -h{} -u{} -P{} -p{} -D{}".format(db_host, db_user, db_port, db_password, db_name)
#print("{}".format(sql_str))
return sql_str.replace('\n', ' ')
def new_db_resource():
db_resource = []
resource = db_resource_api()
for db in resource:
db_res = json.loads(db["service.res.result"])
db_data = {
"db_user": db_res["db_user"],
"db_host": db_res["db_host"],
"db_port": db_res["db_port"],
"db_name": db_res["db_name"],
"db_passwd": db_res["db_password"]
}
db_resource.append({"db_res": json.dumps(db_data)})
return db_resource
# def main():
# db_name = sys.argv[1]
def main(db_name):
db_info = ""
if db_name in minirds_db_list:
db_info = get_minirds_db_resource(db_name)
return db_info
if db_name == "tianjimon0":
db_info = get_tianji_db_resource()
return db_info
if db_name == "aiops":
db_info = get_ark_db_resource()
return db_info
db_data = fuzzy_search_dict(db_name, new_db_resource())
if len(db_data) < 1 and not db_info:
db_info = get_paas_db_info(db_name)
return db_info
for db in db_data:
db_info = print_db_connect(json.loads(db["db_res"]))
return db_info
# if __name__ == "__main__":
# main()
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------
# Time : 2024/8/28 下午2:59
# File : RDS_P1_BAK.py
# 脚本作用 : 检查rds实例备份是否存在异常:连续5天没有备份的情况
# 项目名称 : 阿里云平台
# ------------------------------------
import os
from get_db import main as db
from utils import logger, success_msg, error_msg, str_separator, json_print
LOG = logger('check_rds_bak') #日志记录器
def get_bak_data():
"""
获取RDS实例备份异常情况
作用: 查询数据库获取RDS实例备份信息,并检查是否存在连续5天无备份的情况。
结果格式:
(CHECK_STATE,ERR_TIP)
结果作用:
CHECK_STATE: 定义的bool值,判断是否存在异常
ERR_TIP: list,异常实例列表
"""
LOG.info('开始实例备份异常巡检...........')
SQL_DB = db('dukang') #获取数据库连接
LOG.debug('数据库的连接:{}'.format(SQL_DB))
GET_BAK_SQL = '''select ins_name from m_baknotice_custins'''
GET_INS_SQL = '''select ins_name from instance_list_page'''
GET_BAK_CMD = "{} -Ne '{}'".format(SQL_DB, GET_BAK_SQL) #需要执行的SQL命令
GET_INS_CMD = "{} -Ne '{}'".format(SQL_DB, GET_INS_SQL) #需要执行的SQL命令
LOG.debug('需要执行的sql命令:{}'.format(GET_BAK_SQL))
LOG.info('开始执行sql命令获取数据.....')
BAK_RES = os.popen(GET_BAK_CMD).readlines() #执行SQL命令并读取结果
INS_RES = os.popen(GET_INS_CMD).readlines() #执行SQL命令并读取结果
RM_INS = [ INS for INS in INS_RES if INS.startswith('rm-')]
RESULT = []
for LINE in RM_INS:
CLEANED_LINE = LINE.strip()
CONTENT = {
"ins": CLEANED_LINE,
"result": "true"
}
RESULT.append(CONTENT)
if BAK_RES:
for INS in BAK_RES:
INS_NAME = INS.strip()
for K in RESULT:
if name == k['ins']:
k['result'] = 'false'
print(RESULT)
get_bak_data()
"""
check_state = True #检查状态,默认为True
RDS_BAK_RESULT = [] #定义保存检查结果的列表
if len(data) == 0:
log.info('平台没有实例超过5天没有备份的')
else:
check_state = False
err_tip = ""
for line in data:
files = line.strip().split('\t')
log.error('实例:{}备份异常,最后一次备份失败时间是{},连续5天没有备份'.format(files[2],files[4]))
err_tip += '实例:{}备份异常\n'.format(files[2])
log.info('实例备份异常巡检完成,开始分析...........')
str_separator()
return check_state,err_tip
def main(data):
if data[0]:
json_print(success_msg())
else:
json_print(error_msg(data[1]))
if __name__ == '__main__':
#检查备份异常
main(get_bak_data())
"""
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
#****************************************************************#
# ScriptName: rds.sh
# Author: $SHTERM_REAL_USER@alibaba-inc.com
# Create Date: 2024-09-06 16:02
# Modify Author: $SHTERM_REAL_USER@alibaba-inc.com
# Modify Date: 2024-09-06 16:02
# Function:
#***************************************************************#
/home/tops/bin/python check_rds_bak.py
/home/tops/bin/python check_rds_cluster.py
/home/tops/bin/python check_rds_host.py
/home/tops/bin/python check_rds_ins_disk.py
/home/tops/bin/python check_rds_task.py
+16
View File
@@ -0,0 +1,16 @@
formatted_time=$(date +"%Y-%m-%d")
log_file="$PWD/check_$formatted_time.log"
for file in $PWD/*; do
if [ -f "$file" ] && [[ "$file" == *.py ]]; then
echo "脚本路径: $file" >> $log_file
# 获取文件内容中的'脚本作用'注释并输出,假设注释格式为 '# 脚本作用:描述内容'
description=$(grep "^# 脚本作用" "$file" | cut -d ':' -f2-)
if [ -n "$description" ]; then
echo "脚本作用:$description" >> $log_file
else
echo "No script description found in $file." >> $log_file
fi
# 执行 Python 文件
/home/tops/bin/python "$file" >>$log_file
fi
done
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Project: inspectioncode
# @Time: 2024/7/29 16:48
# @File: utils.py
# @Describe:
import json
import logging
import subprocess
from datetime import datetime
def exec_client(cmd, hostname=None, log=None):
if hostname:
cmd = """ssh -t {} {} """.format(hostname, cmd)
p = subprocess.Popen(cmd, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
code, out, err = p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
log.debug("cmd: [{}], out: [{}], err: [{}], code: {}".format(cmd, out.strip(), err, code))
# if code != 0:
# logging.error("[error: {}, out: {}, code: {}]".format(err, out, code))
# exit(code)
return out.strip(), err, code
def logger(name):
"""
所有场景,公共日志入口
:param name:
:return:
"""
# 根据场景,区分日志
log = logging.getLogger(name)
log.setLevel(logging.DEBUG)
fmt_str = '%(asctime)s [%(levelname)2s] [%(filename)s:%(lineno)d:%(funcName)s] %(message)s'
fmt = logging.Formatter(fmt_str)
stream_h = logging.StreamHandler()
stream_h.setFormatter(fmt)
stream_h.setLevel(logging.DEBUG)
log.addHandler(stream_h)
return log
def success_msg():
return {
"message": "success",
"details": {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"code": "200",
"message": "巡检通过"
}
}
def error_msg(msg):
return {
"message": "failed",
"details": {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"code": "500",
"message": msg
}
}
def str_separator():
print("=" * 30)
def json_print(data):
print(json.dumps(data, ensure_ascii=False, indent=2))
View File
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/6/27 下午11:05
# @Author : cmk
# @File : test-v2.py
# @Email : 15726649712@163.com
import os
import re
import requests
import datetime
import concurrent.futures
from pathlib import Path
#from tools.SMS_PUT import sms
from tools.Logger import setup_logger
# ---------------------- 配置配置 ----------------------
script_dir = Path(__file__).parent.resolve()
log_path = (script_dir / "logs" / "nc_disk.log").resolve()
project_list = ['minirds-mt', 'rds', 'drds', 'dts']
# 告警阈值配置
DISK_THRESHOLD = 80 # 磁盘使用率阈值(%)
CPU_USAGE_THRESHOLD = 80 # CPU使用率阈值(%)
MEM_USAGE_THRESHOLD = 80 # 内存使用率阈值(%)
LOAD_AVG_THRESHOLD = 1.5 # 系统负载阈值(CPU核心数倍数)
# SSH配置
SSH_CONNECT_TIMEOUT = 3 # SSH连接超时时间(秒)
SSH_RETRIES = 3 # SSH连接重试次数
SSH_RETRY_DELAY = 2 # SSH重试间隔时间(秒)
# ---------------------- 日志配置 ----------------------
log = setup_logger(
logger_name="daily_logger",
log_file=log_path,
backup_count=7
)
# 确保日志目录存在
log_path.parent.mkdir(parents=True, exist_ok=True)
# ---------------------- 工具函数 ----------------------
def mask_ip(real_ip: str) -> str:
"""IP脱敏处理"""
parts = real_ip.split('.')
return f"**.**.{parts[2]}.{parts[3]}" if len(parts) == 4 else real_ip
def get_system_info(host):
"""获取本地系统信息(CPU、内存、负载、磁盘)"""
try:
# 1. 获取磁盘使用率(通过df命令)
df_cmd = "df -h | awk 'NR>1{print $1,$2,$3,$4,$5,$6}'"
disk_cmd = f'ssh {host} {df_cmd}'
disk_output = os.popen(disk_cmd).read().split('\n')
disks = []
for line in disk_output:
if line.strip():
parts = line.strip().split()
if len(parts) >= 6:
disk = {
'filesystem': parts[0],
'size': parts[1],
'used': parts[2],
'available': parts[3],
'percent_used': int(parts[4].replace('%', '')),
'mount_point': parts[5]
}
disks.append(disk)
# 2. 获取CPU使用率(通过top命令)
_top_cmd = "top -bn1 | grep 'Cpu(s)'"
top_cmd = f'ssh {host} {_top_cmd}'
top_output = os.popen(top_cmd).read().strip()
cpu_match = re.search(r'(\d+\.\d+)\%* us', top_output)
cpu_usage = float(cpu_match.group(1)) if cpu_match else 0
# 3. 获取内存使用率(通过free命令)
free_cmd = "free -m | grep Mem"
free_output = os.popen(free_cmd).read().strip()
mem_match = re.search(r'Mem:\s+(\d+)\s+(\d+)\s+(\d+)', free_output)
if mem_match:
total_mem = int(mem_match.group(1))
used_mem = int(mem_match.group(2))
mem_usage = round((used_mem / total_mem) * 100, 2)
else:
mem_usage = 0
# 4. 获取系统负载(通过uptime命令)
uptime_cmd = "uptime"
uptime_output = os.popen(uptime_cmd).read().strip()
load_match = re.search(r'load average:\s+([\d.]+),\s+([\d.]+),\s+([\d.]+)', uptime_output)
load_avg = float(load_match.group(1)) if load_match else 0
# 5. 获取CPU核心数
cpu_cores = 1
try:
cpu_cores_cmd = "grep -c 'processor' /proc/cpuinfo"
cpu_cores_output = os.popen(cpu_cores_cmd).read().strip()
if cpu_cores_output:
match = re.search(r'\d+', cpu_cores_output)
if match:
cpu_cores = int(match.group(0))
log.debug(f"获取到本地CPU核心数: {cpu_cores}")
else:
log.warning(f"无法从输出中提取CPU核心数: {cpu_cores_output}")
# 备选方案:使用nproc命令
nproc_cmd = "nproc || echo 1"
nproc_output = os.popen(nproc_cmd).read().strip()
match = re.search(r'\d+', nproc_output)
if match:
cpu_cores = int(match.group(0))
log.info(f"通过nproc获取到本地CPU核心数: {cpu_cores}")
else:
log.warning(f"获取本地CPU核心数失败,命令无输出")
except Exception as e:
log.error(f"获取本地CPU核心数异常: {str(e)}")
return {
"disks": disks,
"cpu_usage": cpu_usage,
"mem_usage": mem_usage,
"load_avg": load_avg,
"load_avg_compare": load_avg / cpu_cores,
"cpu_cores": cpu_cores
}
except Exception as e:
log.error(f"获取本地系统信息失败: {str(e)}")
raise e
+396
View File
@@ -0,0 +1,396 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/6/9 上午10:27
# @Author : cmk
# @File : test.py
# @Email : 15726649712@163.com
import os
import re
import requests
import datetime
import concurrent.futures
from pathlib import Path
#from tools.SMS_PUT import sms
from tools.Logger import setup_logger
# ---------------------- 配置配置 ----------------------
script_dir = Path(__file__).parent.resolve()
log_path = (script_dir / "logs" / "nc_disk.log").resolve()
project_list = ['minirds-mt', 'rds', 'drds', 'dts']
# 告警阈值配置
DISK_THRESHOLD = 80 # 磁盘使用率阈值(%)
CPU_USAGE_THRESHOLD = 80 # CPU使用率阈值(%)
MEM_USAGE_THRESHOLD = 80 # 内存使用率阈值(%)
LOAD_AVG_THRESHOLD = 1.5 # 系统负载阈值(CPU核心数倍数)
# SSH配置
SSH_CONNECT_TIMEOUT = 3 # SSH连接超时时间(秒)
SSH_RETRIES = 3 # SSH连接重试次数
SSH_RETRY_DELAY = 2 # SSH重试间隔时间(秒)
# ---------------------- 日志配置 ----------------------
log = setup_logger(
logger_name="daily_logger",
log_file=log_path,
backup_count=7
)
# 确保日志目录存在
log_path.parent.mkdir(parents=True, exist_ok=True)
# ---------------------- 工具函数 ----------------------
def mask_ip(real_ip: str) -> str:
"""IP脱敏处理"""
parts = real_ip.split('.')
return f"**.**.{parts[2]}.{parts[3]}" if len(parts) == 4 else real_ip
def retry(func):
"""重试装饰器,用于SSH连接"""
def wrapper(*args, **kwargs):
max_retries = kwargs.pop('max_retries', SSH_RETRIES)
delay = kwargs.pop('delay', SSH_RETRY_DELAY)
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt < max_retries - 1:
log.warning(f"操作失败,尝试重试 ({attempt + 1}/{max_retries}): {str(e)}")
import time
time.sleep(delay)
else:
raise e
return wrapper
@retry
def get_system_info(host, ssh_cmd_prefix=""):
"""获取主机系统信息(CPU、内存、负载)"""
try:
# 1.获取磁盘使用率(通过df命令)
disk_cmd = "df -h | awk 'NR>1{print $1,$2,$3,$4,$5,$6}'"
top_disk = f"{ssh_cmd_prefix} {disk_cmd}"
disk_output = os.popen(f"{top_disk}").read().split('\n')
#for line_num, line in enumerate(disk_output.split('\n'), 1):
# 1. 获取CPU使用率(通过top命令)
top_cmd = f"{ssh_cmd_prefix} top -bn1 | grep 'Cpu(s)'"
top_output = os.popen(top_cmd).read().strip()
cpu_match = re.search(r'(\d+\.\d+)\%* us', top_output)
cpu_usage = float(cpu_match.group(1)) if cpu_match else 0
# 2. 获取内存使用率(通过free命令)
free_cmd = f"{ssh_cmd_prefix} free -m | grep Mem"
free_output = os.popen(free_cmd).read().strip()
mem_match = re.search(r'Mem:\s+(\d+)\s+(\d+)\s+(\d+)', free_output)
if mem_match:
total_mem = int(mem_match.group(1))
used_mem = int(mem_match.group(2))
mem_usage = round((used_mem / total_mem) * 100, 2)
else:
mem_usage = 0
# 3. 获取系统负载(通过uptime命令)
uptime_cmd = f"{ssh_cmd_prefix} uptime"
uptime_output = os.popen(uptime_cmd).read().strip()
load_match = re.search(r'load average:\s+([\d.]+),\s+([\d.]+),\s+([\d.]+)', uptime_output)
load_avg = float(load_match.group(1)) if load_match else 0
# 4. 获取CPU核心数(优化版)
cpu_cores = 1
try:
cpu_cores_cmd = f"{ssh_cmd_prefix} grep -c 'processor' /proc/cpuinfo"
cpu_cores_output = os.popen(cpu_cores_cmd).read().strip()
if cpu_cores_output:
match = re.search(r'\d+', cpu_cores_output)
if match:
cpu_cores = int(match.group(0))
log.debug(f"获取到主机 {host} 的CPU核心数: {cpu_cores}")
else:
log.warning(f"无法从输出中提取CPU核心数: {cpu_cores_output}")
# 备选方案:使用nproc命令
nproc_cmd = f"{ssh_cmd_prefix} nproc || echo 1"
nproc_output = os.popen(nproc_cmd).read().strip()
match = re.search(r'\d+', nproc_output)
if match:
cpu_cores = int(match.group(0))
log.info(f"通过nproc获取到主机 {host} 的CPU核心数: {cpu_cores}")
else:
log.warning(f"获取主机 {host} 的CPU核心数失败,命令无输出")
except Exception as e:
log.error(f"获取主机 {host} 的CPU核心数异常: {str(e)}")
return {
"cpu_usage": cpu_usage,
"mem_usage": mem_usage,
"load_avg": load_avg,
"load_avg_compare": load_avg / cpu_cores,
"cpu_cores": cpu_cores
}
except Exception as e:
log.error(f"获取主机 {host} 系统信息失败: {str(e)}")
raise e # 让重试机制处理异常
# ---------------------- 核心逻辑 ----------------------
def get_nc_hostname(project, get_time):
"""获取平台机器信息(带缓存)"""
url = f'http://127.0.0.1:7070/api/v3/column/m.project,m.ip,m.id'
data = requests.get(url).json()
if not data:
return []
data_list = [i for i in data if 'cloud' in i.get('m.id', '') and i.get('m.project') == project]
log.info(f"[项目:{project}] 获取到 {len(data_list)} 台机器")
return data_list
@retry
def get_disk_info(host_info, get_time, ssh_key_path=None):
"""获取单台主机的磁盘、CPU、内存及负载信息"""
host = host_info['m.id']
project = host_info['m.project']
ip = host_info['m.ip']
cmd_prefix = f"ssh -i {ssh_key_path} -o ConnectTimeout={SSH_CONNECT_TIMEOUT} {host} " if ssh_key_path else f"ssh -o ConnectTimeout={SSH_CONNECT_TIMEOUT} {host} "
try:
# 1. 获取磁盘信息
disk_cmd = "df -h | awk 'NR>1{print $1,$2,$3,$4,$5,$6}'"
disk_output = os.popen(f"{cmd_prefix}{disk_cmd}").read()
disk_info_list = []
for line_num, line in enumerate(disk_output.split('\n'), 1):
line = line.strip()
if not line:
continue
parts = line.split()
if len(parts) < 6:
log.warning(f"[项目:{project}, 主机:{host}] 无效磁盘信息行(行号:{line_num}): {line}")
continue
try:
percent_used = parts[4].strip('%')
if not percent_used.isdigit():
log.warning(f"[项目:{project}, 主机:{host}] 无效使用率: {percent_used}, 行: {line}")
continue
disk_info = {
"project": project,
"host": host,
"ip": mask_ip(ip),
"device": parts[0],
"total": parts[1],
"used": parts[2],
"available": parts[3],
"percent_used": int(percent_used),
"mount_point": parts[5],
"get_time": get_time
}
disk_info_list.append(disk_info)
except Exception as e:
log.error(f"[项目:{project}, 主机:{host}] 解析磁盘信息失败: {str(e)}, 行: {line}")
# 2. 获取系统信息
system_info = get_system_info(host, cmd_prefix)
log.debug(f"[项目:{project}, 主机:{host}] 成功获取 {len(disk_info_list)} 条磁盘信息及系统信息")
return {
"disk_info": disk_info_list,
"system_info": system_info,
"project": project,
"host": host,
"ip": mask_ip(ip)
}
except Exception as e:
# 明确处理SSH连接异常
if "Connection timed out" in str(e) or "connect to host" in str(e):
log.warning(f"[项目:{project}, 主机:{host}] SSH连接超时,跳过该主机")
else:
log.error(f"[项目:{project}, 主机:{host}] 获取信息失败: {str(e)}")
raise e # 让重试机制处理异常
def check_disk(project, get_time, ssh_key_path=None, all_hosts=None):
"""获取指定项目的所有主机信息(支持传入全局主机列表)"""
log.info(f"[项目:{project}] 开始处理主机信息")
# 使用全局主机列表,避免重复获取
hosts = [host for host in all_hosts if host.get('m.project') == project] if all_hosts else []
all_info = []
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
future_to_host = {
executor.submit(get_disk_info, host, get_time, ssh_key_path): host
for host in hosts
}
for future in concurrent.futures.as_completed(future_to_host):
try:
info = future.result()
all_info.append(info)
except Exception as e:
host = future_to_host[future]
log.error(f"[项目:{project}, 主机:{host['m.id']}] 处理异常: {str(e)}")
log.info(f"[项目:{project}] 共获取到 {len(all_info)} 台主机的信息")
return all_info
def send_alert(alert_type, data, system_info=None):
"""统一发送告警信息"""
if alert_type == "disk":
alert_title = "-----数据库告警-----\n磁盘高使用率告警"
alert_content = (
f"\n{alert_title}\n"
f"产品:{data['project']}\n"
f" - 主机:{data['host']}\n"
f" ip: {data['ip']}\n"
f" 设备:{data['device']}\n"
f" 总量:{data['total']}\n"
f" 已用:{data['used']}\n"
f" 剩余:{data['available']}\n"
f" 使用率:{data['percent_used']}%\n"
f" 挂载点:{data['mount_point']}\n"
f" 时间:{data['get_time']}\n"
)
elif alert_type == "cpu":
alert_title = "-----数据库告警-----\nCPU高使用率告警"
alert_content = (
f"\n{alert_title}\n"
f"产品:{data['project']}\n"
f" - 主机:{data['host']}\n"
f" ip: {data['ip']}\n"
f" CPU使用率:{system_info['cpu_usage']}%\n"
f" 阈值:{CPU_USAGE_THRESHOLD}%\n"
f" 时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
)
elif alert_type == "memory":
alert_title = "-----数据库告警----\n内存高使用率告警-"
alert_content = (
f"\n{alert_title}\n"
f"产品:{data['project']}\n"
f" - 主机:{data['host']}\n"
f" ip: {data['ip']}\n"
f" 内存使用率:{system_info['mem_usage']}%\n"
f" 阈值:{MEM_USAGE_THRESHOLD}%\n"
f" 时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
)
elif alert_type == "load":
alert_title = "-----数据库告警-----\n系统高负载告警"
alert_content = (
f"\n{alert_title}\n"
f"产品:{data['project']}\n"
f" - 主机:{data['host']}\n"
f" ip: {data['ip']}\n"
f" 系统负载:{system_info['load_avg']}\n"
f" CPU核心数:{system_info['cpu_cores']}\n"
f" 负载/核心数:{system_info['load_avg_compare']:.2f}\n"
f" 阈值:{LOAD_AVG_THRESHOLD}\n"
f" 时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
)
else:
log.warning(f"未知告警类型: {alert_type}")
return False, alert_content
log.info(f"[告警类型:{alert_type}] {alert_content}")
try:
#result = sms(alert_content)
result = ''
if result:
log.info(f"[告警类型:{alert_type}] 告警发送成功")
return True, alert_content
else:
log.error(f"[告警类型:{alert_type}] 告警发送失败")
return False, alert_content
except Exception as e:
log.error(f"[告警类型:{alert_type}] 发送告警异常: {str(e)}")
return False, alert_content
def get_all_data(ssh_key_path=None):
"""获取所有项目的硬件信息并处理告警"""
get_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
alert_count = {"disk": 0, "cpu": 0, "memory": 0, "load": 0}
# 1. 统一获取所有项目的主机列表(仅请求一次API)
log.info("开始获取所有项目的主机列表...")
all_hosts = []
for project in project_list:
hosts = get_nc_hostname(project, get_time)
all_hosts.extend(hosts)
log.info(f"共获取到 {len(all_hosts)} 台主机的基础信息")
# 2. 并发处理每个项目的主机信息
all_info = []
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future_to_project = {
executor.submit(check_disk, project, get_time, ssh_key_path, all_hosts): project
for project in project_list
}
for future in concurrent.futures.as_completed(future_to_project):
try:
project = future_to_project[future]
project_info = future.result()
all_info.extend(project_info)
log.info(f"[项目:{project}] 处理完成,获取到 {len(project_info)} 台主机信息")
except Exception as e:
log.error(f"[项目:{project}] 处理异常: {str(e)}")
log.info(f"所有项目处理完成,共获取到 {len(all_info)} 台主机的详细信息")
# 3. 处理告警
for host_info in all_info:
# 提取基本信息
base_data = {
"project": host_info["project"],
"host": host_info["host"],
"ip": host_info["ip"]
}
# 处理磁盘告警
for disk in host_info['disk_info']:
if disk['percent_used'] > CPU_USAGE_THRESHOLD:
success, _ = send_alert("disk", disk)
if success:
alert_count["disk"] += 1
# 处理系统告警
system_info = host_info['system_info']
if not system_info:
continue
# CPU告警
if system_info['cpu_usage'] > CPU_USAGE_THRESHOLD:
success, _ = send_alert("cpu", base_data, system_info)
if success:
alert_count["cpu"] += 1
# 内存告警
if system_info['mem_usage'] > MEM_USAGE_THRESHOLD:
success, _ = send_alert("memory", base_data, system_info)
if success:
alert_count["memory"] += 1
# 系统负载告警
if system_info['load_avg_compare'] > LOAD_AVG_THRESHOLD:
success, _ = send_alert("load", base_data, system_info)
if success:
alert_count["load"] += 1
log.info(
f"本次检查共触发告警: 磁盘[{alert_count['disk']}]、CPU[{alert_count['cpu']}]、内存[{alert_count['memory']}]、负载[{alert_count['load']}]")
return all_info
if __name__ == '__main__':
try:
log.info("+++++++++++++ 开始检查物理机硬件信息 +++++++++++++++++++++++")
SSH_KEY_PATH = "/root/.ssh/id_rsa"
get_all_data(SSH_KEY_PATH)
log.info("+++++++++++++ 物理机硬件信息检查完成 +++++++++++++++++++++++")
except Exception as e:
log.critical(f"脚本执行异常: {str(e)}", exc_info=True)
+106
View File
@@ -0,0 +1,106 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/5/28 上午9:25
# @Author : cmk
# @File : Logger.py
# @Email : 15726649712@163.com
import logging
import os
import re
from typing import Optional
from logging.handlers import TimedRotatingFileHandler
def setup_logger(
logger_name: str = "app_logger",
log_file: Optional[str] = None,
level: int = logging.INFO,
console_output: bool = True,
log_format: str = "%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s",
backup_count: int = 7, # 保留的历史日志文件数量
when: str = 'midnight', # 切割时间点,默认为午夜
interval: int = 1, # 切割间隔
) -> logging.Logger:
"""
配置并返回一个自定义logger实例
参数:
logger_name: 日志器名称,用于区分不同的日志实例
log_file: 日志文件路径,若为None则不输出到文件
level: 日志级别,默认INFO
console_output: 是否输出到控制台
log_format: 日志格式字符串
backup_count: 保留的历史日志文件数量
when: 日志切割时间单位 ('S'/'M'/'H'/'D'/'midnight'等)
interval: 日志切割间隔
返回:
配置好的logger实例
"""
# 获取或创建logger实例(避免重复配置)
logger = logging.getLogger(logger_name)
# 防止重复添加处理器
if logger.handlers:
return logger
# 设置日志级别
logger.setLevel(level)
# 创建格式化器
formatter = logging.Formatter(log_format)
# 添加文件处理器(如果指定了文件名)
if log_file:
try:
# 确保日志目录存在
log_dir = os.path.dirname(log_file)
if log_dir and not os.path.exists(log_dir):
os.makedirs(log_dir)
# 使用TimedRotatingFileHandler按天切割日志
file_handler = TimedRotatingFileHandler(
log_file,
when=when,
interval=interval,
backupCount=backup_count,
encoding='utf-8'
)
file_handler.setLevel(level)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# 添加日志切割提示
file_handler.suffix = "%Y-%m-%d.log" # 设置历史日志文件后缀
file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}\.log$") # 设置匹配模式
except Exception as e:
print(f"无法创建日志文件 {log_file}: {e}")
# 添加控制台处理器
# if console_output:
# console_handler = logging.StreamHandler()
# console_handler.setLevel(level)
# console_handler.setFormatter(formatter)
# logger.addHandler(console_handler)
return logger
# 示例使用
if __name__ == "__main__":
# 配置按天切割的文件日志
daily_logger = setup_logger(
logger_name="daily_logger",
log_file="logs/app.log", # 日志将按天切割到logs目录
level=logging.DEBUG,
backup_count=30 # 保留30天的历史日志
)
# 测试日志记录
daily_logger.info("这是一条测试日志")
daily_logger.debug("这是一条测试日志")
daily_logger.warning("这是一条测试日志")
daily_logger.error("这是一条测试日志")
daily_logger.critical("这是一条测试日志")
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/6/27 下午10:58
# @Author : cmk
# @File : __init__.py.py
# @Email : 15726649712@163.com
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/6/5 上午9:47
# @Author : cmk
# @File : database.py
# @Email : 15726649712@163.com
import pymysql
class DBHelper:
def __init__(self, host, user, password, database, port=3306, charset='utf8mb4'):
self.conn = pymysql.connect(
host=host,
user=user,
password=password,
database=database,
port=port,
charset=charset
)
self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)
def execute(self, sql, params=None):
"""执行非查询操作(insert, update, delete"""
try:
self.cursor.execute(sql, params or ())
self.conn.commit()
return self.cursor.rowcount
except Exception as e:
self.conn.rollback()
print("执行失败:", e)
return -1
def fetchall(self, sql, params=None):
"""执行查询,返回所有结果"""
self.cursor.execute(sql, params or ())
return self.cursor.fetchall()
def fetchone(self, sql, params=None):
"""执行查询,返回单条结果"""
self.cursor.execute(sql, params or ())
return self.cursor.fetchone()
def insert(self, table, data):
"""插入数据"""
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = f"INSERT INTO {table} ({keys}) VALUES ({values})"
return self.execute(sql, tuple(data.values()))
def update(self, table, data, where):
"""更新数据"""
set_clause = ', '.join([f"{k}=%s" for k in data.keys()])
where_clause = ' AND '.join([f"{k}=%s" for k in where.keys()])
sql = f"UPDATE {table} SET {set_clause} WHERE {where_clause}"
return self.execute(sql, tuple(data.values()) + tuple(where.values()))
def delete(self, table, where):
"""删除数据"""
where_clause = ' AND '.join([f"{k}=%s" for k in where.keys()])
sql = f"DELETE FROM {table} WHERE {where_clause}"
return self.execute(sql, tuple(where.values()))
def close(self):
"""关闭连接"""
self.cursor.close()
self.conn.close()
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/2/13 下午2:07
# @Author : cmk
# @File : tianji_json.py
# @Email : 15726649712@163.com
import json
import pandas as pd
import os
import pprint
with open('zhuque_0213.json','r',encoding='utf-8') as f:
data =f.readlines()
json_data=json.loads(''.join(data))
list_data = json_data['productList']
for i in range(0,int(len(list_data))):
print(list_data[i]['productName'])
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
[{
"host": "localhost",
"port": 3306,
"user": "root",
"password": "password",
"database": "ticai"
}]

Some files were not shown because too many files have changed in this diff Show More