【问题标题】:Scrape all child paragraphs under heading (preferable rvest)刮掉标题下的所有子段落(最好是 rvest)
【发布时间】:2015-04-15 13:45:45
【问题描述】:

我的目标是在相当大的 Word 文档上使用 library(tm) 工具包。 Word 文档有合理的排版,所以我们有h1 用于主要部分,一些h2h3 子标题。我想对每个部分进行比较和文本挖掘(每个 h1 下面的文本 - 副标题并不重要 - 因此可以包含或排除它们。)

我的策略是将 worddocument 导出为 html,然后使用rvestpacakge 提取段落。

library(rvest)
# the file has latin-1 chars
#Sys.setlocale(category="LC_ALL", locale="da_DK.UTF-8")
# small example html file
file <- rvest::html("https://83ae1009d5b31624828197160f04b932625a6af5.googledrive.com/host/0B9YtZi1ZH4VlaVVCTGlwV3ZqcWM/tidy.html", encoding = 'utf-8')

nodes <- file %>%
  rvest::html_nodes("h1>p") %>%
  rvest::html_text()

我可以提取所有的&lt;p&gt;html_nodes("p"),但这只是一大汤。我需要分别分析每个h1

最好的可能是一个列表,每个h1 标题都有一个p 标签向量。并且可能是像for (i in 1:length(html_nodes(fil, "h1"))) (html_children(html_nodes(fil, "h1")[i])) 这样的循环(不起作用)。

如果有办法从rvest 中整理 html 中的单词,则奖励

【问题讨论】:

  • 您现在可以使用htmltidy 包(包装libtidy)直接在R 中整理难看的Word 生成的HTML。

标签: r css-selectors web-scraping rvest


【解决方案1】:

注意&gt; is the child combinator;您当前拥有的选择器会查找 p 元素,它们是h1 的子元素,这在 HTML 中没有意义,因此不返回任何内容。

如果您检查生成的标记,至少在您提供的示例文档中,您会注意到每个 h1 元素(以及被标记为p 代替)有一个关联的父 div

<body lang="EN-US">
  <div class="WordSection1">
    <p class="MsoTocHeading"><span lang="DA" class='c1'>Indholdsfortegnelse</span></p>
    ...
  </div><span lang="DA" class='c5'><br clear="all" class='c4'></span>

  <div class="WordSection2">
    <h1><a name="_Toc285441761"><span lang="DA">Interview med Jakob skoleleder på
    a_skolen</span></a></h1>
    ...
  </div><span lang="DA" class='c5'><br clear="all" class='c4'></span>

  <div class="WordSection3">
    <h1><a name="_Toc285441762"><span lang="DA">Interviewet med Andreas skoleleder på
    b_skolen</span></a></h1>
    ...
  </div>
</body>

每个部分中由h1 表示的所有p 元素都可以在其各自的父级div 中找到。考虑到这一点,您可以简单地选择 p 元素,它们是每个 h1 的兄弟元素。但是,由于 rvest 目前无法从上下文节点中选择兄弟姐妹(html_nodes() 仅支持查看节点的子树,即其后代),因此您需要以另一种方式执行此操作。

假设 HTML Tidy 创建了一个结构,其中每个 h1 都在直接位于 body 内的 div 中,您可以使用以下选择器获取除目录之外的每个 div

sections <- html_nodes(file, "body > div ~ div")

在您的示例文档中,这应该导致div.WordSection2div.WordSection3。目录由div.WordSection1 表示,从选择中排除。

然后从每个div中提取段落:

for (section in sections) {
  paras <- html_nodes(section, "p")
  # Do stuff with paragraphs in each section...

  print(length(paras))
}
# [1] 9
# [1] 8

如您所见,length(paras) 对应于每个divp 元素的数量。请注意,其中一些只包含&amp;nbsp;,这可能会很麻烦,具体取决于您的需要。我将把处理这些异常值作为练习留给读者。

不幸的是,因为 rvest 不提供自己的 HTML Tidy 功能,所以对我来说没有任何奖励积分。您需要单独处理 Word 文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-18
    • 2016-05-29
    • 2021-06-25
    • 2020-05-30
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    相关资源
    最近更新 更多