使用rvest(或另一个R软件包)检测HTML段落的开头是否为不同格式(例如,加粗)

使用rvest(或另一个R软件包)检测HTML段落的开头是否为不同格式(例如,加粗),html,r,dataframe,web-scraping,rvest,Html,R,Dataframe,Web Scraping,Rvest,我正在使用一个R包edgarWebR来解析SEC文件,例如。它返回一个数据帧,其中一列(称为“raw”)是HTML。它将HTML页面分成段落,每个段落一行: 其他栏目 未经加工的 文本 第一排 截至2016年12月31日,我们的净亏损为155万美元,截至2016年12月31日,累计亏损为6150万美元。为了实现可持续的盈利能力,我们必须增加收入。 截至2016年12月31日,我们的净亏损为155万美元,截至2016年12月31日,我们的累计赤字为6150万美元。为了实现可持续的盈利能力,我们必须

我正在使用一个R包edgarWebR来解析SEC文件,例如。它返回一个数据帧,其中一列(称为“raw”)是HTML。它将HTML页面分成段落,每个段落一行:

其他栏目 未经加工的 文本 第一排

截至2016年12月31日,我们的净亏损为155万美元,截至2016年12月31日,累计亏损为6150万美元。为了实现可持续的盈利能力,我们必须增加收入。

截至2016年12月31日,我们的净亏损为155万美元,截至2016年12月31日,我们的累计赤字为6150万美元。为了实现可持续的盈利能力,我们必须增加收入。 第二排
我们有亏损的历史,我们无法向您保证我们将实现盈利。
我们有亏损的历史,我们不能向您保证我们将实现盈利。
我已经在这里读了你的相关问题。有趣的工作!我认为解决办法大致如下:

1:通过做你已经在做的事情,从HTML中提取相关单词

relevant_words <- rvest::html_text(your_raw_html_here)
# split word by word
relevant_words <- stringr::str_split(relevant_words, pattern = " ")

relevant_words我还没有对此做足够的测试,但原则是通过查看给定行的$raw中的子标记来捕捉您提到的情况

目前,它被设置为查看孩子的标签/类型是否位于给定向量
c(“b”、“strong”、“i”)
;此外,对样式属性
html\u attr(“style”)%%>%str\u detect(“italic | bold”)
还有一个额外的测试。如果未找到属性匹配项,则将输出Not N/A

这两个测试的结果是,该行是否应被视为具有标题(并且需要稍后拆分);使用布尔逻辑并将其包装在
if_else
中,以在未找到子对象的位置输出false
if_else(is.na(node)、F、as.logical(style_flag | tag_flag)
。结果将写入名为
header
的新列

为了更精细一点,然后对这个新列和
粗体比例列进行比较,以确定最终是否应该考虑包含要处理的标题行。目前的确定是粗体比例列>=0.5还是标题==T,然后是T或F。显然,需要考虑对于某个点的
italic\u proportion\u列
,或将这两个因素重新考虑到比例函数中(这是我的选择)。此确定写入
结果

我认为在改进这种方法和保证其质量方面还有很多工作要做,例如1)我想重新工作,因此我们只解析html一次,2)从其余部分返回子html的拆分,以满足您在不同行之间从其余部分拆分头节的要求;3) 我还希望通过预先确定的不同页面的测试用例列表来确定这种方法的有效性;4) 我会重新考虑,使函数如
get_child
更通用,例如,通过css选择器模式实现更多的通用性;在其他地方,在结果确定中通过比例>=的测试

但它可能是有用的作为一个开端,为10。。。。。。。如果可以的话,我可能会再次访问此网站并进行改进


库(rvest)
图书馆(tidyverse)
图书馆(edgarWebR)
图书馆(stringr)

段落风格比例我不太明白。首先你告诉我你想检测标题,然后你告诉我你想确定段落中的主要文本类型,这与我能说的不同。你能澄清一下吗?嗨。整个过程的目的是确定哪些段落代表标题,哪些段落不代表标题。逻辑是,如果一个段落的三个词都是,比如说,粗体字,那么这个段落就不太可能是标题,除非这三个粗体字在我看到的段落的开头。如果你试着检查第一个,比如说,5个单词中的大多数与本段其他部分相比是否有不同的“类型”,会怎么样。比如,前三个单词是粗体或斜体,其余的是普通的或混合的。是的,这就是我想要的——但我不知道怎么做,也不容易理解。我不知道如何以那种方式逐字解析这些内容(甚至“文本包含html块,文本包含html块”)
library(rvest)
library(tidyverse)
library(edgarWebR)
library(stringr)

paragraph_style_proportion <- Vectorize(function(html, css_selector) {
  missing_html_flag <- tryCatch(read_html(html), error = function(err) "NOT HTML")
  if (missing_html_flag == "NOT HTML") {
    style_proportion <- -1
  }
  else {
    page <- read_html(html)
    whole_paragraph_length <- nchar(str_squish(page %>% html_text()))
    style_text_length <- sum(nchar(str_squish(page %>% html_nodes(css_selector) %>% html_text())))
    style_proportion <- round(style_text_length / whole_paragraph_length, 2)
  }
  return(style_proportion)
})

get_child <- function(html) {
  child <- html %>%
    read_html() %>%
    html_node("*:nth-child(2)")
  return(child)
}

is_header <- function(node) {
  style_flag <- node %>%
    html_attr("style") %>%
    str_detect("italic|bold") %>% 
    if_else(is.na(.), F, .)
  tag_type <- node %>% html_name() %>% tolower()
  tag_flag <- tag_type %in% c("b", "strong", "i") # test if of certain type then classify
  flag <- if_else(is.na(node), F, as.logical(style_flag | tag_flag))
  return(flag)
}

df <- parse_filing("https://www.sec.gov/Archives/edgar/data/1070154/000114036109028731/form10k.htm", include.raw = TRUE)

df <- df %>%
  mutate(bold_proportion = paragraph_style_proportion(raw, "b, strong, [style*=bold]"))

df$header <- lapply(df$raw, function(x){is_header(get_child(x))})
df$outcome <-  with(df, ifelse(bold_proportion >=.5 | header == T, T, F))