Excel处理
需要安装xlrd、xlwt、xlutils三个包
Excel读
import xlrd
#文件载入
wb = xlrd.open_workbook('../test/datafiles/test.xls')
# 获取sheet信息
# 获取sheet数量
print("sheet 数量:", wb.nsheets)
# 获取sheet名
sheets = wb.sheets()
print("sheet名称:", wb.sheet_names())
# 根据索引-通过sheet对象获得
sh = wb.sheet_by_index(0)
print(sh.name)
# 根据名称-通过sheet对象获得
sh = wb.sheet_by_name('fruits')
print(sh.name)
#
# 取整行、整列
print("sheet %s 有 %s 行 %s 列" % (sh.name, sh.nrows, sh.ncols))
print("第一行的值为:", sh.row_values(0))
print("第二列的值为:", sh.col_values(1))
# 单元格操作
cell = sh.cell(0, 1)
print("第一行的第二列的值:", cell.value)
#获取单元格类型 0 空值; 1 字符串; 2 数值; 3 日期
print("第二行第二列的类型是:", sh.cell(11, 1).ctype)
# 数值
cell = sh.cell(2, 3)
if cell.ctype == 2:
print("第3行的第4列的值:", int(cell.value))
print("最后一行最后一列的值:", sh.cell_value(-1, -1))
# 日期时间
sh = wb.sheet_by_name('fruits')
cell = sh.cell(1, 0)
if cell.ctype == 3:
value = xlrd.xldate_as_datetime(cell.value, 0)# 获得一datetime对象
print(value.strftime('%Y-%m-%d'))
for i in range(sh.nrows):#读行
for j in range(sh.ncols):#读列
cell = sh.cell(i, j)
value = cell.value
if cell.ctype == 2:
if j == 4:
value = int(value)
elif j == 5:
value = round(value, 1)
elif j == 6 or j == 7:
value = round(value, 2)
elif cell.ctype == 3:
d = xlrd.xldate_as_datetime(value, 0)
value = d.strftime('%Y-%m-%d')
print(str(value).center(10), end='\t')#字符串不足10位补满10位后居中
print()
Excel写
import xlwt
wb = xlwt.Workbook()#创建一个Excel对象
sh = wb.add_sheet('第一季度', cell_overwrite_ok=True)#某个单元格可以复写,多次写入不报错
sh.write(0, 0, '姓名')
sh.write(0, 1, '1月')
sh.write(0, 2, '2月')
sh.write(0, 3, '3月')
sh = wb.add_sheet('平方值', cell_overwrite_ok=True)
for i in range(20):
sh.row(i).write(0, i+1)#在第i行第1列写内容
sh.row(i).write(1, (i+1) * (i+1))#在第i行第2列写内容
wb.save('../test/datafiles/test_write.xls')
Excel写入读出的内容&编辑写入后的
读写改Excel
rfile_ph='../test/datafiles/test.xls'
wfile_ph='../test/datafiles/test_write1.xls'
#写入读出
import xlwt
import xlrd
re = xlrd.open_workbook(rfile_ph).sheet_by_index(0)#获取第一个页签对象
we = xlwt.Workbook()#创建一个Excel对象
sh = we.add_sheet('复制后sheet1', cell_overwrite_ok=True)#某个单元格可以复写,多次写入不报错
for i in range(re.nrows):#读行
for j in range(re.ncols):#读列
sh.write(i, j, re.cell(i, j).value) # 在第i行第1列写内容
we.save(wfile_ph)
#修改
from xlutils import copy
rb = xlrd.open_workbook(wfile_ph) #打开文件
wb = copy.copy(rb) #利用xlutils.copy下的copy函数复制
ws = wb.get_sheet(0) #获取表单0
ws.write(0, 0, 'changed!') #改变(0,0)的值
ws.write(8,0,label = '好的') #增加(8,0)的值
wb.save(wfile_ph)
Word处理
Word写
需要安装python-docx包
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.shared import Mm, Inches, Pt, RGBColor
doc = Document()
title = doc.add_heading("每日运营数据分析报告", 0)#增加标题 级别1
title.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER#一级标题并且居中
doc.add_paragraph('此报告为Python脚本每日自动生成,共分为三部分')#新增段落
doc.add_paragraph('数据汇总', style="List Number")#新增段落,风格为列表 1.数据汇总
doc.add_paragraph('线上数据', style="List Number")#新增段落,风格为列表 2.线上数据
doc.add_paragraph('线下数据', style="List Number")
doc.add_heading('数据汇总', 1)#增加标题 级别2
online_sale = 292932
shop_sale = 192837
pg = doc.add_paragraph('昨日线上销售总额为{:,}元,线下销售总额为{:,}元,'
'总计销售额为{:,}元'.format(online_sale, shop_sale, online_sale + shop_sale))
pg.paragraph_format.left_indent = Mm(5)#增加5毫米缩进
doc.add_heading('线上数据分析', 1)
pg = doc.add_paragraph('各渠道类型销售金额分布如下:')
pg.add_run('免费渠道为292189元,付费渠道为283272元')#增加文本
doc.add_picture('../test/datafiles/online_sale.png', width=Inches(5.5))#增加图片并限制大小
doc.add_paragraph('建议改进方案:')
doc.add_paragraph('增加付费广告投放', style="List Bullet")#新增段落,风格为列表-小圆点 ·增加付费广告投放
doc.add_paragraph('提高着陆页的加载速度', style="List Bullet")#新增段落,风格为列表-小圆点 ·提高着陆页的加载速度
doc.add_paragraph('减少页面跳转', style="List Bullet")
doc.add_heading('线下数据分析', 1)
table = doc.add_table(rows=1, cols=3)#新增表格
cells = table.rows[0].cells
cells[0].text = '城市'
cells[1].text = '销量'
records = [
['北京', '100'],
['上海', '120'],
['天津', '300'],
['河北', '200'],
['广东', '400'],
['辽宁', '500'],
['江苏', '700'],
['湖南', '600']
]
for city, amount in records:
cells = table.add_row().cells
cells[0].text = city
cells[1].text = amount
doc.add_picture('../test/datafiles/city_sale.png', width=Inches(5.5))
graph = doc.add_paragraph()
graph.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT #右对齐
graph.add_run('报告撰写人:').bold = True
graph.add_run('刘德华')
graph = doc.add_paragraph()
graph.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
graph.add_run('联系邮箱:').bold = True
run = graph.add_run('xxxx@email.com')
run.font.name = 'Times New Roman'#字体
run.font.size = Pt(12)#大小
run.italic = True#斜体
run.underline = True#下划线
doc.add_page_break()#强制增加分页
graph = doc.add_paragraph()
graph.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
run = graph.add_run('谢谢观看')
run.font.color.rgb = RGBColor(255, 0, 0)#颜色 RGB
doc.add_paragraph('此报告为机密文件,请勿泄露', style="Intense Quote")
doc.save('../test/datafiles/daily_report.docx')
Word转PDF
需要安装doxc2pdf包
from docx2pdf import convert
convert('../test/datafiles/daily_report.docx', '../test/datafiles/运营报告.pdf')
PDF处理
PDF读取
需要安装pdfminer包
from docx2pdf import convert
convert('../test/datafiles/daily_report.docx', '../test/datafiles/运营报告.pdf')
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfparser import PDFParser
from io import StringIO
output_string = StringIO()
with open('../test/datafiles/运营报告.pdf', 'rb') as f:
# 从文件句柄创建一个pdf解析对象
parser = PDFParser(f)
# 创建pdf文档对象,存储文档结构
doc = PDFDocument(parser)
# 创建一个pdf资源管理对象,存储共享资源
rm = PDFResourceManager()
# 创建一个device对象,指定参数,行距、边距等,这里使用默认参数
device = TextConverter(rm, output_string, laparams=LAParams())
# 创建一个解释对象
interpreter = PDFPageInterpreter(rm, device)
# 按页解析pdf文件
for page in PDFPage.create_pages(doc):
# 将内容读取到缓存
interpreter.process_page(page)
# 打印出缓冲区的内容
print(output_string.getvalue())
PDF读取
需要安装pypdf2包
#添加水印
from PyPDF2 import PdfFileReader, PdfFileWriter
watermark_pdf = PdfFileReader('../test/datafiles/水印.pdf')
watermark = watermark_pdf.getPage(0)#读取第一页
input_pdf = PdfFileReader('../test/datafiles/运营报告.pdf')
writer = PdfFileWriter()
for pn in range(input_pdf.getNumPages()):
page = input_pdf.getPage(pn)
page.mergePage(watermark)#合并页
writer.addPage(page)
with open('../test/datafiles/包含水印.pdf', 'wb') as f:
writer.write(f)
邮件发送
不需要安装其他包,需要用你本地自己的邮箱发送,所以需要去邮箱设置开启POP3/SMTP服务。
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 1. 设置服务器所需信息
# SMTP服务器域名
mail_host = 'smtp.qq.com'
# 邮箱用户名
mail_user = '651435666@qq.com'
# 密码或授权码
mail_pass = '这里填写授权码'
# 邮件发送方邮箱地址,有可能和用户名不一样
sender = '651435666@qq.com'
# 邮件接收方邮箱地址,可以有多个收件人,所以用列表
receivers = ['651435666@qq.com']
# 2 设置邮件内容
# 可以带附件的邮件消息对象
message = MIMEMultipart()
# 邮件主题
message['Subject'] = '每日运营报告'
# 发送方信息
message['From'] = sender
# 接受方信息
message['To'] = receivers[0]
# 2.1 邮件正文
content = MIMEText('详情请见附件','plain','utf-8')
# 将正文添加到消息对象中
message.attach(content)
# 2.2 构造附件
with open('../test/datafiles/运营报告.pdf', 'rb') as f:
# 设置附件的文件路径
att = MIMEText(f.read(), 'base64', 'utf-8')
# 设置附件头信息:文件类型、文件名
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename="daily_report.pdf"'
# 将附件添加到邮件内容中
message.attach(att)
# 3. 发送邮件
try:
smtpObj = smtplib.SMTP_SSL(mail_host, 465)
# 设置日志级别,这样万一出错就会有详细的输出
smtpObj.set_debuglevel(1)
# 登录到服务器
smtpObj.login(mail_user, mail_pass)
#发送
smtpObj.sendmail(sender, receivers, message.as_string())
smtpObj.quit()
print('邮件发送成功')
except smtplib.SMTPException as e:
print('error', e)
爬虫
网页抓取
#网页的抓取
import requests
r=requests.get('https://news.sina.com.cn/')
#设置编码格式
r.encoding='utf-8'
#查看返回的状态码 200是正常 400找不到 500他们服务器有问题
print(r.status_code)
#若返回的状态码不是200,抛异常,后续代码不再执行
r.raise_for_status()
#查看网页的内容
# print(r.text)
#带参数的URL-动态⽣成参数
params = {'product_id': '123', 'key': 'iphone'}
r=requests.get('https://item.jd.com/100008567426.html', params=params)
print(r.status_code)
# 设置头信息
headers = {
'Cookie': 'll="108288"; bid=v8-QyOSurlo',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
}
# 使⽤GET⽅法请求服务器
response = requests.request("GET", 'https://httpbin.org/post', headers=headers)
# 当返回的状态码不是2xx时,将会抛出异常
response.raise_for_status()
# 打印具体的状态码数值
print(response.status_code)
if response.status_code == 200:
print("ok")
else:
print("error")
网页处理
需要引用beautifulsoap4包
#网页的处理
from bs4 import BeautifulSoup
with open('../test/datafiles/python.html', encoding='utf-8') as f:
text = f.read()
# 以字符串对象创建BeautifulSoup对象
bs = BeautifulSoup(text, 'lxml')
# ⼯整的打印出所有HTML代码
print(bs.prettify())
# title节点的名称
print(bs.title.name)
# title节点的⽂本
print(bs.title.text)
# title节点的⽗节点名称
print(bs.title.parent.name)
# 第⼀个p节点的⽗节点的所有⼦节点
print(bs.p.parent.children)
# p节点的class属性
print(bs.p['class'])
# 第⼀个a标签节点
print(bs.a)
# 所有的a标签节点
print(bs.find_all('a'))
# 属性id为title1的第⼀个节点
print(bs.find(id='title1'))
# 找出所有class属性为paragraph的p标签,注意class是Python中的关键字,所以在传参数时加了⼀个下划线。
bs.find_all('p', class_='paragraph')
# 第⼀个a节点
print(bs.find('a'))
# 找出所有的a节点,并打印他们的⽂本
for a in bs.find_all('a'):
print(a.text)
# 获取⽂档内所有⽂字内容
print(bs.get_text())
爬取实战
#网站爬取
import requests
from bs4 import BeautifulSoup
# 起始⻚⾯
start_url = 'http://quotes.toscrape.com'
# 刚开始的时候下⼀⻚就是起始⻚
next_page_url = start_url
# 不停的获取下⼀⻚
while next_page_url:
r = requests.get(next_page_url)
r.raise_for_status()
bs = BeautifulSoup(r.text, 'html.parser')
# 解析出当前⻚⾯的内容
div_list = bs.find_all('div', class_='quote')
for div in div_list:
print(div.small.text, ':', div.span.text)
# 获取下⼀⻚按钮
next_page = bs.find('li', class_='next')
if not next_page:
# 如果没有下⼀⻚,结束爬⾍
break
# 取下⼀⻚的链接
next_page_url = next_page.a['href']
# 拼装成完整的URL
next_page_url = start_url + next_page_url
网友评论