Python记录手册
离线部署
先确认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 json
headers = {
'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 pd
df = 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 json
data = {"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
import pyperclip
# 获取屏幕尺寸
# screen_width, screen_height = pg.size()
# print("屏幕宽度:", screen_width)
# print("屏幕高度:", screen_height)
# 获取鼠标位置
while True:
mouse_x, mouse_y = pg.position()
print("鼠标位置的坐标值:", mouse_x, mouse_y)
input('Stop!!!!!')
time.sleep(3)
name_list = []
for name in name_list:
time.sleep(3)
pg.moveTo(3600, 50) # 点击搜索框
pg.click(button='left')
pyperclip.copy(name)
pg.hotkey('ctrl', 'v')
time.sleep(1)
pg.moveTo(3650, 180) # 点击名字
pg.click(button='left')
pg.moveTo(4800, 1500) # 点击聊天框
pg.click(button='left')
time.sleep(1)
pyperclip.copy('Text')
pg.hotkey('ctrl', 'v')
pg.moveTo(6000, 1490) # 点击发送
input('Stop!!!')
'''
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()
报错&&排障
SyntaxError: Non-ASCII character '\xe8' in file Test.py on line 5, but no encoding declared;
第一行加上
# -*- coding: utf-8 -*-
即可
print(f"已创建目录:{current_month_dir}") SyntaxError: invalid syntax
Python 2 不支持 f-string 格式化,改为:
print("已创建目录:%s" % current_month_dir)
面向AI编程
设计一个python脚本,功能如下:
1.获取当前日期,月份
2.在当前目录下创建一个新目录,名称为当月月份,比如6月,如果已存在则不创建
3.把文件名是7天之前创建的,挪到对应的月份目录下
需调整一下,文件名格式是:HCS_2026-06-11.xlsx这种,把7天前的文件移入到文件夹中
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import shutil
from datetime import datetime, timedelta
# 1. 获取当前月份,创建当月目录
now = datetime.now()
current_month = now.month
month_dir = str(current_month)
# 不存在则创建目录
if not os.path.exists(month_dir):
os.mkdir(month_dir)
print("已创建目录:%s" % month_dir)
else:
print("目录 %s 已存在,无需创建")
# 计算7天前的日期
seven_days_ago = now - timedelta(days=7)
current_dir = os.getcwd()
# 遍历当前目录所有文件
for filename in os.listdir(current_dir):
file_path = os.path.join(current_dir, filename)
# 跳过文件夹、跳过当月目录本身
if os.path.isdir(file_path) or filename == month_dir:
continue
# 只处理 HCS_日期.xlsx 格式文件
if not filename.startswith("HCS_") or not filename.endswith(".xlsx"):
continue
try:
# 截取文件名中的日期部分:HCS_2026-06-11.xlsx -> 2026-06-11
date_str = filename.split("_")[1].split(".")[0]
# 转为日期对象
file_date = datetime.strptime(date_str, "%Y-%m-%d")
# 判断:文件日期 <= 7天前,就迁移
if file_date <= seven_days_ago:
target_path = os.path.join(month_dir, filename)
# 处理同名文件,追加时间戳避免覆盖
if os.path.exists(target_path):
name_part, ext = os.path.splitext(filename)
new_name = "%s_%s%s" % (name_part, now.strftime("%Y%m%d%H%M%S"), ext)
target_path = os.path.join(month_dir, new_name)
shutil.move(file_path, target_path)
print("已迁移:%s -> %s" % (filename, month_dir))
except Exception as e:
print("跳过异常文件 %s:%s" % (filename, str(e)))

浙公网安备 33010602011771号