html - 如何从包含“p”标签和内部文本混合的 HTML 元素中提取文本?
问题描述
我正在使用名为Reaver的 jsoup 周围的 Clojure 包装器来抓取一个包含一些结构不佳的 HTML 的网站。以下是一些 HTML 结构的示例:
<div id="article">
<aside>unwanted text</aside>
<p>Some text</p>
<nav><ol><li><h2>unwanted text</h2></li></ol></nav>
<p>More text</p>
<h2>A headline</h2>
<figure><figcaption>unwanted text</figcaption></figure>
<p>More text</p>
Here is a paragraph made of some raw text directly in the div
<p>Another paragraph of text</p>
More raw text and this one has an <a>anchor tag</a> inside
<dl>
<dd>unwanted text</dd>
</dl>
<p>Etc etc</p>
</div>
这div
代表 wiki 上的一篇文章。我想从中提取文本,但如您所见,有些段落在p
标签中,有些则直接包含在 div 中。我还需要标题和锚标记文本。
我知道如何从所有 、 和 标签中解析和提取文本p
,a
我h
可以选择div
并从中提取内部文本,但问题是我最终选择了两个需要合并的文本不知何故。
如何从此 div 中提取文本,以便按顺序提取p
, a
,h
标签中的所有文本以及 上的内部文本?div
结果应该是与 HTML 中的顺序相同的文本段落。
这是我目前用来提取的内容,但div
结果中缺少内部文本:
(defn get-texts [url]
(:paragraphs (extract (parse (slurp url))
[:paragraphs]
"#article > *:not(aside, nav, table, figure, dl)" text)))
另请注意,其他不需要的元素出现在 this 中div
,例如 ,aside
等figure
。这些元素包含文本,以及带有文本的嵌套元素,不应包含在结果中。
解决方案
您可以将整篇文章提取为 JSoup 对象(可能是Element
),然后使用reaver/to-edn
. 然后你遍历:content
那个并处理字符串(s 的结果)和你感兴趣TextNode
的元素。:tag
(由 vaer-k 编写)
(defn get-article [url]
(:article (extract (parse (slurp url))
[:article]
"#article"
edn)))
(defn text-elem?
[element]
(or (string? element)
(contains? #{:p :a :b :i} (:tag element))))
(defn extract-text
[{content :content}]
(let [text-children (filter text-elem? content)]
(reduce #(if (string? %2)
(str %1 %2)
(str %1 (extract-text %2)))
""
text-children)))
(defn extract-article [url]
(-> url
get-article
extract-text))
推荐阅读
- pandas - 在熊猫中将列解析为日期时间的最快方法
- angular - 禁用按钮不适用于 angular4 验证
- python - 如何从列表中定位 python 小部件标签?
- php - TYPO3 isDir、getRealPath 在控制器上不起作用
- android - 无法从 Facebook 请求 user_age_range
- json - Google Assistant SDK 中的多个参数
- find - OSX 查找名称中带有 (1) 的文件
- azure - 数据湖分析 U-SQL 提取速度(本地与 Azure)
- animation - Javascript 为我的 onmouseover 函数添加时间间隔
- javascript - 如何访问 DOM 对象的 CSS 属性?