【发布时间】:2015-05-23 08:18:01
【问题描述】:
我正在使用 Beautifulsoup 解析大小在 3 到 10MB 之间的大型 HTMl 文件。不幸的是,99% 的数据是我想要解析的内容。该文件实际上包含一个小标题、一些 js 脚本以及 1,000 到 10,000 个项目。每个项目由以下表格行组成:
<tr class="New" id="content_id">
<td class="item" align="center">
</td><td align="center">
<a onclick="somecode"><img src="/images/sample.gif" alt="alttext" class="image"></a>
</td><td style="astyle">[content1]</td><td>[content2]</td><td>[content3]</td><td>[content4]</td><td>[content5]</td><td style="bstyle">[content6]</td><td>[content7]</td><td>[content8]</td><td>[content9]</td><td>[content10]</td><td>[content11]</td><td></td><td>[content12]</td><td>[content13]</td><td>
<a href="somejs">[content14]</a>
</td><td>
<a href="somejs">[content15]</a>
</td><td>[content16]</td><td>
<a title="" href="somejs">[content16]</a>
</td><td>
<a title="" href="somejs">[content17]</a>
</td>
</tr>
注意每个 [content] 占位符都是我需要解析的相关数据。
我尝试了各种常见的优化,例如 a) 使用不同的解析器,b) 使用 SoupStrainer,c) 定义编码
b) 和 c) 在我记录所花费的时间时实际上没有任何效果。不同的解析器有很大的影响。当我在 1.5k 项目列表(相对较小的列表)上运行以下脚本时,我得到以下解析时间(我在 2012 年 Mac Book Air 上运行实验):
#1653 items parsed in 15.5 seconds with lxml
#xml takes 27 sec
#html5lib takes 69 sec
#html.parser takes 24 sec
current = datetime.datetime.utcnow()
strainer = SoupStrainer('table', attrs={'id':'contenttable'})
soup = BeautifulSoup(html,'lxml',parse_only=strainer,from_encoding="UTF-8")
print datetime.datetime.utcnow() - current
问题:除了我目前使用的以外,还有什么可以用来显着缩短解析时间的调整吗?
到目前为止,我只能考虑增加 CPU 功率。
【问题讨论】:
-
您是一次加载整个页面吗?你是如何解析每一行的?也许您可以使用生成器一次解析一行(避免较大文档的内存问题)。
-
我敢肯定我会为此受到抨击,因为“HTML 不是常规语言”,但如果每个“项目”都是正确的 HTML,就像你展示的那样,你可以迭代在文件的行上(抛出一对
next()方法调用以加快不必要的检查)并使用正则表达式来提取您需要的内容。
标签: python performance parsing beautifulsoup lxml