python 让你的报表做得更好

python可以让你的报表做得又快又好,今天给大家分享一篇python自动化办公的干货。

总体思路是:

1. 从网上获取科幻电影排行榜数据

2.将获取的数据写入excel,并自动修改excel样式

代码所需要的第三方库为requests,pandas,openpyxl,pywin32。

pip install requests
pip install pandas
pip install openpyxl
pip install pywin32

从网上获取科幻电影排行榜数据,主要使用requests库从网页获取数据。

import requests
import pandas as pd

# 获取一页的数据
def get_one_page_data(start: int = 0):
    '''
    :param start: 每页20条数据,start的值为0,1,2,...
    :return:
    '''
    url = f"https://movie.douban.com/j/chart/top_list?type=17&interval_id=100%3A90&action=&start={start * 20}&limit=20"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
    }
    resp = requests.get(url=url, headers=headers)
    # 如果请求正确,则返回数据
    if resp.status_code == 200:
        resp = resp.json()
        # 中文字段名,与返回结果的英文字段名要一一对应
        columns = ['rank', 'title', 'types', 'regions', 'actors', 'rating', 'cover_url', 'is_playable', 'id', 'url',
                   'release_date', 'actor_count', 'vote_count', 'score', 'is_watched']
        columns_cn = ['排名', '电影名', '类型', '地区', '演员列表', '评价', '背景图片', '可播放', 'id', 'url',
                      '上映时间', '演员数量', '评价数', '评分', '可观看']
        # 构建一个空数据,为了确保返回数据为空时,数据格式保持一致
        data = {}
        for col in columns:
            data[col] = []
        # 往data里面添加数据
        for res in resp:
            for key, value in res.items():
                if type(value) == list:
                    value = ','.join(value)
                data[key] = data.get(key, []) + [value]
        data = pd.DataFrame(data)
        # 将data的行索引改为中文
        data.columns = columns_cn
        # 将'可播放'字段的true和false改为是、否
        data['可播放'] = data['可播放'].map(lambda x: '是' if x else '否')
        # 将'可观看'字段的true和false改为是、否
        data['可观看'] = data['可观看'].map(lambda x: '是' if x else '否')
        return data
    raise ValueError("请求错误")


# 获取所有页的数据并写入excel表格
def get_total_data():
    datas = []
    for i in range(20):
        data = get_one_page_data(i)
        # 如果返回的数据为空,则表示已经获取完毕
        if data.empty:
            break
        datas.append(data)
        sleep(2) # 等待2秒,防止数据获取得太快
    datas = pd.concat(datas, axis=0)
    datas.to_excel('科幻片排行榜.xlsx', sheet_name='sheet1', index=False)

执行get_total_data()方法,生成excel表格。因为设置的excel格式为xlsx,所以在使用pandas写入excel方法时,需要openpyxl引擎。这就是为什么全文都没有看见openpyxl的使用,却依然需要安装openpyxl库。

当你学会了数据抓取,就一定会学数据分析,pands是数据分析最好用的工具。当你想要实现数据永久化,无论是写入数据库还是写入excel,pandas也是你的最佳选择。

get_total_data()

生成的excel效果如下,可以看到生成的excel样式比较丑,所以这里使用pywin32自动化处理excel,使excel更加beautiful。美化需求如下:

1.给excel所有激活的内容添加边框

2.给第一行添加筛选功能

3.冻结第二行第二列窗口,在上下左右拉动的时候,也可以一直看到电影名

4.用红色标注“莱昂纳多”主演的电影,让人一眼就知道男神有哪些电影上榜了

from win32com.client import Dispatch

# 调整excel格式
def adjust_excel_format():
    excel = Dispatch('Excel.Application')
    excel.Visible = 1
    base_path = os.path.dirname(__file__)
    wb = excel.WorkBooks.Open(os.path.join(base_path, '科幻片排行榜.xlsx'))  # 注意:这里只能传绝对路径,不能传相对路径
    ws = wb.Worksheets('sheet1')
    rng = ws.UsedRange
    cols = rng.Columns.Count
    rows = rng.Rows.Count
    # 给excel添加边框
    rng.Borders.LineStyle = 1
    rng.Borders.Weight = 2
    # 调整宽度、自动换行
    for col in range(1, cols + 1):
        ws.Columns(col).AutoFit() # 自动调整宽度
        ws.Columns(col).WrapText = True  # 自动换行
    ws.Columns(2).ColumnWidth = 15
    ws.Columns(3).ColumnWidth = 20
    ws.Columns(4).ColumnWidth = 20
    ws.Columns(5).ColumnWidth = 100
    # 冻结excel窗口
    ws.Range("C2").Select()
    excel.ActiveWindow.FreezePanes = True
    # 给第一行添加筛选
    ws.Range("A1").CurrentRegion.AutoFilter(1)
    # 将”莱昂纳多“主演的电源名标红
    target = "莱昂纳多"
    for i in range(1, rows + 1):
        target_rng = ws.Range(f"E{i}")
        if target in target_rng.Text:
            ws.Range(f"B{i}").Interior.Color = 255  # 单元格标为红色
    wb.Save()
    wb.Close()
    excel.Quit()

执行adjust_excel_format()方法,美化后的效果,是不是比之前的原始版本更nice。

全部代码如下:

import requests
import pandas as pd
from time import sleep
from win32com.client import Dispatch
import os


# 获取一页的数据
def get_one_page_data(start: int = 0):
    '''
    :param start: 每页20条数据,start的值为0,1,2,...
    :return:
    '''
    url = f"https://movie.douban.com/j/chart/top_list?type=17&interval_id=100%3A90&action=&start={start * 20}&limit=20"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
    }
    resp = requests.get(url=url, headers=headers)
    # 如果请求正确,则返回数据
    if resp.status_code == 200:
        resp = resp.json()
        # 中文字段名,与返回结果的英文字段名要一一对应
        columns = ['rank', 'title', 'types', 'regions', 'actors', 'rating', 'cover_url', 'is_playable', 'id', 'url',
                   'release_date', 'actor_count', 'vote_count', 'score', 'is_watched']
        columns_cn = ['排名', '电影名', '类型', '地区', '演员列表', '评价', '背景图片', '可播放', 'id', 'url',
                      '上映时间', '演员数量', '评价数', '评分', '可观看']
        # 构建一个空数据,为了确保返回数据为空时,数据格式保持一致
        data = {}
        for col in columns:
            data[col] = []
        # 往data里面添加数据
        for res in resp:
            for key, value in res.items():
                if type(value) == list:
                    value = ','.join(value)
                data[key] = data.get(key, []) + [value]
        data = pd.DataFrame(data)
        # 将data的行索引改为中文
        data.columns = columns_cn
        # 将'可播放'字段的true和false改为是、否
        data['可播放'] = data['可播放'].map(lambda x: '是' if x else '否')
        # 将'可观看'字段的true和false改为是、否
        data['可观看'] = data['可观看'].map(lambda x: '是' if x else '否')
        return data
    raise ValueError("请求错误")


# 获取所有页的数据并写入excel表格
def get_total_data():
    datas = []
    for i in range(20):
        data = get_one_page_data(i)
        # 如果返回的数据为空,则表示已经获取完毕
        if data.empty:
            break
        datas.append(data)
        sleep(2) # 等待2秒,防止数据获取得太快
    datas = pd.concat(datas, axis=0)
    datas.to_excel('科幻片排行榜.xlsx', sheet_name='sheet1', index=False)


# 调整excel格式
def adjust_excel_format():
    excel = Dispatch('Excel.Application')
    excel.Visible = 1
    base_path = os.path.dirname(__file__)
    wb = excel.WorkBooks.Open(os.path.join(base_path, '科幻片排行榜.xlsx'))  # 注意:这里只能传绝对路径,不能传相对路径
    ws = wb.Worksheets('sheet1')
    rng = ws.UsedRange
    cols = rng.Columns.Count
    rows = rng.Rows.Count
    # 给excel添加边框
    rng.Borders.LineStyle = 1
    rng.Borders.Weight = 2
    # 调整宽度、自动换行
    for col in range(1, cols + 1):
        ws.Columns(col).AutoFit() # 自动调整宽度
        ws.Columns(col).WrapText = True  # 自动换行
    ws.Columns(2).ColumnWidth = 15
    ws.Columns(3).ColumnWidth = 20
    ws.Columns(4).ColumnWidth = 20
    ws.Columns(5).ColumnWidth = 100
    # 冻结excel窗口
    ws.Range("C2").Select()
    excel.ActiveWindow.FreezePanes = True
    # 给第一行添加筛选
    ws.Range("A1").CurrentRegion.AutoFilter(1)
    # 将”莱昂纳多“主演的电源名标红
    target = "莱昂纳多"
    for i in range(1, rows + 1):
        target_rng = ws.Range(f"E{i}")
        if target in target_rng.Text:
            ws.Range(f"B{i}").Interior.Color = 255  # 单元格标为红色
    wb.Save()
    wb.Close()
    excel.Quit()

if __name__ == '__main__':
    get_total_data()
    adjust_excel_format()

猜你喜欢

转载自blog.csdn.net/spiderwower/article/details/136429585
今日推荐