【问题标题】:web scraping different number of variables (rvest)网络抓取不同数量的变量(rvest)
【发布时间】:2021-02-19 01:51:15
【问题描述】:

我正在使用 0.99.879 版并使用包 0.3.2 版执行以下任务(我是网络抓取技术的初学者):

对于一个研究项目,我想抓取期刊网站以提取特定文章的作者、机构隶属关系等信息。
我通过以下方式执行此操作:

#Specifying the url for desired website to be scraped (article)
webpage001 <- read_html("https://link.springer.com/article/10.1007/s12286-017-0325-1")
#Using CSS selectors to scrape the rankings section (with Abstract)
abstract_html001 <- html_node(webpage001,".Para")
authors_html001 <- html_nodes(webpage001,".authors__name")
affiliation_html001 <- html_nodes(webpage001, ".affiliation__item")

#Converting the title data to text 
abstract001 <- html_text(abstract_html001)
authors001 <- html_text(authors_html001)
affiliation001 <- html_text(affiliation_html001)
# creating a data frame
text01 <- data.frame(Abstract = abstract001, Author = authors001, 
Institution = affiliation001)
text01

这很好用,我得到了一个 obs。和三个变量。但也有一些学术文本,例如书评,不包含摘要。如果我尝试相同的评论,

webpage002 <- read_html("https://link.springer.com/article/10.1007/s12286-017-0324-2")
authors_html002 <- html_nodes(webpage002,".authors__name")
affiliation_html002 <- html_nodes(webpage002, ".affiliation__item")
authors002 <- html_text(authors_html002)
affiliation002 <- html_text(affiliation_html002)
# creating a data frame
text02 <- data.frame(Author = authors001, Institution = affiliation001)
text02

我得到一个 obs。和两个变量。最后,我想合并两个数据框,但由于列数不相等, 函数不起作用。
对于一些文本,我可以指定以下

abstract002 <- NA
text02 <- data.frame(Abstract = abstract002, Author = authors002, 
Institution = affiliation002)
text02

total <- rbind(text01, text02)

但是,对于大量的文本,这太多了,我想知道是否有办法以不同的方式甚至是半自动化的(例如,每次文本都没有摘要,NA 被分配到正确的列中)。

有没有人知道如何做到这一点或解决它?

提前致谢!

【问题讨论】:

    标签: rstudio rvest rbind r web-scraping rvest


    【解决方案1】:

    使用rvestpurrr,我们可以:

    library(rvest)
    library(purrr)
    
    url <- 'https://link.springer.com/article/10.1007/s12286-017-0325-1'
    url2 <- 'https://link.springer.com/article/10.1007/s12286-017-0324-2'
    
    l <- list(url, url2)
    
    l %>% 
        map_df( ~{
    
            h <- read_html(.x)
    
            abstract <- html_node(h, '.Para') %>%
                html_text()
    
            author <- html_node(h, '.authors__name') %>% 
                html_text()
    
            affiliation <- html_node(h, '.affiliation__item') %>% 
                html_text()
    
            data.frame(abstract, author, affiliation, stringsAsFactors = FALSE)
        })
    #>  abstract
    #> 1 When the Cold War ended, many non-democratic...
    #> 2 <NA>
    #>               author
    #> 1       Marlene Mauk
    #> 2 Christina Forsbach
    #>                                                                        affiliation
    #> 1 Institut für PolitikwissenschaftJohannes Gutenberg-Universität MainzMainzGermany
    #> 2     Institut für SozialwissenschaftenUniversität HildesheimHildesheimDeutschland
    

    【讨论】:

    • 很好用。非常感谢(我之前的评论可能在代码中发现了一个错误,但它并不存在 - 网站上的 CSSselector 是错误的其他文本。)
    【解决方案2】:

    这是假数据:

    df1 <- data.frame( Abstract = letters[1:3], Author = letters[4:6], Institution = letters[7:9] )
    df2 <- data.frame( Author = letters[10:12], Institution = letters[13:15] )
    
    df1
      Abstract Author Institution
    1        a      d           g
    2        b      e           h
    3        c      f           i
    
    df2
      Author Institution
    1      j           m
    2      k           n
    3      l           o
    

    我建议添加一列Obs 为每个观察保留一个唯一标识符:

    df1 <- df1 %>% mutate( Obs = 1:nrow(df1) )
    df2 <- df2 %>% mutate( Obs = (nrow(df1)+1):(nrow(df1)+nrow(df2)) )
    
      Abstract Author Institution Obs
    1        a      d           g   1
    2        b      e           h   2
    3        c      f           i   3
    

    然后将gather的数据先转成长格式并合并(只显示head):

    df3 <- df1 %>%
           gather(key,value,-Obs) %>% 
           rbind(gather(df2,key,value,-Obs))
    
       Obs         key value
    1    1    Abstract     a
    2    2    Abstract     b
    3    3    Abstract     c
    4    1      Author     d
    5    2      Author     e
    

    然后spread再次数据:

    df3 <- df3 %>% spread(key=key,value=value)
    
      Obs Abstract Author Institution
    1   1        a      d           g
    2   2        b      e           h
    3   3        c      f           i
    4   4     <NA>      j           m
    5   5     <NA>      k           n
    6   6     <NA>      l           o
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2021-02-09
      • 2023-03-06
      相关资源
      最近更新 更多