python—beautifulSoup提取网页数据写入指定的Excel表格
1.前言
任务需求:测试的报告是HTML格式,我需要把报告中对应的结果提取出来,并且把结果写入指定的Excel中的位置
2.实现步骤
第一步:获取当前目录下的多个HTML文件
第二步:从HTML中提取指定的结果(使用beautifulSoup完成)
第三步:优化内存结构,使用字典保存数据
第四步:把字典数据对应的内容写入到Excel中
import os
from bs4 import BeautifulSoup # 建议使用beatifulsop进行处理 可能简单
from openpyxl import load_workbook
def writeTolog(logtext): # 写入日志
with open(Filename_log_path, 'a',encoding='utf-8') as f_new:
f_new.write(str(logtext))
class HtmlSpider:
def get_current_path(self): # 应该加个try语句
source_path = os.getcwd();
files = os.listdir(source_path)
File_html_path_list = [];
file_xlsx_path_list = []
try:
for file in files:
# print(file)
if file[-5:] == '.html': # 后缀名相等
File_html_path_list.append(os.path.join(source_path, file))
if file[-5:] == '.xlsx': # excel文件应该只有一个
file_xlsx_path_list.append(os.path.join(source_path, file))
if len(file_xlsx_path_list) == 1:
pass;
else:
writeTolog("Error05:当前一级目录下没有或者有多个Excel文件请确认!\n")
os.sys.exit() # 强制退出
except IOError:
writeTolog("Error00: 没有找到文件或读取文件失败\n")
if File_html_path_list==None:
writeTolog("Error07:当前路径下没有找到后缀为html的文件\n")
os.sys.exit() # 强制退出
return File_html_path_list,file_xlsx_path_list[0];
def read_html(self,html_path):
'''一个发送请求,获取响应,同时etree处理html'''
response = open(html_path,'r',encoding="utf-8") # 读取本地文件
html = response.read() #获取str 类型的html
soup_html = BeautifulSoup(html, 'lxml')
return soup_html
def get_data(self,html_path): #实现主要逻辑
# 1.获取目标网址url
# 2.发送请求获取响应
soup_html = self.read_html(html_path)
h3_list = (soup_html.find_all('h3'))[0:-1:2] # 只取出相关的
# 3.提取数据
success_list= []
for h3 in h3_list:
middle_adjust_str = h3.get('class')
if middle_adjust_str == ['success']:
success_list.append('Passed')
elif(middle_adjust_str == ['fail']):
success_list.append('Failed')
else:
writeTolog("Error01:html网页class标签中请提取class ='success'或者class ='fail'\n")
os.sys.exit() # 强制退出
# print(success_list)
name_list = []
for h3 in h3_list:
middle_3_str = h3.get_text().replace("\n", "").replace(" ","")
middle_2_str = middle_3_str.split('-')[1] # 按照-切割字符串,取第2部分 如DRV_0040201:R档能量回收;滑行出负扭矩
middle_str = middle_2_str.split(':')[0] # 按照英文状态:切割字符串,取第1部分 如DRV_0040201
if len(middle_2_str) == len(middle_str):
writeTolog("Error02:请确认{}里面的-或者:是否是英文状态下的输入\n".format(middle_3_str))
name_list.append(middle_str) #获取文本并去掉换行符
# print((name_list))
return success_list,name_list
def readexcel(self,success_list,name_list,sheetIndex):
if len(success_list) != len(name_list):
writeTolog("Error03:提取测试用例有{}个,但是测试用例的结果有{}个,因此测试个数和结果不匹配\n".format(len(name_list),len(success_list)))
os.sys.exit() # 强制退出
dict_middle_total = dict(zip(name_list, success_list)) # 删除错误的键值对,并保存到log日志
# 删除无效的键值对
for name in list(dict_middle_total.keys()):
if (len(name) != 11):
writeTolog("Error07:测试用例{}的名字无效或者长度不是11,故删除!\n".format(name))
dict_middle_total.pop(name);
# print(dict_middle_total)
table = None
try:
data = load_workbook(File_xlsx_path)
table = data['测试用例'] # excel中的sheet名字
# print(table)
except IOError:
writeTolog("Error04: 没有找到xlsx文件或读取文件失败,请确认xlsx文件已经关闭!\n")
os.sys.exit() # 强制退出
else:
dict_total = {}
for name in dict_middle_total.keys():
for i in range(3, table.max_row): # 从第3行开始,0,1,2是标题
if (table.cell(row=i,column=2).value == name): # 第2列 中的每个值比较 如 'DRV_0070201'
#取到对应的行数,列都是F列;根据'DRV_0070201' 得到对应的列数
dict_total.update({i:dict_middle_total[name]}) # 重新生成新的键值对
# print("此时的{}对应的行数是{},结果是{}".format(name,rowIndex,dict_middle_total[name]))
break;
else:
continue;
writeTologText.append(dict_middle_total) # 写入日志
writeTologText.append('\n')
writeTologText.append(dict_total) # 写入日志
writeTologText.append('\n')
return dict_total;
def writeToExcel(self,dict_total): # 注意运行程序的时候要关闭Excel,否则无法写入
wb = load_workbook(filename=File_xlsx_path)
ws = wb['测试用例'] # excel中的sheet名字
for key in list(dict_total.keys()): # dict_total[key]
# print("此时F{}的值是{}".format(key,dict_total[key]))
ws[('F' + str(key) )] = dict_total[key] # 类似ws["F86"] = 'Passed'
wb.save(File_xlsx_path)
if __name__ == '__main__':
File_xlsx_path = None;
Filename_log_path = 'resulthtml.log'
if os.path.exists(Filename_log_path): # 清空日志
os.remove(Filename_log_path);
writeTologText = []
myspider = HtmlSpider()
File_html_path_list,File_xlsx_path = myspider.get_current_path()
# 取出的元素已经默认不为空了
for html_path in File_html_path_list:
writeTologText.append("当前处理的文件路径为:"+ html_path + "\n")
success_list, name_list = myspider.get_data(html_path)
dict_total = myspider.readexcel(success_list, name_list,sheetIndex = 2)
myspider.writeToExcel(dict_total)
writeTologText.append("所有html文件内容,已经在{}中设置成功".format(File_xlsx_path))
with open(Filename_log_path, 'a', encoding='utf-8') as f_new: #y一次性写入更快
for logtext in writeTologText:
f_new.write(str(logtext))
3.结果如下:
保存到日志中: