python3从本地excel表格获取账号,实现后台系统的登录,并获取运费后保存到表格中

1、首先有一个账号的excel文件,里面包含企业名称、登录账号以及登录密码;

2、获取账号文件里面的信息,实现模拟登录,登录成功则获取运费,登录失败则提示并且将失败的手机号颜色标红;

3、后台网站用XXXX代替。

#!/usr/bin/env python
# coding=utf-8
# 获取后台系统的运费规则,保存到表格中,其中登录账号从本地表格中获取

import requests
from bs4 import BeautifulSoup
from lxml import etree
from openpyxl import Workbook
import os,re,time
from fileread import ProcessData
from convert import Convert

class CBS_crawl(object):
    def __init__(self, username, password):
        # 初始化headers实例
        self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0",
                        "Referer": "https://cbs.XXXX.com/login.html"
                        }
        # 账号核实界面
        self.post_url = "https://cbs.XXXX.com/j_spring_security_check"
        # session会话对象
        self.session = requests.session()
        self.username = username
        self.password = password
        self.data = ['入驻企业名称','运费内容','运费区域']
        self.wb = Workbook()
        self.datavalue = []

    # 提取表单登录信息(可以和模拟登陆合并成一个)
    def get_login_info(self):
        data = {
            "j_username": self.username,
            "j_password": self.password
        }
        return data
    # 模拟登录
    def login(self):
        data = self.get_login_info()
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0",
                   "Referer": self.post_url,
                   "X-Requested-With": "XMLHttpRequest"
                   }
        try:
            login_page = self.session.post(self.post_url, data=data, headers=headers)
            # print(login_page.text)
            if "errorMsg" in login_page.text:
                print("登录失败,错误的手机号码或密码!")
                 # 将登录失败的手机号添加到一个列表中,颜色变为红色
                fail_phone = []
                fail_phone.append(self.username)
                ProcessData().fail_high_light(fail_phone)                
            if "</span>首页" in login_page.text:
                print("欢迎您'%s',成功登陆CBS管理系统!"%self.username)
                # 登录成功的手机号码添加到列表中,颜色变为黑色,考虑之前登录失败后来登录成功的情况
                success_phone = []
                success_phone.append(self.username)
                ProcessData().success_high_light(success_phone)
                self.freight_on_list()
                # 只要有登录成功的手机号,最后才会去调用合并功能
                return len(success_phone)

        except Exception as e:
            print(e)
            # print("登陆成功!")
    #获取运费的信息
    def freight_on_list(self):
        # 系统设置网址,获取商家名字
        company_url = "https://cbs.XXXX.com/system/companyshow.html"    
        # 注意company_list返回的是一个response对象,需加.text才能显示具体网页内容
        company_list = self.session.post(company_url, headers=self.headers)
        company_html = etree.HTML(company_list.text)
        # 获取商家名称,首尾有空格
        company_name = company_html.xpath("//div[@id='tabs-1']/p[1]/span/text()")

        # 运费网址
        freight_list_url = "https://cbs.XXXX.com/shipfee/shipfeesupfee.html"
        freight_list = self.session.post(freight_list_url, headers=self.headers)
        # 利用xpath规则提取运费的ID、运费内容等信息
        html = etree.HTML(freight_list.text)
        # 提取运费id号,如果有那么freight_id长度为2,没有长度为1
        freight_id = html.xpath('//div/form[@id="shipfeeForm"]/input/@value')
        # 运费内容,可能会有多个情况
        freight_content = html.xpath('//table[@class="stdtable"]/tbody/tr/td[2]/text()')
         # 运费区域
        freight_area = html.xpath('//table[@class="stdtable"]/tbody/tr/td[3]/text()')
        # 获取模板类型
        patt = re.compile(r'checked="checked" value="(\d+)"')
        # 如果结果是1代表全国统一计费,如果是2代表按区域计费,str类型
        mould_type = patt.search(freight_list.content.decode('utf-8')).group(1)
        # 肯定有运费内容情况
        if len(freight_content) != 0:
            for i in range(len(freight_content)):
                 # 有运费id,有运费内容
                if len(freight_id) == 2:
                    if mould_type == '1':
                        freight_content = freight_content
                    # 只有这种情况下,才有可能出现,多个运费条款,一个全国区域的情况,为了列表长度统一,所以乘
                        freight_area = ["模板类型:全国统一计费,运费区域全国"]*len(freight_content)
                    elif mould_type == '2':
                        freight_area = freight_area
                        freight_content = freight_content
        # 无运费情况
        else:
            # 有id,无运费
            if len(freight_id) == 2:
                freight_content = ["运费添加过,但是没有运费条款,默认包邮"]
                freight_area  = ["运费添加过,但是没有运费条款,区域全国"]
            # 无id,无运费
            else:
                freight_content = ["从未设置过运费,默认包邮"]
                freight_area  = ["从未设置过运费,区域全国"]
        # 处理运费内容到临时文件夹的表格中
        self.save_content(company_name,freight_content,freight_area)
    def save_content(self,company_name,freight_content,freight_area):
        # company_name是列表并且只有一个值,所以是0,并去除首尾空格
        print("'%s'运费处理中...."%company_name[0].strip())
        # 如果有多个运费,那么企业名称也相应的有多个,方便写入
        company_name_list = company_name*(len(freight_content))
        ws = self.wb.active
        ws.title = '运费规则'  # 修改第一个sheet表名
        # 先写入表头
        for head in range(1,len(self.data)+1):
            ws.cell(row = 1,column=head,value=self.data[head-1])
        # 从第2行开始以后写入N行1列企业名称
        for i in range(2,len(freight_content)+2):
            ws.cell(row =i ,column = 1,value=company_name_list[i-2].strip())
        # 从第2行开始以后写入N行2列运费规则
        for i in range(2,len(freight_content)+2):
            ws.cell(row =i ,column = 2,value=freight_content[i-2])
        # 从第2行开始以后写入N行3列运费区域
        for j in range(2,len(freight_area)+2):
            ws.cell(row =j ,column = 3,value=freight_area[j-2])
        # 创建临时文件夹,如果不存在则创建,存在则不创建
        if not os.path.exists('./临时文件'):
            os.makedirs('./临时文件')
            # 隐藏文件夹,不能隐藏否则搜索不到,只能合并完最后删除掉此文件夹
            # os.popen('attrib +h ' + './临时文件')
        # 临时文件夹中的文件命名
        file = './临时文件/' + company_name[0].strip() +"-运费规则.xlsx"
        self.wb.save(file)
        print("以上数据处理完毕!"+'\n')

if __name__ == "__main__":
    try:
        data_dict = ProcessData().getData()
        # print(data_dict)
        # 将符合要求的11位手机号和不是空的密码存入新字典
        new_data_dict = {}
        for key, value in data_dict.items():
            if len(key) == 11:
                if value != 'None':
                    new_data_dict[key] = value
                else:
                    print("\n"+"账号'%s'此行密码不能为空,请核实账号表格!" % key)
                    ProcessData().fail_high_light(key)
            elif key != 'None' and len(key) !=11:
                print("\n"+"账号'%s'此行手机号码输入有误,请核实!"%key)
                ProcessData().fail_high_light(key)
            else:
                print("\n"+"手机号码有空值,请核实!")
        if new_data_dict:
            count = 0
            for key, value in new_data_dict.items():
                username = key
                password = value
                print("\n"+"尝试登录账号'%s'中..." % (username))
                az = CBS_crawl(username, password)
                count = az.login()
                time.sleep(2)
            # 调用convert文件的main模块,实现合并文件,只有有登录成功的号码才会去调用合并功能
            if count:
                Convert().main()
            else:
                # 如果没有一个登录成功的账号,返回提示
                print("\n" + "抱歉,以上均没有符合条件的登录账号,请核实账号表格!")
        else:
            print("\n"+"抱歉,以上均没有符合条件的登录账号,请核实账号表格!")
        input('\n'+'请按回车键退出!')  # 目的执行.bat脚本的时候窗口不会闪退
    except Exception as e:
        print("出错了,问题为:",e)
        input('\n'+'请按回车键退出!')  # 目的执行.bat脚本的时候窗口不会闪退
#!/usr/bin/env python
# coding=utf-8
# 这里面处理并获取账号信息,以及将登录失败的手机号标颜色
import openpyxl
from openpyxl.styles import colors
from openpyxl.styles import Font

class ProcessData(object):
    def __init__(self):
        self.file_name = "./账号.xlsx"
        self.wb = openpyxl.load_workbook(self.file_name)
        self.sheet = self.wb.worksheets[0]
        # try:
        #     self.file_name = "./账号.xlsx"
        #     self.wb = openpyxl.load_workbook(self.file_name)
        #     self.sheet = self.wb.worksheets[0]
        # except Exception as e:
        #     print("错误,问题为:",e)
    # 获取账号信息
    def getData(self):
        # 将来是字典的key值
        self.data_list_keys = []
        # 将来是字典的values值
        data_list_values = []
        data_dict = {}
        # 获取B列账号信息
        for cellobj_keys in self.sheet['B']:
            self.data_list_keys.append(cellobj_keys.value)
        # 获取D列密码信息
        for cellobj_values in self.sheet['D']:
            data_list_values.append(cellobj_values.value)
        # 组合成字典,去掉第一行
        for i in range(1,len(data_list_values)):
            data_dict[str(self.data_list_keys[i])] = str(data_list_values[i])
        # print(data_dict.items())
        # for key in data_dict.keys():
        #     username = key
            # password = value
            # print("尝试登录账号'%s'中..."%(username))
        return (data_dict)
    # 登录失败电话号码颜色为红色
    def fail_high_light(self,fail_phone):
        for cell in self.sheet['B']:
        # cell.value如果是手机号这里是int类型,而fail_phone是列表,里面是str类型
            if str(cell.value) in fail_phone:
                print("无法登陆账号,颜色处理中...")
                cell.font = Font(color=colors.RED)
        # 将第一行第二列的登录账号加粗
        self.sheet.cell(1,2).font = Font(bold=True)
        self.wb.save(self.file_name)
    # 如果登录成功,电话号码颜色变黑,考虑之前登录失败后来登录成功的情况
    def success_high_light(self,success_phone):
        for cell in self.sheet['B']:
        # cell.value如果是手机号这里是int类型,而success_phone是列表,里面是str类型
            if str(cell.value) in success_phone:
                cell.font = Font(color=colors.BLACK)
        # 将第一行第二列的登录账号加粗
        self.sheet.cell(1,2).font = Font(bold=True)
        self.wb.save(self.file_name)
    
#!/usr/bin/env python
# coding=utf-8
# 对生成的多个临时文件进行合并,最后删除临时文件夹
from openpyxl import Workbook
import os,shutil,time,xlrd,xlsxwriter
import glob

class Convert(object):
    def __init__(self):
        # 在哪里搜索多个表格
        self.filelocation = "./临时文件"
        self.datavalue = []
        self.data = ['入驻企业名称', '运费内容', '运费区域']
        if not os.path.exists(self.filelocation):
            print('未找到指定目录,系统已自动创建,请将需要合并的文件放到该目录下,目录为:%s' % self.filelocation)
            os.makedirs(self.filelocation)
        # else:
        #     self.main()
    def main(self):
        # 当前文件夹下搜索的文件名后缀
        f_list = os.listdir(self.filelocation)
        # print(f_list)
        end_file = []
        for i in f_list:
            # os.path.splitext():分离文件名与扩展名
            if os.path.splitext(i)[1] == '.xlsx':
                j = os.path.splitext(i)[1]
                # print(j) #.xlsx
                # print(os.path.splitext(i)[1])
                end_file.append(j)
        # fileform = ".xlsx"
        # 首先查找默认文件夹下有多少文档需要整合
        # print(end_file)
        filearray = [] #最终需要的.xlsx文件的列表
        for fileform in set(end_file): # end_file里面包含多个.xlsx内容,只需要一个即可
            for filename in glob.glob(self.filelocation +"/"+ "*" + fileform):
                filearray.append(filename)
        # print(filearray)
        for i in range(len(filearray)):
            end_file = self.hebing(filearray[i])
        print("\n"+"数据合并中.....")
        # 删除临时文件
        self.del_file()
        address = os.path.abspath(end_file)
        print("数据合并完成,保存在'%s'"%address)

    # 将数据合并到一个文件中
    def hebing(self, file):
        fh = self.open_xls(file)
        x = self.getshnum(fh)
        rvalue=[]
        for shnum in range(x):
            rvalue = self.getFilect(shnum, fh)  # 生成最终数据列表嵌套[[],[],[],[]]
        # 当天的日期
        file_name_date = time.strftime("%Y-%m-%d", time.localtime())
        endfile = './运费规则总表' + file_name_date + '.xlsx'
        wb1 = xlsxwriter.Workbook(endfile)  # 建立文件
        # 创建一个sheet工作对象
        ws = wb1.add_worksheet('运费规则')  # 建立sheet
        # 要先写表头,占了第一行,所以下面应该从第二行开始添加
        for i in range(0, len(self.data)):
            ws.write(0, i, self.data[i])  # 写入0行i列数据
        for a in range(len(rvalue)):
            for b in range(len(rvalue[a])):
                c = rvalue[a][b]
                # 要a+1行,第一行被表头占据
                ws.write(a + 1, b, c)
        wb1.close()
        return endfile

    # 打开一个excel文件
    def open_xls(self, file):
        fh = xlrd.open_workbook(file)
        return fh

    # 获取sheet表的个数
    def getshnum(self, fh):
        x = 0
        sh = self.getsheet(fh)
        for sheet in sh:
            x += 1
        return x

    # 获取excel中所有的sheet表
    def getsheet(self, fh):
        return fh.sheets()

    def getFilect(self, shnum, fh):  # shnum第几个sheet表,第一个值是0
        table = fh.sheets()[shnum]
        num = table.nrows  # sheet表有多少行数据
        for row in range(1, num):  # 从1开始不会读取每个表格的表头,从0开始或者不填就会
            rdata = table.row_values(row)
            # 需要判断这一行是不是空行,如果是空行则不添加
            rdata = [str(i) for i in rdata]  # 将内容全部转换为字符串
            if ''.join(rdata) != '':  # 如果不为空则添加到datavalue列表里
                self.datavalue.append(rdata)
        return self.datavalue

    # 删除临时文件
    def del_file(self):
        # 删除临时文件夹和里面生成的文件
        shutil.rmtree(self.filelocation)

猜你喜欢

转载自blog.csdn.net/z564359805/article/details/81392267