在必须使用正则表达式在 html 文档中查找某些内容后重新使用 lxml 的强大功能的最佳方法

StackOverflow https://stackoverflow.com/questions/2421396

我正在尝试从大量 html 文档(数十万个)中提取一些文本。这些文档实际上是表格,但它们是由大量不同的组织准备的,因此他们创建文档的方式存在很大差异。例如,文档分为章节。我可能想从每个文档中提取第 5 章的内容,以便我可以分析该章的内容。最初我认为这很容易,但事实证明作者可能在整个文档中使用一组非嵌套表格来保存内容,以便可以使用表格内的 td 标签显示第 n 章。或者他们可能使用其他元素,例如 p 标签、H 标签、div 标签或任何其他块级元素。

在反复尝试使用 lxml 来帮助我识别每一章的开头和结尾之后,我确定使用正则表达式会更清晰,因为在每种情况下,无论封闭的 html 元素是什么,章节标签始终位于的形式

>Chapter #

它有点复杂,因为可能存在一些以不同方式表示的空白或不间断空格(或或只是空格)。尽管如此,编写一个正则表达式来标识每个部分的开头还是很简单的。(一个部分的开头是上一节的结尾。)

但现在我想使用 lxml 来获取文本。我的想法是,我真的别无选择,只能沿着字符串查找包含我用来查找相关部分的文本的元素的关闭标签。

这是一个示例,其中保存章节名称的元素是 div

<div style="DISPLAY: block; MARGIN-LEFT: 0pt; TEXT-INDENT: 0pt; MARGIN-RIGHT: 0pt" align="left"><font style="DISPLAY: inline; FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Times New Roman">Chapter 1.&#160;&#160;&#160;Our Beginnings.</font></div>

所以我想象我将从找到第一章匹配的位置开始并设置正则表达式来查找下一个

</div|</td|</p|</h1 . . .

所以此时我已经确定了保存章节标题的元素类型

我可以使用相同的逻辑来查找该元素内的所有文本,该元素设置了正则表达式来帮助我标记

>Chapter 1.&#160;&#160;&#160;Our Beginnings.<

所以我已经确定了第一章的开始位置

我可以对第二章做同样的事情(这是第一章结束的地方)

现在我想象我要从我标识为指示第 1 章开始位置的元素的开头开始剪切文档,并在我标识为指示第 1 章位置的元素的开头之前结束2开始。然后,我识别的字符串将被提供给 lxml,以利用其功能来获取内容。

我会遇到所有这些麻烦,因为我已经读了一遍又一遍 - 从来没有使用正则表达式从 html 文档中提取内容,而且我还没有找到一种与 lxml 一样准确的方法来识别起始和结束位置我要提取的文本。例如,我永远无法确定第一章的副标题是我们的开始,也可能是我们的红色金丝雀。让我说,我花了整整两天的时间尝试使用 lxml 来确信我拥有开始和结束元素,并且我只能在 <60% 的时间内准确,但非常短的正则表达式给了我超过 95% 的成功率。

我倾向于让事情变得比必要的更复杂,所以我想知道是否有人见过或解决了类似的问题,以及他们是否有他们想要提供的方法(不是细节)。

有帮助吗?

解决方案 3

由于我担心有使用LXML识别并提取什么,我需要没有系统的方法。 Ø^ h好,我感谢大家插话。请注意,这不是lxml的错,这是不一致的HTML代码的故障。例如。因为章节是一个文件,合理地划分在一章的所有内容应该被包裹在一些类型的元件。也许最灵活的将与随后的DIV是下一章div标签。这将使章树的一个分支。不幸的是,而文件的大约20%的可能是结构良好的人都没有。

我可以测试每种类型的应持有我的内容(DIV,P)元素,并抓住所有的孩子,所有的兄弟姐妹的,直到我到达那个类型且具有信息,可以提醒我,我们的下一个元素是在段(下一个部分的开始时)的端部。但是,这似乎有太多的工作的时候,我的时间或更多的好95%用正则表达式。

感谢所有的答案和评论一如既往我从他们learnded。

其他提示

有时,在处理写得不好或不一致的 HTML 时,没有直接的途径来获取内容。

您可能希望考虑使用 lynx 或基于文本的浏览器之一将页面内容转储到文件中,或将其通过管道传输到代码中,然后对其进行处理。或者,您可以使用 lxml 加载和解析页面,然后使用 text_content() 提取文本并通过正则表达式查找章节。

就像他们说的那样,GIGO - 垃圾进来,垃圾出去,而我们作为开发人员的工作就是将垃圾变成黄金。这样做可能会变得非常混乱。

这听起来像你可能做的最简单的事情是叠代tree.getroot()。iterdescendants()寻找与node.text你想要的正则表达式匹配的节点。从这一点来说,你可以在节点传递到使用一些专门搜索,以确定该文本是一个功能。 (也许如果对根iterdescendants太慢,你可以用你的正则表达式的方法,并潜入etree,试图找到一个f(text_position) -> node功能。)

例如,如果您发现该目标是一个//tr/td,你可以将它传递给看着下一个TD在node.parent一些表格,文本调查子程序(),以查看其是否具有文本是有道理的(约章长度,含有特定字词,等等)。同样,你可以做一些试探法等标签,如divp查找数据。如果你发现自己像font一个未知的标签,你可以尝试向上冒泡级别的数量有限找到你知道如何处理的东西 - 你必须要小心,不要泡涨过头,或者我想你可能会不小心文本检索从另一章。

问题的症结似乎是你挖掘而不是以编程的方式编程提供的数据 - 在这种情况下,人际交往,通常需要某种程度的

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top