0%

Python|自动化脚本实战手册

python

调用系统终端(cmd)

1.运用场景

有一些工具是使用命令行来执行的,这时可以调用系统终端来实现自动化

如:

swftool:http://www.swftools.org/ (swf转换工具)

ffmpeg:https://ffmpeg.org/ (视频转码工具)

2.实例
1
2
# pdf转swf
os.system('E:\swftools\pdf2swf.exe -b E:\swftools\pdf\%s.pdf -o E:\swftools\swf\%s.swf' % (name, name))
3.语法解释
  • import os引入os模块,该模块主要提供与操作系统相关的功能的便捷式途径

  • os.system可以在系统的子shell中执行命令,在windows上即相当于在cmd运行命令行,其返回值为命令退出的状态

  • os.system运行命令行时无法实时显示运行过程,只能最终返回运行结果,这是和在cmd运行时的差别

  • 使用system函数,会创建一个子进程,但是子进程无法影响父进程中的环境变量。简单来说,就是使用第一个system函数用cd切换目录,第二个system函数的环境变量仍然继承父进程的环境变量。所以第二个子进程的目录位置没有被第一条语句改变

  • 关于新进程的生成和跟踪执行结果,往往用subprocess模块代替system

  • system函数执行多条语句的方法,可以使用复合语句,如:os.system('cd path-to-repo && svn ci'),即都在一个子进程中运行命令

  • 或者使用os.chdir切换父进程的目录,再执行子进程

文件遍历筛选

1.运用场景

在自动化批量操作文件时,一定少不了文件遍历,并且可以筛选出需要的文件

2.实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 引入python的标准库os库
import os
# 遍历文件夹
def file(name):
# 初始化一个空列表存储文件
list_all = []
# 搜索一个目录下的所有文件夹和所有文件内的指定类型文件
for root, dirs, files in os.walk('E:\swftools\%s' % name):
# 获得文件名
for name in files:
# 加上文件路径
dir_path = os.path.join(root, name)
# 切割出文件名
dir_name = os.path.split(dir_path)[-1]
# 筛选文件
if '.pdf' or '.swf' in name:
list_all.append(dir_name)
return list_all
3.语法解释
  • os.walk(根目录)可返回3元组 (dirpath, dirnames, filenames)【文件夹相对路径, 文件夹名字, 文件名】
  • os.path.join拼接路径
  • os.path.split(path)拆分路径为(head, tail)

服务器操作

1.运用场景

可以运用在将本地文件上传到服务器或者操作服务器上的文件,还可以调用服务器的终端(可用于在服务器上制作视频流)

2.实例

参考博客:

https://www.jianshu.com/p/486dd9993125

https://juejin.cn/post/6844904078057668615

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import paramiko
# 建立ssh连接的同时,建立一个加密的文件传输通道
# 设置连接服务器信息
t = paramiko.Transport(("host(主机号)", 端口(一般为22)))
t.connect(username="用户名", password="密码")
# 将sshclient的对象的transport指定为以上的t,即进行ssh连接
ssh = paramiko.SSHClient()
ssh._transport = t
# ssh连接后在服务器终端运行命令,此处为复合语句
stdin, stdout, stderr = ssh.exec_command('cd /../var/www/;pwd;')
# 开启sftp通道,传输文件
sftp = ssh.open_sftp()
# 文件传输
sftp.put(localpath='本地路径', remotepath='远程路径’)
# 关闭通道
sftp.close
3. 语法解释
  • paramiko模块主要用于远程操作服务器,利用该模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输

  • pip install paramiko下载安装paramiko模块

  • 使用paramiko模块有两种连接方式,一种是通过paramiko.SSHClient()函数,另外一种是通过paramiko.Transport()函数

  • exec_command函数调用会返回3个变量,其中stdout为标准输出,在输出内容比较少时,可以通过直接使用read读取出所有的输出

  • sftp用get函数即下载远程文件,put函数即上传本地文件

数据库操作

1.运用场景

筛选统计数据库,或者可以利用数据库批量快捷发布网站内容(如基于wordpress的站点)

2.实例

参考文章:https://www.runoob.com/python3/python3-mysql.html

(1)引入所需库

1
2
import pymysql
from sshtunnel import SSHTunnelForwarder

(2)连接一般数据库

1
2
3
4
def link():
data = pymysql.connect(host='数据库主机号', port=端口, user='用户名', passwd='密码', db='数据库名', charset='utf8')

return data

(3)连接需要跳板机的数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

def link_base():
server = SSHTunnelForwarder(
('跳板机主机号', 22), # B机器的配置
ssh_password="跳板机密码",
ssh_username="跳板机用户名",
remote_bind_address=('数据库主机号', 数据库端口))

server.start()

data = pymysql.connect(host='127.0.0.1', # 此处必须是是127.0.0.1
port=server.local_bind_port,
user='数据库用户名',
passwd='数据库密码',
db='数据库名'
)

return data

(4) 利用sql语句操作数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 获取目标id
def mysql():
# 获得连接后的数据库
data = link()
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = data.cursor()
# 用execute执行sql语句操作数据库
sql = "sql语句"
cursor.execute(sql)

# 如果为查询操作
# 获取指针指向的数据
result = cursor.fetchall()
# 输出获取的元组数据
return result

# 如果为增删改操作
# 提交到数据库执行
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
db.rollback()
# 关闭数据库连接
db.close()
3.语法解释
  • 连接数据库的核心模块为pymysql,可以通过pip install PyMySQL安装
  • 当需要跳板机连接服务器对象时(可以说数据库服务器也可以是文件服务器),要用到sshtunnel模块,可以通过pip install sshtunnel安装
  • 数据库由多张关系表构成,往往需要查询多个表才能得到自己需要的批量数据
  • 通过cursor可以不断指定执行新的sql语句
  • sql语句可以善用where筛选语句,应选择查询对象是某个字段,而不是*(全表)

字符串操作

1.运用场景

自动化操作往往会涉及到字符串的筛选和修改,这时候就要用到python的字符串操作和正则匹配

2.实例

(1)python字符串处理

1
2
3
4
5
6
7
# 简单筛选出含有指定子字符串的字符串
if '.pdf' or '.swf' in name:
print(name)

# 简单字符串切片,利用find找到切点,再用字符串索引取出所需的字符串
num = str(i).find('.')
title = str(i)[:num]

(2)正则表达式处理字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re

# 利用正则匹配筛选字符串,并修改取代字符串
def edit(content):
# 正则匹配
pattern = re.compile(r'<embed')
if pattern.search(content):
content = str(content).replace('.pdf', '.swf').replace('pdf', 'x-shockwave-flash').replace('height="100%"', 'height="400"')
return content

# 正则匹配的两种方法
prog = re.compile(pattern)
result = prog.match(string)
# 等价于
result = re.match(pattern, string)
3.语法解释
  • 正则表达式往往是用大于看,看是很难看懂的,比较有用的正则工具:https://regex101.com/
  • 正则查找有match和search两种方式
  • re.match() 从第一个字符开始找, 如果第一个字符就不匹配就返回None, 不继续匹配. 用于判断字符串开头或整个字符串是否匹配,速度快
  • re.search() 会整个字符串查找,直到找到一个匹配
  • re.compile()将正则表达式的样式编译为一个正则对象,如果需要多次使用这个正则表达式的话,使用 re.compile()和保存这个正则对象以便复用,可以让程序更加高效

Word文档操作

1.运用场景

在办公中可以批量生成只有日期和名字改动的模板,可以读取一篇word文档生成计算机可以处理的数据

2.实例

(1)引入基本模块

1
2
3
4
5
6
7
8
# 负责新建文档
from docx import Document
# 对齐
from docx.enum.text import WD_ALIGN_PARAGRAPH
# 磅数
from docx.shared import Pt
# 中文格式
from docx.oxml.ns import qn

(2)文档基础设置

1
2
3
4
5
6
7
# 新建一个文档
document = Document()
# 设置文档基础字体,注意该处的styles有个s
document.styles['Normal'].font.name = u'微软雅黑'
document.styles['Normal'].font.size = Pt(14)
# 设置文档基础中文字体
document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), u'微软雅黑')

(3)创建纯文字模板

1
2
3
4
5
6
7
8
9
10
11
12
13
def add_context(context):
# 创建自然段
p = document.add_paragraph()
# 设置该自然段对齐方式
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
# 在该自然段添加文字
r = p.add_run(str(context))
# 设置字体格式
r.font.size = Pt(16)
# 段后距离5磅
p1.space_after = Pt(5)
# 段前距离5磅
p1.space_after = Pt(5)

(4)创建表格

1
2
3
4
5
6
7
8
9
height = len(list)
# 文档插入表格
table = document.add_table(rows=height, cols=5, style='Table Grid')
# 填写字段
table.cell(0, 0).text = '序号'
table.cell(0, 1).text = '网址名称'
table.cell(0, 2).text = '网址'
table.cell(0, 3).text = '责任部门'
table.cell(0, 4).text = '负责人姓名'

(5)存储文档

注意要标注后缀为docx,否则打不开文件,储存位置为程序根目录

1
document.save('test.docx')

(6)读取文档

可用于将记录题目的word文档转换为计算机可以处理的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from docx import Document
# 打开一个文档
document = Document("C语言.docx")
# 获取所有段落
all_paragraphs = document.paragraphs



# 创建二维数组存储一道题
passage = [[]]
sent = []
# 逐个读取段落,一般不读取run中的,因为会出现文字割裂的问题
for i in range(0, len(all_paragraphs)):
pattern = re.compile(r'^\d')
matching = pattern.findall(all_paragraphs[i].text)
if matching:
# 重置单个题目的列表
passage.append(sent)
sent = []
sent.append(all_paragraphs[i].text)

else:
sent.append(all_paragraphs[i].text)

(7)修改文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from docx import Document

# 读取word文件
document = Document("资料2.0.docx")

def change_text(old_text, new_text):
# 修改纯文本
# 复制粘贴word文档内容包括格式
all_paragraphs = document.paragraphs
for paragraphs in all_paragraphs:
for run in paragraphs.runs:
# 修改文字
run_text = run.text.replace(old_text, new_text)
run.text = run_text

# 修改表格
all_tables = document.tables
for table in all_tables:
for row in table.rows:
for cell in row.cells:
cell_text = cell.text.replace(old_text, new_text)
cell.text = cell_text

# 替换字符串
change_text('社团', '协会')
# 可以覆盖保存,但注意要将打开程序关闭
document.save("资料2.0.docx")

8.word转pdf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 使用win32模板的功能
from win32com.client import Dispatch, constants, gencache

# 确定读取docx的路径,保存pdf路径
docx_path = '资料2.0.docx'
pdf_path = '资料.pdf'

# 指向offic的功能并调用
gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)

# 调用word服务,开始转换
wd = Dispatch("Word.Application")
doc = wd.Documents.Open(docx_path, ReadOnly=1)
doc.ExportAsFixedFormat(pdf_path, constants.wdExportFormatPDF, Item=constants.wdExportDocumentWithMarkup,CreateBookmarks=constants.wdExportCreateHeadingBookmarks)

# 退出并保存
wd.Quit(constants.wdDoNotSaveChanges)
3.语法解释
  • 安装docx模块,pip install python-docx
  • 读取文档时要注意,document.paragraphs返回的数组的每一个元素即一行的内容
  • 一维数组的增加可以直接使用append不断扩展数组sent.append('str')
  • 二维数组的二维增加,可以直接填入数组passage.append(array),一维增加的前提的二维存在,否则会报错超出范围passage[1].append('str')

Excel文档操作

1.运用场景

办公中经常会用到excel表格来整理统计数据,利用python可以批量读取和写入表格,提高工作效率

2.实例

(1)xlrd库读取execl内容

1
2
3
4
5
6
7
8
9
10
11
12
13
import xlrd  # 引入xlrd库

# 引入工作簿路径
xlsx = xlrd.open_workbook('E://考勤表.xlsx')

# 确定读取的工作表,也可以用工作表名字来索引
# table = xlsx.sheet_by_name("表名")
table = xlsx.sheet_by_index(0)

# 确定单元格的坐标值,并打印,注意不要超过单元格所有的内容否则会报错,以下三种形式是一致的
print(table.cell_value(1, 2))
print(table.cell(1, 2).value)
print(table.row(1)[2].value)

(2)xlwt库写入execl工作表

1
2
3
4
5
6
7
8
9
10
11
# 引入xlwt库
import xlwt

# 新建一个工作簿
new_workbook = xlwt.Workbook()
# 新建一个工作表
worksheet = new_workbook.add_sheet('sheet1')
# 在工作表指定坐标写入值
worksheet.write(0, 0, 'test')
# 保存工作簿
new_workbook.save('test.xls')

Pandas分析数据

1.运用场景

Pandas是一个强大的分析结构化数据的工具集;用于数据挖掘和数据分析,同时也提供数据清洗功能。

2.案例

参考文档:https://www.pypandas.cn/

读取excel数据

1
2
3
4
5
6
7
import pandas as pd

# 用pandas打开excel
file = pd.ExcelFile('test.xlsx')
# 指定表名,excel的数据以数组的形式返回
data = file.parse('Sheet1')
print(data)