Python: 多线程查找XML中节点信息

最近有项目需要去某个文件夹里面,获取所有XML文件,然后从XML文件中查找特定节点中查找是否有特定信息。

为了便于获取所有文件信息,直接用bat文件每天自动运行生成一个文件列表list信息供查看。

cd /d %~dp0
dir /s /b *.* > FileList.txt

 

所以接下来要做的事情是从该FileList.txt文件中查找到所有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+,运行速度有了显著提升。

posted @ 2021-07-02 18:51  danvy617  阅读(282)  评论(0编辑  收藏  举报