python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python从Excel/Word处理到浏览器操控

Python自动化办公之从Excel/Word处理到浏览器操控的全面指南

作者:独隅

在数字化办公时代,Python 自动化已成为职场核心竞争力,本指南旨在帮助职场人士、数据分析师及开发者利用 Python 解放双手,实现办公流程的自动化,我们将深入剖析三大核心工具库:openpyxl、python-docx以及 Selenium,需要的朋友可以参考下

openpyxl, python-docx, Selenium 核心实战

核心定位:本指南聚焦于非结构化与结构化文档的自动化处理

  • openpyxl:Excel (.xlsx) 文件的读写与格式化专家。
  • python-docx:Word (.docx) 报告的生成与编辑利器。
  • Selenium:浏览器自动化之王,用于网页数据抓取、表单自动填写及跨系统流程打通。
  • 核心价值:将重复、枯燥的“复制粘贴”工作转化为秒级执行的脚本,释放人力专注于高价值决策。

摘要

在数字化办公时代,Python 自动化已成为职场核心竞争力。

本指南旨在帮助职场人士、数据分析师及开发者利用 Python 解放双手,实现办公流程的自动化。我们将深入剖析三大核心工具库:openpyxl(高效操作 Excel)、python-docx(专业生成 Word 文档)以及 Selenium(全能的浏览器自动化测试与爬虫工具)。文章不仅涵盖从基础文件读写到复杂样式定制、动态 网页交互的语法详解,还通过“财务报表合并”、“合同批量生成”、“Web 数据抓取与录入”等真实场景案例,展示端到端的自动化解决方案。同时,重点揭示内存管理、反爬虫对抗、环境依赖等常见陷阱,并提供系统的学习路径与资源推荐,助您构建高效的数字化办公工作流。

一、背景、发展历史与方向

1. 为什么需要 Python 自动化办公?

2. 发展历史

3. 核心作用与发展方向

二、基础语法与核心库详解

1. openpyxl:Excel 精细操作

核心概念: Workbook (工作簿), Worksheet (工作表), Cell (单元格)。
注意: 仅支持 .xlsx 格式,不支持 .xls (旧版)。
作用:读取、修改、创建 .xlsx 文件,保留原有公式和样式。

from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font, Color, PatternFill

# 1. 创建新 workbook
wb = Workbook()
ws = wb.active
ws.title = "Sales Data"

# 2. 写入数据
ws['A1'] = "Product"
ws['B1'] = "Price"
ws.append(['Laptop', 1200]) # 追加一行
ws.append(['Mouse', 25])

# 添加公式
# 3. 设置样式
ws['A1'].font = Font(bold=True, color="FFFFFF")
ws['A1'].fill = PatternFill(start_color="4472C4", fill_type="solid")
ws['C1'] = "Total"
ws['C2'] = "=A2*B2" # 注意:openpyxl 只写公式字符串,不计算结果

# 4. 读取现有文件
wb_load = load_workbook('report.xlsx')
ws_load = wb_load['Sheet1']
value = ws_load['A1'].value
# 读取现有文件
wb = load_workbook("report.xlsx", data_only=True) # data_only=True 读取公式计算后的值
ws = wb["Sales Data"]
print(ws['A2'].value)
# 5. 保存
wb.save('new_report.xlsx')

2. python-docx:Word 文档生成

核心概念: Document, Paragraph, Run (文本片段,用于样式), Table
注意: 只能创建/修改 .docx,不能打开旧的 .doc
作用:创建报告、合同,控制段落样式、表格布局。

from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH

# 1. 创建文档
doc = Document()

# 2. 添加标题
heading = doc.add_heading('Monthly Report', 0)
heading.alignment = WD_ALIGN_PARAGRAPH.CENTER

# 3. 添加段落与样式 (Run 的概念)
p = doc.add_paragraph('This is an automated report generated by Python.')
p.add_run(' Bold text').bold = True
p.add_run(' Italic text').italic = True

# 4. 添加表格
table = doc.add_table(rows=3, cols=3)
table.style = 'Table Grid'
cell = table.cell(0, 0)
cell.text = 'Header 1'

# 5. 保存
doc.save('report.docx')

3. Selenium:浏览器自动化神器

核心概念: WebDriver, WebElement, Locator Strategies (By.ID, By.XPATH), Wait (显式/隐式等待)。
前置: 需安装对应浏览器的 Driver (如 ChromeDriver) 并匹配版本。
作用:模拟用户打开网页、点击、输入、截图、下载。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
import time

# 1. 配置 Chrome 选项 (无头模式)
options = Options()
options.add_argument("--headless=new") # 2026 新版无头模式
options.add_argument("--disable-gpu")

# 初始化驱动 (需确保 chromedriver 版本匹配)
driver = webdriver.Chrome(options=options)

try:
    # 2. 打开网页
    driver.get("https://www.example.com")
    
    # 3.查找元素 (推荐 WebDriverWait 显式等待,此处简化演示)
    search_box = driver.find_element(By.NAME, "q")
    # 4. 模拟操作
    search_box.send_keys("Python Automation")
    search_box.send_keys(Keys.RETURN)
    
    time.sleep(2) # 实际生产请用 WebDriverWait
    
    # 5. 获取数据
    results = driver.find_elements(By.CSS_SELECTOR, ".result-title")
    print(f"Found {len(results)} results")
    
    # 6.截图
    driver.save_screenshot("result.png")
    
finally:
    # 7.关闭浏览器
    driver.quit() # 务必关闭浏览器

三、基本使用与进阶场景实例

场景一:批量合并 100 个 Excel 销售报表并生成透 视表

需求:将文件夹下所有 sales_*.xlsx 合并为一个总表,并计算总和。

import os
import openpyxl
from openpyxl.utils import get_column_letter

def merge_excel_files(folder_path, output_file):
    master_wb = openpyxl.Workbook()
    master_ws = master_wb.active
    master_ws.title = "All_Data"
    
    headers_written = False
    row_offset = 1
    
    for filename in os.listdir(folder_path):
        if filename.startswith("sales_") and filename.endswith(".xlsx"):
            wb = load_workbook(os.path.join(folder_path, filename))
            ws = wb.active
            
            for i, row in enumerate(ws.iter_rows(values_only=True), start=1):
                if i == 1: # 表头
                    if not headers_written:
                        master_ws.append(row)
                        headers_written = True
                    continue
                
                # 添加来源文件名作为新的一列
                new_row = list(row) + [filename]
                master_ws.append(new_row)
    
    # 添加汇总公式示例
    last_row = master_ws.max_row
    col_b = get_column_letter(2) # 假设第2列是金额
    master_ws[f'B{last_row+1}'] = f"=SUM(B2:B{last_row})"
    
    master_wb.save(output_file)
    print(f"Merged into {output_file}")

# merge_excel_files('./sales_reports', 'total_sales.xlsx')

场景二:根据 Excel 名单批量生成 Word 聘用合同

需求:读取 Excel 中的姓名、职位、薪资,填充到 Word 模板中,生成独立合同。

import openpyxl
from docx import Document

def generate_contracts(excel_path, template_path, output_folder):
    wb = load_workbook(excel_path)
    ws = wb.active
    
    # 加载模板
    template = Document(template_path)
    
    for row in ws.iter_rows(min_row=2, values_only=True):
        name, position, salary = row[0], row[1], row[2]
        
        # 复制模板内容 (深拷贝避免污染)
        import copy
        doc = copy.deepcopy(template)
        
        # 替换占位符 (简单文本替换,复杂情况需遍历 paragraphs)
        for paragraph in doc.paragraphs:
            if '{{NAME}}' in paragraph.text:
                paragraph.text = paragraph.text.replace('{{NAME}}', name)
            if '{{POSITION}}' in paragraph.text:
                paragraph.text = paragraph.text.replace('{{POSITION}}', position)
            if '{{SALARY}}' in paragraph.text:
                paragraph.text = paragraph.text.replace('{{SALARY}}', str(salary))
        
        # 处理表格内的替换 (略,逻辑类似,需遍历 table.rows)
        
        doc.save(f"{output_folder}/Contract_{name}.docx")
    print("Contracts generated!")

场景三:自动登录后台系统并下载日报

需求:登录公司内部 ERP,点击“下载日报”,保存文件。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
import os

def auto_download_report(url, username, password, download_dir):
    options = Options()
    options.add_argument("--headless=new")
    prefs = {"download.default_directory": download_dir, "download.prompt_for_download": False}
    options.add_experimental_option("prefs", prefs)
    
    driver = webdriver.Chrome(options=options)
    wait = WebDriverWait(driver, 10)
    
    try:
        driver.get(url)
        
        # 等待并输入账号密码
        user_input = wait.until(EC.presence_of_element_located((By.ID, "username")))
        user_input.send_keys(username)
        
        pass_input = driver.find_element(By.ID, "password")
        pass_input.send_keys(password)
        
        driver.find_element(By.ID, "login-btn").click()
        
        # 等待导航栏出现
        wait.until(EC.presence_of_element_located((By.LINK_TEXT, "Daily Reports")))
        driver.find_element(By.LINK_TEXT, "Daily Reports").click()
        
        # 点击下载按钮
        download_btn = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "download-excel")))
        download_btn.click()
        
        print("Download triggered. Waiting for completion...")
        # 实际项目中需轮询检查文件是否下载完成
        
    finally:
        driver.quit()

场景四:跨平台数据搬运 (Web -> Excel)

需求:从网页抓取股票数据,写入 Excel 并标红跌幅超过 5% 的股票。

from openpyxl.styles import Font, PatternFill

# 假设 data 是从 Selenium 或 requests 抓取到的列表 [(name, price, change), ...]
data = [("AAPL", 150.2, -0.5), ("TSLA", 200.5, -6.2), ("NVDA", 400.0, 2.1)]

wb = Workbook()
ws = wb.active
ws.append(["Stock", "Price", "Change%"])

red_fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
red_font = Font(color="9C0006", bold=True)

for item in data:
    row_idx = ws.max_row + 1
    ws.append(item)
    
    # 条件格式化:如果跌幅 > 5% (即 change < -5)
    if item[2] < -5.0:
        for cell in ws[row_idx]:
            cell.fill = red_fill
            cell.font = red_font

wb.save("stock_monitor.xlsx")

场景五:财务月报自动化 (OpenPyXL 进阶)

任务: 合并 12 个分公司的 Excel 报表,计算总和,生成透 视表风格汇总,并标红异常值。

import os
from openpyxl import load_workbook
from openpyxl.styles import Font, Color

def merge_reports(folder_path):
    summary_wb = Workbook()
    summary_ws = summary_wb.active
    summary_ws.append(['Company', 'Item', 'Amount', 'Status'])

    for filename in os.listdir(folder_path):
        if filename.endswith('.xlsx'):
            wb = load_workbook(os.path.join(folder_path, filename))
            ws = wb.active
            company_name = filename.split('.')[0]
            
            for row in ws.iter_rows(min_row=2, values_only=True):
                item, amount = row[0], row[1]
                status = "Normal"
                color = "000000"
                
                # 业务逻辑:金额大于 10000 标红
                if amount > 10000:
                    status = "High Risk"
                    color = "FF0000"
                
                summary_ws.append([company_name, item, amount, status])
                
                # 动态样式设置 (需要获取单元格对象)
                cell = summary_ws.cell(row=summary_ws.max_row, column=4)
                cell.font = Font(color=color, bold=True)

    summary_wb.save('Monthly_Summary.xlsx')

场景六:批量合同生成 (Python-docx + 数据源)

任务: 根据 Excel 中的客户名单,批量生成个性化的 Word 劳动合同。

from docx import Document
import pandas as pd

def generate_contracts():
    # 读取数据源
    df = pd.read_excel('clients.xlsx')
    
    # 加载模板
    template = Document('contract_template.docx')
    
    for index, row in df.iterrows():
        # 复制模板内容 (深拷贝避免污染)
        doc = Document() 
        # 实际项目中通常直接复制模板文件再打开,此处简化逻辑
        # 更好的做法:shutil.copy('template.docx', f'contract_{row["name"]}.docx')
        # 然后打开该文件进行修改
        
        # 模拟替换逻辑 (实际需遍历 paragraph 和 table 进行文本替换)
        # 这里展示核心思路:查找占位符 {{NAME}} 并替换
        for para in template.paragraphs:
            if '{{NAME}}' in para.text:
                para.text = para.text.replace('{{NAME}}', row['Name'])
            if '{{DATE}}' in para.text:
                para.text = para.text.replace('{{DATE}}', str(row['Date']))
        
        # 保存
        doc.save(f"Contracts/Contract_{row['Name']}.docx")

注:实际替换文本保留样式较复杂,建议使用 mailmerge 库辅助或仔细处理 run 级别替换。

场景七:电商竞品价格监控与录入 (Selenium 实战)

任务: 登录后台,抓取竞品网站价格,填入内部系统。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def price_monitor_and_entry():
    driver = webdriver.Chrome()
    wait = WebDriverWait(driver, 15)
    
    # 1. 抓取竞品价格
    driver.get("https://competitor-site.com/product/123")
    price_elem = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "price-tag")))
    competitor_price = float(price_elem.text.replace('$', ''))
    
    # 2. 登录内部系统
    driver.get("https://internal-system.com/login")
    driver.find_element(By.ID, "user").send_keys("admin")
    driver.find_element(By.ID, "pass").send_keys("secret")
    driver.find_element(By.ID, "submit").click()
    
    # 3. 填入数据
    wait.until(EC.presence_of_element_located((By.NAME, "price_input")))
    input_box = driver.find_element(By.NAME, "price_input")
    input_box.clear()
    input_box.send_keys(str(competitor_price * 0.95)) # 定价为竞品的 95%
    
    driver.find_element(By.ID, "save_btn").click()
    
    time.sleep(2)
    driver.quit()

四、致命陷阱与避坑指南

陷阱 1:Selenium 元素定位失败 (ElementNotFound)

陷阱 2:openpyxl 处理大文件内存爆炸

# 读取大文件
wb = load_workbook("huge_file.xlsx", read_only=True)
# 写入大文件
wb = Workbook(write_only=True)

陷阱 3:Word 模板替换破坏样式

陷阱 4:浏览器指纹被识别 (反爬虫)

陷阱 5:路径与编码问题

陷阱 6:Python-docx 陷阱

五、实践总结

  1. 异常处理是必须的:网络波动、文件占用、元素加载失败随时可能发生。务必使用 try-except-finally 块,并确保在 finally 中关闭浏览器或保存文件。
  2. 显式等待优于隐式等待:在 Selenium 中,永远使用 WebDriverWait 配合 expected_conditions,不要依赖固定的 sleep 时间。
  3. 数据与逻辑分离:将配置信息 (路径、账号、URL) 提取到配置文件 (.env 或 .json) 中,不要硬编码在脚本里。
  4. 日志记录:使用 logging 模块代替 print,记录操作步骤、错误信息和时间戳,便于排查问题。
  5. 分步调试:先手动操作一遍流程,再写成代码。开发时先注释掉大部分代码,逐段验证。
  6. 尊重目标系统
    • 不要高频请求导致服务器崩溃。
    • 遵守网站的 robots.txt 协议和服务条款。
    • 仅在授权范围内使用自动化工具。

终极建议
“自动化不是为了完全取代人,而是为了把人从机械劳动中解放出来。最好的自动化脚本是健壮的、可维护的,并且能在出错时优雅地通知人类介入。”

Python 自动化办公不仅仅是学习几个库的 API,更是一种思维方式的转变:从“手动重复”转向“流程设计”。

起步时,请从解决手头最繁琐的一个小任务开始(如“每天合并这 5 个表”),逐步积累代码片段,最终形成自己的自动化工具箱。记住,最好的自动化脚本是那些稳定、易维护且能真正节省时间的脚本。

掌握 openpyxl, python-docx 和 Selenium,你将拥有“点石成金”的能力,让电脑为你 24 小时工作。现在,去写下你的第一个自动化脚本吧!

以上就是Python自动化办公之从Excel/Word处理到浏览器操控的全面指南的详细内容,更多关于Python从Excel/Word处理到浏览器操控的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文