最近有项目需要去某个文件夹里面,获取所有XML文件,然后从XML文件中查找特定节点中查找是否有特定信息。
为了便于获取所有文件信息,直接用bat文件每天自动运行生成一个文件列表list信息供查看。
cd /d %~dp0 dir /s /b *.* > FileList.txt
所以接下来要做的事情是从该FileList.txt文件中查找python教程到所有XML文件,然后打开每个XML文件查找是否包含指定节点信息。

import os.path
from lxml import etree
TARGET = r'specific_info'
xml_files_list = []
with open(r'C:\test\FileList.txt', 'r') as f:
for line in f.readlines():
if line.strip().endswith('_2_.xml'):
xml_files_list.append(line)
duplicated_id_list = []
result_xml_files = []
for xml_file in xml_files_list:
xml_tree_root = etree.parse(xml_file).getroot()
detect_install_str = xml_tree_root.xpath('//SPECIFIC_NODE')[0].xpath('string(.)')
if TARGET in detect_install_str:
# 检查是否此文件名已经检查过了:因为可能在不同文件夹里面有同名的文件
if os.path.basename(xml_file) not in duplicated_id_list:
duplicated_id_list.append(os.path.basename(xml_file))
result_xml_files.append(xml_file)
print(result_xml_files)

因为FileList.txt中看到的XML文件有近2w个,最后查询速度很慢,需要1000s+。
所以考虑使用多线程的方式来加快查询速度:

import os
from lxml import etree
from multiprocessing.dummy import Pool
TARGET = r'specific_info'
xml_files_list = []
file_name_list = []
with open(r'C:\test\FileList.txt', 'r') as f:
for line in f.readlines():
# 先去重,这样就不用在读取XML的时候去重了
if line.strip().endswith('_2_.xml') and os.path.basename(line) not in file_name_list:
xml_files_list.append(line)
# 创建函数用来跑多线程
def handle_xml(xml_file):
xml_tree_root = etree.parse(xml_file).getroot()
detect_install_str = xml_tree_root.xpath('//SPECIFIC_NODE')[0].xpath('string(.)')
if TARGET in detect_install_str:
return xml_file
p = Pool()
results = []
start = time.time()
for i in xml_files_list:
results.append(p.apply_async(handle_xml, args=(i,)))
p.close()
p.join()
result_xml_files = [x.get() for x in results if x.get()]
print(result_xml_files)

用多线程后速度大概是100s+,运行速度有了显著提升。




















