Python记录手册

离线部署

先确认Python版本和系统架构

uname -m
aarch64

https://pypi.org/project/
搜索包-->Release history-->找到需要的版本
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

img
img

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 pandas
1.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

正则

html_str = '''


c




'''

匹配 中的 href 和 download 属性
干扰项:

  1. 中的href和download属性
  2. <a前后有非空格字符
  3. href和download前后非空格字符
^:匹配开头
\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 --> 打开计算机管理 --> 任务计划程序 --> 【右键】创建基本任务
img

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)))
posted @ 2026-05-22 17:25  WiseHYH  阅读(11)  评论(0)    收藏  举报