python自动化办公小结

在日常办公中,经常免不了和Excel打交道,每次手工处理数据,稍微不细心点。数据可能就出错了。而且重复的任务又会占据大量的工作时间。那有没有办法可以解决这些问题呢?

今天介绍一种方法,可以解决日常工作的重复工作,节省时间,从而优化自己工作。今天说的就是通过Python语言的selenium+numpy+js+pandas库。完成自动化办公。

首先,需要通过Python+Selenium+Js 封装一个函数get,用于在公司管理平台下载各类所需的数据表(如果数据是直接以excel提供,则忽略此步骤)。自动化办公目录图片如下:
123456.png
封装的数据获取的get函数:
from selenium import webdriver
import time,random
import json,os
from selenium.webdriver.support.select import Select
import cv2

'''封装函数,自动登录     //*[@id="img"]验证码xpath'''
class cook:
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(120)
        try:
            self.cook_login()
            time.sleep(3)
            if self.driver.title != '需求管理平台':
                print('cookie login fail')
                '''弹出框处理#send_keys(Keys.ENTER)'''
                self.driver.switch_to.alert.accept()
        except:
            time.sleep(2)
            self.driver.delete_all_cookies()
            self.driver.get('url')
            self.login()
            self.cookies_write()
            
    #cookies写入,从而每次调用可以跳过验证码
    def cookies_write(self):
        dictCookies = self.driver.get_cookies()
        jsonCookies = json.dumps(dictCookies)
        os.remove('C:/Users/lenovo/Downloads/cookies4.json')
        time.sleep(2)
        with open('C:/Users/lenovo/Downloads/cookies4.json', 'w') as f:
            f.write(jsonCookies)
        print(type(jsonCookies),jsonCookies)
        print('收集完成cookie')

    '''
    :param 账号密码
    '''
    def login(self,user='账号',pwd='密码'):
        time.sleep(1.5)
        self.driver.find_element_by_id('j_username').send_keys(user)
        time.sleep(1)
        self.driver.find_element_by_id('j_password').send_keys(pwd)
        # img_yzm = self.driver.find_element_by_xpath('//*[@id="img"]')
        # img_yzm.screenshot(r'D:\360MoveData\Users\lenovo\Music\Desktop\yzm.jpg')
        # time.sleep(1)
        # image1 = cv2.imread(r'D:\360MoveData\Users\lenovo\Music\Desktop\yzm.jpg')
        # cv2.imshow('image', image1)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()
        code = input('\n请输入验证码:')
        self.driver.find_element_by_id('code').send_keys(code)
        log_in = self.driver.find_element_by_xpath("//input[@value='登录']")
        log_in.click()
        while self.driver.title == '首页登录':
            self.login()

    def cook_login(self):
        with open('C:/Users/lenovo/Downloads/cookies4.json', 'r') as f:
            #, encoding='utf-8')
            listCookies = json.loads(f.read())
        self.driver.get('http://iimp.sh.cmcc/rip/login.do')
        self.driver.delete_all_cookies()
        for i in listCookies:
            self.driver.add_cookie(i)
        self.driver.get('http://iimp.sh.cmcc/rip/chaxun.do')
        self.cookies_write()

    ''':return 网址dict'''
    #返回各类数据的一个字典,从而可以通过链接进行下载
    def back(self):
        report_list = []
        for link in self.driver.find_elements_by_xpath("//*[@id='sf-menu2']/li/a"):
            herf = link.get_attribute('href')
            text = link.get_attribute('text')
            lis1 = [text, herf]
            report_list.append(lis1)
        report_list = dict(report_list)
        return report_list

    '''更改时间
    :param form H5标签的id
    :param t 更改的时间'''
    def alter_time(self,form, t):
        js = "document.getElementById('%s').removeAttribute('readonly');" % form
        self.driver.execute_script(js)
        js_value = "document.getElementById('%s').value='%s'" % (form, t)
        self.driver.execute_script(js_value)

    '''导出报表函数'''
    def report(self,name,start,end):
        report_list = self.back()
        if name == '政企业务需求报表':
            self.driver.get(report_list['政企业务需求报表'])
            self.driver.find_element_by_xpath(
                '//*[@id="bd"]/div[1]/div[2]/table/tbody/tr/td/table/tbody/tr/td/input').click()

        elif name == '政企KPI跟踪报表':
            self.driver.get(report_list['政企KPI跟踪报表'])
            self.driver.find_element_by_xpath(
                '//*[@id="bd"]/div[1]/div[2]/table/tbody/tr/td/table/tbody/tr/td/input').click()
            time.sleep(3)

        elif name == '需求确认时间查询报表':
            self.driver.get(report_list['需求确认时间查询报表'])
            self.alter_time('confirmTimeStart', start)
            self.alter_time('confirmTimeEnd', end)
            self.driver.find_element_by_xpath('// *[ @ id = "export"]').click()

        elif name == 'PATCH计划':
            self.driver.get(report_list['PATCH计划'])
            self.alter_time('planTimeStart', start)
            self.alter_time('planTimeEnd', end)
            self.driver.find_element_by_xpath(
                '//*[@id="bd"]/div/div[2]/table/tbody/tr/td/table/tbody/tr[10]/td/input[2]').click()

        elif name == '业支厂商工时报表':
            self.driver.get(report_list['业支厂商工时报表'])
            self.alter_time('planTimeStart', start)
            self.alter_time('planTimeEnd', end)
            self.driver.find_element_by_xpath(
                '//*[@id="bd"]/div/div[2]/table/tbody/tr/td/table/tbody/tr[2]/td/input[2]').click()

        elif name == '测试进度报表':
            self.driver.get(report_list['测试进度'])
            self.alter_time('planTimeStart', start)
            self.alter_time('planTimeEnd', end)
            time.sleep(1)
            self.driver.find_element_by_xpath('//*[@id="testPerson"]').clear()
            self.driver.find_element_by_xpath(
                '//*[@id="bd"]/div/form/div[1]/table/tbody/tr/td/table/tbody/tr[3]/td/input[2]').click()

        elif name == '缺陷工单修复时长报表':
            self.driver.get(report_list['缺陷工单修复时长报表'])
            self.alter_time('planOnlineTimeStart', start)
            self.alter_time('planOnlineTimeEnd', end)
            self.driver.find_element_by_xpath(
                '//*[@id="bd"]/div/div[2]/table/tbody/tr/td/table/tbody/tr[5]/td/input[2]').click()

        elif name == '需求查询':
            self.driver.get(report_list['需求查询'])
            self.alter_time('time', start)
            self.alter_time('time1', end)
            '''下拉选框选择'''
            Select(self.driver.find_element_by_xpath("//select[@id='remandType']")).select_by_visible_text('业务支撑')
            time.sleep(2)
            Select(self.driver.find_element_by_xpath("//select[@id='secondSelect']")).select_by_visible_text('集团下发')
            self.driver.find_element_by_xpath("//*[@name='importBtn']").click()
        elif name == '敏捷工时统计报表':
            self.driver.get(report_list['敏捷工时统计报表'])
            self.alter_time('planTimeStart', start)
            self.alter_time('planTimeEnd', end)
            self.driver.find_element_by_xpath('//*[@id="bd"]/div[1]/div[2]/table/tbody/tr/td/table/tbody/tr[4]/td/input[2]').click()
        else:
            print('发生错误,请检查判断条件')

    def quit(self):
        self.driver.quit()

准备工作完成后,然后利用Pandas对表格进行处理,处理数据的步骤:读取、排序、筛选、去重、计算时间差、透视表、交叉表,删除数据、时间修改以及excel的函数:计算首次上线、计算上线次数、计算最后一次上线等等。
以一个每日任务代码为例,代码如下:

'''政企KPI任务报表'''
from control.common.get import cook
from control.common import demand
import time, os, datetime
import pandas as pd
import warnings
warnings.filterwarnings('ignore')

# 每次记得更新时间
start = '2020-01-01'
end = '2021-01-31'

'''政企任务的报表下载'''
report1 = cook()
report1.report('PATCH计划', start, end)
report1.report('政企业务需求报表', start, end)
report1.report('政企KPI跟踪报表', start, end)

time.sleep(3)
#定义需要剔除考核的工单列表
zq_data = [政企工单列表]
sj_data = [数据工单列表]

#创建,处理后数据的导出路径
t1 = demand.ltime(0)
t1path = r'D:\数据统计\12.政企KPI日报/' + t1
if not os.path.exists(t1path):
    os.makedirs(t1path)
os.chdir(t1path)


def clean():
    time.sleep(2)
    #数据读取
    data1 = pd.read_excel(r'C:\Users\lenovo\Downloads\政企业务需求报表.xls')
    data2 = pd.read_excel(r'C:\Users\lenovo\Downloads\PATCH计划2.xls')

    df1 = data1.copy()
    df1.index = df1['工单编号']
    #数据排序和计算
    df1.sort_values(by=['工单编号', '上线时间'], inplace=True, ascending=True)
    df1['外部工时'][df1['是否重复'] == '是'] = df1[df1['是否重复'] == '是']['外部工时'] / 2

    '''删除指定的工单'''
    for i in zq_data:
        demand.drop_data(df1, i)
    '''修改时间'''
    df1.loc[工单编号1, '上线时间'] = '2018-04-24'
    df1.loc[工单编号2, '上线时间'] = '2018-03-30'
    df1.loc[工单编号3, '创建时间'] = '2018-06-12'
    df1.loc[工单编号4, '创建时间'] = '2018-06-12'
    df1.loc[工单编号5, '创建时间'] = '2018-06-28'
    
    #更改值为时间格式
    df1['需求确认'] = pd.to_datetime(df1['需求确认'])  # ,format='%Y-%m-%d')
    df1['到达时间'] = pd.to_datetime(df1['到达时间'])
    df1['上线时间'] = pd.to_datetime(df1['上线时间'])
    lst = df1[df1['到达时间'].isnull()].工单编号.unique().tolist()
    print(lst)
    #替换指定工单时间
    for i in lst:
        df1.loc[i]['到达时间'] = df1.loc[i]['需求确认'] - datetime.timedelta(2)
    df1.loc['政企-2018-17184', '到达时间'] = pd.to_datetime('2018-12-08')
    # 修改时间为年-月-日  去除时分秒
    df1['需求确认'] = df1['需求确认'].apply(lambda x: x.strftime('%Y-%m-%d'))
    df1['到达时间'] = df1['到达时间'].apply(lambda x: x.strftime('%Y-%m-%d'))
    df1['上线时间'] = df1['上线时间'].apply(lambda x: x.strftime('%Y-%m-%d'))

    df2 = data2.copy()
    df2.index = df2['工单编号']
    df2['计划上线时间'] = pd.to_datetime(df2['计划上线时间'])
    df2.sort_values(by='计划上线时间', inplace=True, ascending=True)
    #计算最后一次上线工单
    df2 = df2.groupby('工单编号').last()
    df2['计划上线时间'] = df2['计划上线时间'].apply(lambda x: x.strftime('%Y-%m-%d'))

    # 筛选出指定部门的工单
    df2 = df2[df2['提出部门'].str.contains('数据业务中心') | df2['提出部门'].str.contains('产品运营支撑中心') | df2['提出部门'].str.contains('客户响应与产品运营中心')]
    # 筛选出指定需求负责人的工单,后期用字典实现筛选
    df2 = df2[df2['需求负责人'].str.contains('name1') | df2['需求负责人'].str.contains('name2') |
              df2['需求负责人'].str.contains('name3') | df2['需求负责人'].str.contains('name4') |
              df2['需求负责人'].str.contains('name5') | df2['需求负责人'].str.contains('name6') |
              df2['需求负责人'].str.contains('name7') | df2['需求负责人'].str.contains('name8') |
              df2['需求负责人'].str.contains('name9') | df2['需求负责人'].str.contains('name10') |
              df2['需求负责人'].str.contains('name11') | df2['需求负责人'].str.contains('name12')]
    
    # 删除指定的行
    for i in sj_data:
        try:
            demand.drop_data(df2, i)
        except:
            print('无法删除的行:%s' % i)

    df2['工单编号'] = df2.index
    data3 = pd.read_excel(r'D:\360MoveData\Users\lenovo\Music\Desktop\svn\政企KPI日报.xlsx')
    data3.index = data3['工单编号']

    a = data3[data3.index.str.contains('数据')][['需求确认', '到达时间']]
    a['需求确认'] = pd.to_datetime(a['需求确认'])
    a['到达时间'] = pd.to_datetime(a['到达时间'])
    a['需求确认'] = a['需求确认'].apply(lambda x: x.strftime('%Y-%m-%d'))
    a['到达时间'] = a['到达时间'].apply(lambda x: x.strftime('%Y-%m-%d'))
    #两张数据表合并
    df2 = pd.merge(df2, a, left_index=True, right_index=True, how='left')
    concat2 = df2[['工单编号', '工单名称', '工单简介', '创建人', '需求负责人', '创建时间', '需求确认', '计划上线时间', '到达时间']]
    #修改列名
    concat2.rename(columns={'计划上线时间': '上线时间', '工单简介': '简介'}, inplace=True)
    df = pd.concat([df1, concat2])
    #数据排序,后期用insert插入方式实现
    df = df[['工单编号', '工单名称', '简介', '创建人', '需求负责人', '创建时间', '需求确认', '上线时间', '到达时间',
             '期望上线时间', '需求期望上线时间', '到达总控时间', '一级总控拆分', '来源部门', '工单大类', '工单类型',
             '一级业务标签', '二级业务标签', '一级指标库标签', '二级指标库标签', '三级指标库标签', '上线次数', '外部工时',
             '是否重复']]
    print('数据已经处理完成,正在导出中……')
    os.chdir(r'D:\360MoveData\Users\lenovo\Music\Desktop')
    
    # 写入Excel,并导出
    shet = pd.ExcelWriter('政企KPI日报.xlsx')
    df.to_excel(shet, sheet_name='政企KPI报表', index=False)
    df1.to_excel(shet, sheet_name='政企需求表')
    df2.to_excel(shet, sheet_name='patch计划表')
    shet.close()

    print('本次政企据共%i条' % len(df1))
    print('本次数据共%i条' % len(df2))
    print('本次政企日报数据共%i条' % len(df))
    print('\n在' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '分,导出处理后数据')

通过自动化,以前每次一小时左右完成的数据处理任务,现在只需要几分钟就可以完成。而且自动化处理的数据准确性高,防止手工操作可能由于一些原因导致数据的不准确性。自动化省出来工作时间,从而可以用于继续封装其他任务,提高整体效率。从而进入一个良性循环,低成本,高回报。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容