离线部署
先确认Python版本和系统架构
uname -m
aarch64
https://pypi.org/project/
搜索包
cp37:对应Python3.7版本
aarch64:对应系统架构
pip3 install pandas-1.3.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl --no-index --find-links=. # --no-index 忽略索引,--find-links=. 表示在当前目录下查找包。
环境设置
可能导致yum install出问题
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/bin/pip3 /usr/bin/pip
requests
response.text # 返回服务器响应的文本内容,通常是HTML或JSON格式。
response.content # 返回服务器响应的二进制内容,通常是原始数据。
response.status_code # 返回服务器响应的HTTP状态码,例如200表示成功。
response.cookies # 返回服务器响应的Cookie信息。
response.encoding # 返回服务器响应的编码方式,例如utf-8。
response.json() # 返回服务器响应的JSON数据,如果响应内容不是JSON格式则会抛出异常。
post
import requests
import jsonheaders = {'Accept':'application/json, text/javascript, */*; q=0.01','Accept-Encoding':'gzip, deflate','Accept-Language':'zh-CN,zh;q=0.9','Connection':'keep-alive','Content-Length':'186','Content-Type':'application/json; charset=UTF-8','Cookie': cookie,'Host':'tapi.zjcftce.com','Origin':'http://console.zjcftce.com','Referer':'http://console.zjcftce.com/','User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36','X-CsrfCode': X_CsrfCode
}
Json = {"serviceType":"cvm","action":"DescribeInstances","data":{"Limit":1,"Offset":0,"Language":"zh-CN","Version":"2017-03-12"},"region":"sz"} # 请求载荷:POST 请求的主体内容。Param_Url = 'http://tapi.zjcftce.com/capi/v3?i=cvm/DescribeInstances' # ?后面的 i=cvm/DescribeInstances 就是查询字符串参数
response = requests.post(url=Param_Url, headers=headers, json=Json) # url就是请求网址,headers是请求标头,json是请求载荷。params = {"i": "cvm/DescribeInstances"} # 查询字符串参数,即URL后面?后面的部分。
NoParam_Url = 'http://tapi.zjcftce.com/capi/v3'
response = requests.post(url=NoParam_Url, headers=headers, json=Json, params=params) # 相当于把URL后面?后面的部分挪到params参数里面了。print(response.text) # str
print(json.loads(response.text)) # dict


pandas
问题汇总:
1. import pandas报错:module 'os' has no attribute 'add_dll_directory'-->解决办法:Python 版本升级到 3.8以上
格式转换
DataFrame-->string
My_str = result_df.to_string(index=False)
DataFrame-->list
My_list = result_df.values.tolist()
依赖
pandas-->setuptools|wheel|numpy|openpyxl-->ex_xmlfile
写入Excel
纯dict就加[]。
df = pd.DataFrame([Dict])
如果Excel不存在就创建一个
import pandas as pd
if not os.path.exists(self.Excel_name):pd.DataFrame().to_excel(self.Excel_name, index=False)
追加数据到Excel的不同sheet中
import pandas as pd
Excel_name = "数据.xlsx"
with pd.ExcelWriter(Excel_name, engine="openpyxl", mode="a") as writer:DF.to_excel(writer, sheet_name=f"Sheet{len(writer.sheets)+1}", index=False)
import pandas as pddf = pd.DataFrame(list_or_dict) # 将dict/list转换为DataFrame对象。
df['未填写占比'] = (df['待填写迁移时间'].astype(int) / all_non_shutdown * 100).round(2).astype(str) + '%'
df.to_excel('Test.xlsx', index=False) # 写入Excel文件,index=False表示不包含索引列。df_existing = pd.read_excel('Test.xlsx')
df = pd.DataFrame(CVM_dict)
with pd.ExcelWriter('Test.xlsx', mode='a', engine='openpyxl', if_sheet_exists='overlay') as writer:
# 使用 ExcelWriter 对象追加数据到已存在的Excel文件。df.to_excel(writer, index=False, header=False, startrow=len(df_existing)+1) # 追加数据到Excel文件,不包含索引列和表头。 startrow:指定从哪一行开始写入数据。
读取Excel
df = pd.read_excel("VM.xlsx", usecols=["计划完成时间", "组长", "组别"]) # 读取指定列
for group_name, group_data in df.groupby("组别"): # group_name
shutdown_count = group_data[
group_data["计划迁移TCE"].isin(["关机下线", "平台下线"]) # 多值匹配
].shape[0]
# 统计<计划迁移TCE>中值为<"关机下线", "平台下线">的数量
# .shape-->(行, 列)
# .shape[0]-->统计行数
# .shape[1]-->统计列数
non_shutdown = group_data[
~group_data["计划迁移TCE"].isin(["关机下线", "平台下线"]) # ~表示取反
]
has_time = non_shutdown["计划完成时间"].notna() & (non_shutdown["计划完成时间"] != "") # .notna()-->不是空值(NaN)
openpyxl
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.cell(row=1, column=1, value=1)
wb.save('output.xlsx') # 创建并保存,如果文件已存在,则会覆盖。
with open
with open('system.json', 'w', encoding='utf-8') as f: # 打开文件进行写操作,并指定编码格式为utf-8。f.write(response.text)with open('system.json', 'r', encoding='utf-8') as f: # 打开文件进行读操作,并指定编码格式为utf-8。data = json.load(f) # 读取文件内容,并将其转换为json。with open("output.json", "w", encoding="utf-8") as f:json.dump(self.cvm_dict, f, ensure_ascii=False, indent=4)# ensure_ascii=False, # 关键:保留中文# indent=4 # 格式化输出
json
json.dump() 和 json.dumps()
若需将 JSON 数据写入文件,用 json.dump()(少一次字符串写入文件的步骤,更高效)。
若需在内存中操作 JSON 格式的字符串(如拼接、传输),用 json.dumps()。
import jsondata = {"name": "北京", "code": "bj"}# 1. json.dump():写入文件
with open("data.json", "w", encoding="utf-8") as f:json.dump(data, f, ensure_ascii=False, indent=2) # 直接写入文件,ensure_ascii=False, # 关键:保留中文# 2. json.dumps():返回字符串
json_str = json.dumps(data, ensure_ascii=False, indent=2) # 得到JSON字符串
print(type(json_str)) # <class 'str'>
json.load() 和 json.loads()
若 JSON 数据在文件中,用 json.load()(直接操作文件对象,更简洁)。
若 JSON 数据是内存中的字符串(如接口返回、变量存储),用 json.loads()(处理字符串输入)
import json# 1. json.load():从文件解析JSON
with open("data.json", "r", encoding="utf-8") as f:data_from_file = json.load(f) # 直接读取文件并解析为Python对象print(type(data_from_file)) # <class 'dict'># 2. json.loads():从字符串解析JSON
json_str = '{"name": "上海", "code": "sh"}'
data_from_str = json.loads(json_str) # 解析字符串为Python对象
print(type(data_from_str)) # <class 'dict'>
包&pip
下载
pip install pandas1.5.3 # 安装特定版本的包
pip download pandas1.5.3 -C D:\Downloads\pandas-1.5.3.tar.gz # 下载特定版本的包到指定目录
查看本地包的安装位置
import os
print(os.__file__)
时间
赞
from datetime import datetime, timedelta# 获取当前北京时间
now = datetime.now()# 1. 计算 end_time:当前时间向下取 5 分钟整
current_min = now.minute
align_end_min = (current_min // 5) * 5 # 43→40, 47→45, 38→35
end_time = now.replace(minute=align_end_min, second=0, microsecond=0)# 2. 计算 begin_time:end_time 往前推 30 分钟
begin_time = end_time - timedelta(minutes=30)# 转成接口需要的 13 位毫秒时间戳
begin_ts = int(begin_time.timestamp() * 1000)
end_ts = int(end_time.timestamp() * 1000)# 输出结果
print(f'"begin_time": {begin_ts},')
print(f'"end_time": {end_ts}')# 打印可读时间(方便你核对)
print("\n核对时间:")
print(f"开始时间:{begin_time}")
print(f"结束时间:{end_time}")
from datetime import datetime
now = datetime.now()
day = str(now.date()) # 2025-10-10
timestamp = int(now.timestamp()) # 1760061958
正则
^:匹配开头
\b:单词边界
[]:字符集合,匹配括号内的任意一个字符
():捕获组,用于提取匹配的文本
[]^\s*<a 确保只匹配带前导空格的<a标签(不匹配<link>)
<a\b 单词边界,用于确保 <a 是一个完整的标签名,防止误匹配如<ab等
.*? 匹配任意数量的非贪婪字符,直到遇到下一个模式
\bhref="([^"]+)" 捕获href属性值,但不包括引号
import re# 原始字符串(包含link标签和带前导空格的a标签)
html_str = '''<link href="aaa" download="bbb"><a href="aaa" download="bbb"><a href="ASD" download="fgh">c<a href="ASD" download="fgh"><ab href="ASD" download="fgh"><a vhref="ASD" cdownload="fgh"><a hrefc="ASD" downloads="fgh">
'''# 正则表达式:匹配带任意前导空格的<a>标签中的href和download属性
# 1. ^\s*<a 确保只匹配带前导空格的<a>标签(不匹配<link>)
# 2. 同时捕获href和download的属性值(考虑属性顺序可能不同)
pattern = r'^\s*<a\b.*?\bhref="([^"]+)".*?\bdownload="([^"]+)"'# 启用多行模式(让^匹配每行开头)
matches = re.findall(pattern, html_str, re.MULTILINE | re.DOTALL)# 1. 打印匹配结果
print("匹配到的<a>标签属性值:")
for href_val, download_val in matches:print(f"href: {href_val}, download: {download_val}")# 2. 将href和download的值分别替换为"XXX"和"YYY"
def replace_attributes(match):# 保留标签结构,只替换属性值return f'<a href="XXX" download="YYY">'replaced_str = re.sub(pattern, replace_attributes, html_str, flags=re.MULTILINE | re.DOTALL)
print("\n替换后的字符串:")
print(replaced_str)
pyautogui
问题汇总:
1. pg.click()实际上并没有点击-->以管理员身份运行脚本即可
2. pg.write("你好")无法写入中文-->pyperclip.copy("你好") + pg.hotkey('ctrl', 'v')
3. pg.hotkey('Ctrl', 'A')实际效果是ctrl+shift+a-->不确定是什么原因,但是改成pg.hotkey('ctrl', 'a')即可-->应该是A == shift + a
import pyautogui as pg
import time# 获取屏幕尺寸
screen_width, screen_height = pg.size()
print("屏幕宽度:", screen_width)
print("屏幕高度:", screen_height)# 获取鼠标位置
mouse_x, mouse_y = pg.position()
print("鼠标位置的坐标值:", mouse_x, mouse_y)
'''
pg.PAUSE = 1.0 # 秒pg.moveTo(100, 100, duration=1) # 移动到指定位置
pg.move(100, -100, duration=1) # 移动到相对位置
'''pg.moveTo(368, 60) # 移动到指定位置
pg.click(x=368, y=60,clicks=1,interval=0,duration=0, button='left')############################################################################
'''
#绝对拖拽,指拖拽到那个位置
pg.dragTo(x=100, y=-100, duration=0.5, button='left')
#相对拖拽,相对于当前位置拖拽
pg.drag(xOffset=100, yOffset=100, duration=0.5, button='right')
'''############################################################################pg.click(x=90, y=100,clicks=2,interval=0,duration=0, button='left') # 单击
pg.doubleClick(x=90, y=100, duration=0, button='left') # 双击
'''
#button:默认左键,左键 left,右键 right,中键 middle
#clicks:点击次数,默认是1次
#interval:每次点击间隔时间,默认是0
#duration:持续时间,默认是0
'''############################################################################'''
#单击分布操作
#按下鼠标键位
pg.mouseDown(button='left')
#释放鼠标键位
pg.mouseUp(button='left')
'''
数据处理【数据类型转换】
JSON 格式 的bytes
1.先转为string再转成dict
str_data = bytes_data.decode('utf-8')
dict_data = json.loads(str_data)
2.dict转为JSON 格式 的bytes后再转为 dict
bytes_data = json.dumps(dict_data, ensure_ascii=False).encode('utf-8') # ensure_ascii=False-->保留中文
dict_data = json.loads(bytes_data.decode('utf-8'))
redis
list
import redis
# 创建一个StrictRedis对象,连接到本地Redis服务
r = redis.StrictRedis(host='10.135.114.16', port=6379, db=0)
# List操作
r.lpush('mylist', 'item1', 'item2') # 向列表左侧添加元素
r.rpush('mylist', 'item3', 'item4') # 向列表右侧添加元素# 获取 mylist 中所有元素(0 表示第一个,-1 表示最后一个)
items = r.lrange('mylist', 0, -1)
print([item.decode() for item in items]) # 输出:['item2', 'item1', 'item3', 'item4']# 弹出【删除】并返回左侧第一个元素
left_item = r.lpop('mylist')
# 弹出【删除】并返回右侧最后一个元素
right_item = r.rpop('mylist')
print(left_item.decode())# 获取 mylist 的元素个数
length = r.llen('mylist')# 删除key【任意类型】
r.delete("key1", "key2", "key3") # 删除一个或多个键
set
import redis# 连接 Redis(根据实际情况配置参数)
r = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)
# 注意:decode_responses=True 可自动将返回的 bytes 转为 str,避免手动 decode()# 1. 向集合添加元素(SADD):添加一个或多个元素,已存在的元素会被忽略
r.sadd('cities', '北京', '上海', '广州') # 返回新增元素数量:3# 2. 获取集合所有元素(SMEMBERS):返回无序列表
print(r.smembers('cities')) # 输出:{'北京', '上海', '广州'}(集合类型,无序)# 3. 判断元素是否在集合中(SISMEMBER):存在返回 True,否则 False
print(r.sismember('cities', '北京')) # 输出:True
print(r.sismember('cities', '深圳')) # 输出:False# 4. 删除集合中的元素(SREM):删除一个或多个元素,返回删除成功的数量
r.srem('cities', '广州') # 返回 1(删除了'广州')# 5. 获取集合长度(SCARD):返回元素个数
print(r.scard('cities')) # 输出:2(剩余'北京'、'上海')# 6. 集合运算:交集、并集、差集
r.sadd('cities2', '上海', '深圳', '杭州') # 新建另一个集合# 交集(SINTER):两个集合共有的元素
print(r.sinter('cities', 'cities2')) # 输出:{'上海'}# 并集(SUNION):两个集合所有元素(去重)
print(r.sunion('cities', 'cities2')) # 输出:{'北京', '上海', '深圳', '杭州'}# 差集(SDIFF):前者有、后者没有的元素
print(r.sdiff('cities', 'cities2')) # 输出:{'北京'}# 7. 随机获取元素(SRANDMEMBER):随机返回n个元素(不删除)
print(r.srandmember('cities', 1)) # 随机返回1个元素,如 ['北京']# 8. 随机删除并返回元素(SPOP):随机删除并返回1个元素
print(r.spop('cities')) # 如输出:'上海'(此时集合仅剩'北京')# 9. 删除整个集合(DEL):通用命令,删除集合key
r.delete('cities') # 删除集合'cities'
Python定时任务
Windows
Win + X --> 打开计算机管理 --> 任务计划程序 --> 【右键】创建基本任务

paramiko
import paramiko ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('hostname', username='username', password='password')stdin, stdout, stderr = ssh.exec_command('ls -l')
output = stdout.read().decode()
print(output) ssh.close()
