前言
闲来无事,想起来之前在简书发过的文章还没搬过来,正想搬一篇lxml和re效率对比的,结果发现代码没了,索性重写一次。
先上结果:
只做解析加取数据,re比lxml快了300%!
解析加pandas处理数据,re比lxml快40%
其实这个测试结果应该没什么好纠结的,预计应该是re优于lxml,二者都优于beautifulsoup。
因为很少用beautifulsoup,所以这次没测试它。
注意事项
为了避免网络波动,测试时不应该把网络请求时间计算进去,这里使用参数传入要解析的HTML。
另外,解析语句的写法优劣会在极大程度上影响结果,所以一般工作重点应该放在表达式的写法上。
小技巧
导出list列表数据的时候直接来一个pandas,省时省力
代码
# -*- encoding: utf-8 -*-
'''
@File : test-re-lxml.py
@Time : 2021年12月18日 22:33:10 星期六
@Author : erma0
@Version : 1.0
@Link : https://erma0.cn
@Desc : 测试re lxml效率
'''
import re
import time
import pandas as pd
import requests
from lxml import etree
from itertools import zip_longest
# ahtml = requests.get('http://test.cn/').text
ahtml = '''
教育网盘
图标
文件名
所属用户
大小
更新时间
1汽包安装施工技术交底.pdf HNAZ 871.49 K 2021-11-23 水冷壁安装施工技术交底.doc HNAZ 139.66 K 2021-11-23 水压试验技术交底 - 副本.doc HNAZ 173.44 K 2021-11-23 烟道安装施工技术交底 - 副本.doc HNAZ 130.84 K 2021-11-23 (最终)山西东义干熄焦工程施工组织设计0610.doc HNAZ 2.4 M 2021-11-23 东义干熄焦锅炉水压试验方案(1)10.10.docx HNAZ 103.62 K 2021-11-23 山西干熄焦锅炉水冷壁安装方案0507.doc HNAZ 711.05 K 2021-11-23 东义汽包吊装施工方案 0710.docx HNAZ 989.66 K 2021-11-23 PQR044(12Cr2MoG,273×13)SMAW+GT... HNAZ 20.24 M 2021-11-23 锅炉焊接施工方案0525.doc HNAZ 711.5 K 2021-11-23 山西东义锅炉钢架安装施工方案0520.doc HNAZ 1.08 M 2021-11-23 东义230T干熄焦余热锅炉安装方案.docx HNAZ 418.04 K 2021-11-23 冬季施工方案 11.11.docx HNAZ 47.07 K 2021-11-23 1汽包安装安全技术交底.pdf HNAZ 908.46 K 2021-11-23 余热锅炉入口烟道安装安全技术交底.docx HNAZ 50.87 K 2021-11-23 余热锅炉钢结构安全技术交底.docx HNAZ 50.86 K 2021-11-23 吊装指挥安全交底.docx HNAZ 13.59 K 2021-11-23 水压试验安全技术交底.docx HNAZ 48.24 K 2021-11-23 移动脚手架安全技术交底 - 10.31.docx HNAZ 45.41 K 2021-11-23 余热锅炉水冷壁安全技术交底.docx HNAZ 50.98 K 2021-11-23
'''
def get_lxml(html):
d = etree.HTML(html)
link = d.xpath('//tr/td[2]/a[1]/@href')
title = d.xpath('//tr/td[2]/a[1]/text()')
passwd = d.xpath('//tr/td[2]/font/text()')
user = d.xpath('//tr/td[3][@width="120"]/text()')
size = d.xpath('//tr/td[4]/div/text()')
time = d.xpath('//tr/td[5]/div/text()')
datas = list(zip_longest(link, title, passwd, user, size, time, fillvalue=''))
datas = pd.DataFrame(datas, columns=['link', 'title', 'passwd', 'user', 'size', 'time'])
datas['link'] = datas['link'].str.strip()
datas.to_csv('result-lxml.csv')
# print(len(datas))
return datas
def get_re(html):
datas = []
# datas= r.findall(html)
datas = re.findall(rep, html, re.S)
# for data in datas: # link, title, passwd, user, time
# pass
# print(len(datas))
datas = pd.DataFrame(datas, columns=['link', 'title', 'passwd', 'user', 'size', 'time'])
datas['link'] = datas['link'].str.strip()
datas.to_csv('result-re.csv')
return datas
if __name__ == '__main__':
rep = r"([\s\S]*?)[\s\S]*?([\s\S]*?)[\s\S]*?center>([\s\S]*?) ([\s\S]*?) ([\s\S]*?)"
r = re.compile(rep, re.S)
for name, function in [('lxml', get_lxml), ('re', get_re)]:
start = time.time()
for i in range(500):
function(ahtml)
# function(ahtml)
end = time.time()
print(name, end - start)
结果
lxml 2.1219968795776367
re 1.341965675354004
re比lxml快了接近40%
再测试一下纯解析的效率
因为上面代码中计算了pandas的数据处理时间,使用下面把它注释掉再测试一下,代码如下:
def get_lxml(html):
d = etree.HTML(html)
link = d.xpath('//tr/td[2]/a[1]/@href')
title = d.xpath('//tr/td[2]/a[1]/text()')
passwd = d.xpath('//tr/td[2]/font/text()')
user = d.xpath('//tr/td[3][@width="120"]/text()')
size = d.xpath('//tr/td[4]/div/text()')
time = d.xpath('//tr/td[5]/div/text()')
def get_re(html):
# datas= r.findall(html)
datas = re.findall(rep, html, re.S)
结果2
lxml 0.6280360221862793
re 0.15498137474060059
单纯解析加取数据,re比lxml快了300%!