案例:
我正在尝试读取 XML 文件,使用 BeautifulSoup 从中提取少量数据,将数据添加到字典中,关闭文件,然后继续处理下一个文件。一旦我提取了所需的数据,文件应该被关闭并从内存中释放。
问题:
程序最终将因内存错误而停止,任务管理器清楚地显示每个文件后内存消耗量不断增加,使我相信我的文件没有正确关闭或从内存中释放。在我的环境中,这将在读取大约 200 个文件后发生。
我尝试过但没有成功的事情:
使用 gc.collect() 收集垃圾(似乎没有什么区别)
使用 soup.decompose() 分解文件(似乎没有什么区别)
不同大小的各种文件
SoupStrainer(有/没有它几乎没有区别)
我发现的2个“解决方案”:
强制脚本在一段时间后自行重新启动(并非最佳)
64 位版本和更多物理内存(并非最佳)
有关文件的信息:
- 大小从 100kb 到 5mb 不等
- 每个文件 10,000 到 70,000 行。
- 标准 .xml 格式
E文件中 XML 结构/片段的示例。 (最多可达 70.000 行):
<!-- language: xml -->
<Partner>
<Language>en-US</Language>
<PartnerRole>stackoverflow1</PartnerRole>
<IsSalesAreaDependent>True</IsSalesAreaDependent>
<ContactPerson>
<ContactPerson>
<Language>en-US</Language>
</ContactPerson>
</ContactPerson>
<InheritFromSoldTo>True</InheritFromSoldTo>
<SalesAreaData>
<SalesAreaData>
<Language>en-US</Language>
<Valid>False</Valid>
<SalesOrganization>stackoverflow2</SalesOrganization>
<DistributionChannel>stackoverflow3</DistributionChannel>
<SalesDivision>stackoverflow4</SalesDivision>
<CustomerGroup />
<Currency>stackoverflow5</Currency>
<PriceGroup />
<PriceList>stackoverflow6</PriceList>
<ShippingConditions />
<Plant />
<PaymentTerms />
</SalesAreaData>
</SalesAreaData>
<CustomerHierarchy />
</Partner>
代码:
for fname in glob.glob(path+"/Quotes/**/*.quote"): #Further define path
with open(fname, encoding="utf8") as open_file:
gc.collect()
counter += 1
contents = open_file.read()
soup = BeautifulSoup(contents, 'lxml')
try:
results = ("("+str(counter)+") " + " Ref: " + soup.quickref.string + " Last modified: " + soup.modifieddate.string)
bsize = os.path.getsize(fname)
totalsize += bsize
tempdata = (soup.modifieddate.string, soup.quickref.string, soup.ownerusername.string, soup.companyname.string, soup.totalnetvalue.string, fname)
dictHolder[counter] = tempdata
except AttributeError:
results = "("+ str(counter) + ")" + "Invalid data / corrupted file, please check: " + fname
corruptCounter += 1
soup.decompose()
gc.collect()
print (results)
10/08/2020:问题已通过切换到 xml.etree.elementtree 模块“解决”,并不能真正算作答案或解决方案,但如果将来有人遇到同样的问题并阅读这个,尝试上面的模块。
最佳答案
我对 beautifulsoup 不太了解......但是用 pandas 读取数千个 csv 文件并将其存储在字典中对我来说非常有用,只需阅读并将其添加到字典中即可。 您可以尝试使用 pandas 读取文件,并检查问题是否在读取第 200 个文件时出现。如果是这种情况,我假设这是 RAM 问题。
关于python - 循环读取 XML 文件最终会导致内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63314468/