影刀RPA新手教程:数据透视与分析报告自动化——Python pandas让数据会说话
0. 这篇文章解决什么问题
采集完数据只是第一步。把数据变成报告才能交付。这篇文章用pandas做数据透视、groupby分组汇总、openpyxl写带样式的Excel并自动画折线图,最后飞书发报告。全程代码,没有废话。
1. 认识影刀 / 安装确认
确认影刀已安装"数据处理"和"Python"指令集。安装方式:指令中心→搜索→勾选→安装。pandas和openpyxl是Python标准生态库,影刀Python代码块里import pandas和import openpyxl直接用,不用单独装。
影刀官网 home.linyan.cloud 有详细的Python环境说明。
影刀的Python是内置的3.8+环境,自带pandas、numpy、openpyxl、requests等常用库。如果缺了什么包,在设置→Python环境中手动pip安装。
2. 元素定位四合一
这篇文章不涉及网页自动化,元素定位部分跳过。但如果你需要从网页抓数据做分析报告,回顾前面文章的元素定位四种方式:XPath/CSS/文本/相对定位。
3. 变量与数据类型(数据处理核心)
pandas处理的核心数据类型:
DataFrame(最常用):二维表,类似Excel表格。影刀数据表格可以直接转DataFrame:
importpandasaspd# data_table是影刀的"D"类型变量(数据表格)df=pd.DataFrame(data_table)Series:DataFrame的一列,是一个带索引的数组。
日期类型转换(关键坑):
df['发布日期']=pd.to_datetime(df['发布日期'])# 如果读进来是字符串"2024-01-15"NaN处理:
df['价格']=pd.to_numeric(df['价格'],errors='coerce')# 转换失败变NaNdf.dropna(subset=['价格'],inplace=True)# 删掉价格为NaN的行df.fillna({"描述":"无"},inplace=True)# 用"无"填充空描述4. 流程控制(分析报告生成流程)
生成分析报告的流程控制:
步骤1:读取采集到的原始数据Excel 步骤2:数据清洗(价格标准化、日期格式化、NaN填充) 步骤3:数据透视分析(按维度分组统计) 步骤4:写入分析结果到Excel(带样式) 步骤5:生成折线图 步骤6:通过飞书/邮件发送报告用if判断处理不同维度:
ifreport_type=="价格分析":result=df.groupby('价格区间')['商品数量'].sum()elifreport_type=="平台对比":result=df.groupby('平台')['均价'].mean()elifreport_type=="趋势分析":result=df.groupby('日期')['均价'].mean().reset_index()5. 网页自动化
分析报告的文章不涉及网页自动化,但如果你需要把报告上传到网页系统(比如企业内部BI平台),参考前面文章的网页自动化操作。
6. 数据处理(pandas完整分析流程)
读数据:
importpandasaspd# 读Exceldf=pd.read_excel("D:/data/采集结果.xlsx")# 读多个文件合并importglob all_dfs=[]forfileinglob.glob("D:/data/采集*/*.xlsx"):all_dfs.append(pd.read_excel(file))df=pd.concat(all_dfs,ignore_index=True)df.drop_duplicates(subset=['商品URL'],inplace=True)# 去重数据清洗:
# 1. 价格字段统一为纯数字df['价格']=df['价格'].str.replace('元','').str.replace('¥','')df['价格']=df['价格'].str.replace(',','').str.strip()df['价格']=pd.to_numeric(df['价格'],errors='coerce')# 2. 日期列转标准格式df['发布日期']=pd.to_datetime(df['发布日期'])# 3. 添加辅助列:月份、周数df['月份']=df['发布日期'].dt.month df['周数']=df['发布日期'].dt.isocalendar().week数据透视三大用法:
groupby分组统计:
# 按成色分组统计均价condition_stats=df.groupby('成色').agg(商品数=('标题','count'),均价=('价格','mean'),最低价=('价格','min'),最高价=('价格','max')).round(2)pivot_table交叉表:
# 成色 × 价格区间交叉透视df['价格区间']=pd.cut(df['价格'],bins=[0,500,1000,2000,3000,5000,10000])pvt=pd.pivot_table(df,index='成色',columns='价格区间',values='标题',aggfunc='count',fill_value=0)时间序列分组:
# 按周统计新增商品数量weekly=df.groupby(df['发布日期'].dt.isocalendar().week.astype(int)).size()weekly=weekly.reset_index(name='商品数')7. 鼠标键盘 / 图像自动化
分析报告流程不涉及这部分。但如果你的报告需要在固定时间打开指定的Excel发给某人,可以用图像识别定位发送按钮。了解即可。
8. 进阶技能(openpyxl写样式 + 画图)
基础写入:
fromopenpyxlimportWorkbookfromopenpyxl.stylesimportFont,PatternFill,Alignment,Border,Side wb=Workbook()ws=wb.active ws.title="竞品价格分析报告"# 写标题行ws['A1']='竞品价格分析报告'ws['A1'].font=Font(name='微软雅黑',size=16,bold=True,color='1F4E79')ws.merge_cells('A1:E1')设置样式(颜色、边框、字体):
# 表头样式header_fill=PatternFill(start_color='4472C4',end_color='4472C4',fill_type='solid')header_font=Font(name='微软雅黑',size=11,bold=True,color='FFFFFF')header_align=Alignment(horizontal='center',vertical='center')headers=['成色','商品数','均价','最低价','最高价']forcol,headerinenumerate(headers,1):cell=ws.cell(row=2,column=col,value=header)cell.fill=header_fill cell.font=header_font cell.alignment=header_align# 数据行交替颜色thin_border=Border(left=Side(style='thin'),right=Side(style='thin'),top=Side(style='thin'),bottom=Side(style='thin'))forrow_idx,row_datainenumerate(condition_stats.values,3):forcol_idx,valinzip(range(1,6),row_data):cell=ws.cell(row=row_idx,column=col_idx,value=val)cell.border=thin_border cell.alignment=Alignment(horizontal='center')ifrow_idx%2==0:cell.fill=PatternFill(start_color='D9E2F3',end_color='D9E2F3',fill_type='solid')# 列宽自适应ws.column_dimensions['A'].width=12ws.column_dimensions['B'].width=10自动画折线图:
fromopenpyxl.chartimportLineChart,Reference# 假设B列是商品数,A列是成色chart=LineChart()chart.title="各成色商品数量分布"chart.y_axis.title="商品数量"chart.x_axis.title="成色"chart.style=10# 数据区域:B2到B最后一行data_ref=Reference(ws,min_col=2,min_row=2,max_row=2+len(condition_stats),max_col=2)cats_ref=Reference(ws,min_col=1,min_row=3,max_row=2+len(condition_stats))chart.add_data(data_ref,titles_from_data=True)chart.set_categories(cats_ref)# 设置线条颜色fromopenpyxl.chart.seriesimportDataPoint chart.series[0].graphicalProperties.line.width=25000# 线宽ws.add_chart(chart,"A10")# 把图表放在A10位置写入多个Sheet:
ws2=wb.create_sheet("价格趋势")ws2['A1']='日期'ws2['B1']='均价'foridx,(date,price)inenumerate(zip(weekly.index,weekly.values),2):ws2.cell(row=idx,column=1,value=date)ws2.cell(row=idx,column=2,value=price)wb.save("D:/reports/竞品价格分析报告.xlsx")日期写入坑:Windows下用office或wps写入datetime类型会少8小时(时区问题)。解决方案——转字符串再写入,或者用openpyxl写入:
df['发布日期']=df['发布日期'].dt.strftime('%Y-%m-%d %H:%M:%S')# 或者importdatetime,pywintypes excel_date=pywintypes.Time(row['发布日期'].timetuple())这个坑我排查了一下午。报告里的时间全部比实际早了8小时,后来才知道office的COM接口用的是UTC时间。
9. 平台实战(飞书通知 + 邮件发送)
飞书机器人群通知:
importrequests,jsondefsend_feishu_report(webhook_url,report_path,summary):# 发送文本汇总text_msg={"msg_type":"text","content":{"text":f"本周竞品分析报告已生成\n{summary}"}}requests.post(webhook_url,json=text_msg)# 发送Excel文件importrequestswithopen(report_path,'rb')asf:requests.post("https://open.feishu.cn/open-apis/im/v1/files",headers={"Authorization":"Bearer xxx"},files={"file":f})邮件发送:
importsmtplibfromemail.mime.multipartimportMIMEMultipartfromemail.mime.textimportMIMETextfromemail.mime.baseimportMIMEBasefromemailimportencoders msg=MIMEMultipart()msg['Subject']='本周竞品价格分析报告'msg['From']='report@company.com'msg['To']='team@company.com'body=MIMEText('报告见附件,自动生成于'+str(datetime.now()),'plain','utf-8')msg.attach(body)# 附件withopen('D:/reports/竞品价格分析报告.xlsx','rb')asf:attachment=MIMEBase('application','octet-stream')attachment.set_payload(f.read())encoders.encode_base64(attachment)attachment.add_header('Content-Disposition','attachment',filename='竞品价格分析报告.xlsx')msg.attach(attachment)smtp=smtplib.SMTP_SSL('smtp.exmail.qq.com',465)smtp.login('report@company.com','password')smtp.send_message(msg)smtp.quit()10. 系统联动
影刀定时任务 + 自动报告:
控制台配置:每周一早上8点执行。流程顺序:
- 影刀启动 → 读取上周所有采集数据
- Python代码块用pandas分析
- 再用Python代码块openpyxl生成带图表的报告
- 飞书通知 + 邮件发送
- 日志打印完成
Excel数据表整理技巧:
影刀数据表格的导出指令可以把采集数据保存为Excel。然后Python代码块读取这个Excel做分析。注意确保导出路径存在,不然会报错。
对比上周数据:
importpandasaspd this_week=pd.read_excel("D:/data/本周.xlsx")last_week=pd.read_excel("D:/data/上周.xlsx")# 合并对比compare=pd.merge(this_week,last_week,on='成色',suffixes=('_本周','_上周'))compare['均价变化']=compare['均价_本周']-compare['均价_上周']compare['变化率']=(compare['均价变化']/compare['均价_上周']*100).round(1)11. 工程化与规范
目录规范:
D:/RPA/ ├── 数据分析/ │ ├── report_config.json # 报告配置(邮件/飞书/webhook等) │ ├── report_template.xlsx # 报告模板 │ ├── output/ # 生成的报告 │ └── scripts/ │ ├── data_clean.py # 数据清洗模块 │ └── report_gen.py # 报告生成模块配置集中管理:
{"report":{"title":"竞品价格分析周报","output_dir":"D:/reports","sheets":["价格分布","趋势分析","对比分析"]},"feishu_webhook":"https://open.feishu.cn/xxx","email":{"smtp":"smtp.exmail.qq.com","to":"team@xxx.com"}}12. 速查表 / 常见报错
pandas常用操作速查:
| 操作 | 代码 |
|---|---|
| 读Excel | pd.read_excel("path") |
| 转数字 | pd.to_numeric(df['col'], errors='coerce') |
| 分组统计 | df.groupby('col').agg({'a':'mean','b':'sum'}) |
| 数据透视表 | pd.pivot_table(df, index='a', columns='b') |
| 合并DataFrame | pd.concat([df1, df2]) |
| 按条件筛选 | df[df['价格'] > 1000] |
| 排序 | df.sort_values('价格', ascending=False) |
| 写Excel | df.to_excel("path", index=False) |
常见报错:
报错1:KeyError: 'xxx'→ DataFrame里没有这个列名。打印df.columns确认列名。
报错2:invalid literal for int() with base 10→ 数据类型不对。先用pd.to_numeric(errors='coerce')转换。
报错3:无法打开Excel文件→ Excel进程残留。任务管理器关掉所有Excel/WPS进程(wps.exe和et.exe),再跑流程。
报错4:中文乱码→ 读取Excel时指定编码:pd.read_excel('path').apply(lambda x: x.astype(str) if x.dtype == 'object' else x),或确保Excel文件是UTF-8。
报错5:openpyxl图表报错→ 数据引用范围不对。检查Reference的min_row和max_row是否覆盖所有数据行。
报错6:日期时间少了8小时→ COM接口时区问题。用openpyxl写入或把datetime转str后再写入。
报错7:NaN出现导致统计不对→ groupby前dropna()或fillna()。
报错8:merge后数据少了→ 注意how='inner'(交集)和how='left'(左表全保留)的区别。做对比分析用how='left'避免丢失数据。
内容标签:pandas数据分析、openpyxl报表、图表生成、飞书通知、自动化报告
作者:林焱