代码之家  ›  专栏  ›  技术社区  ›  BadAtCoding

为什么我的函数要创建重复项?

  •  1
  • BadAtCoding  · 技术社区  · 7 年前

    我编写了一个函数,它可以遍历URL并从每个页面中提取所需的数据。

    library(xml2)
    library(rvest)
    

    下面创建了相关URL的矢量:

    tripadvisor_urls <- c()
    
    for (n in seq(0, 80, 10)) {
        url <- paste('https://www.tripadvisor.co.uk/Attraction_Review-g186306-d9756771-Reviews-or',n,
               '-Suckerpunch_St_Albans-St_Albans_Hertfordshire_England.html', sep = "")
        tripadvisor_urls <- c(tripadvisor_urls, url)
        }
    

    这是我写的函数:

    all_pages <- function(x) {
    id_v <- c()
    rating_v <- c()
    headline_quote_v <- c()
    date_v <- c()
    review_v <- c()
    for (url in x) {
            reviews <- url %>%
              read_html() %>%
              html_nodes("#REVIEWS .innerBubble")
    
            id <- reviews %>%
              html_node(".quote a") %>%
              html_attr("id")
            id_v <- c(id_v, id)
    
            headline_quote <- reviews %>%
              html_node(".quote span") %>%
              html_text()
            headline_quote_v <- c(headline_quote_v, headline_quote)
    
            rating_wrong <- url %>%
              read_html() %>%
              html_nodes("#REVIEWS .ui_bubble_rating") %>%
              as.character() %>%
              substr(38,39) %>%
              as.numeric()
            rating <- rating_wrong/10
            rating_v <- c(rating_v, rating)
    
            date <- reviews %>%
              html_node(".rating .ratingDate") %>%
              html_attr("title") %>%
              as.Date('%d %B %Y')
            date_v <- c(date_v, date)
    
            review <- reviews %>%
              html_node(".entry .partial_entry") %>%
              html_text()
            review_v <- c(review_v, review)
        }
    tripadvisor <<- data.frame(id_v, headline_quote_v, rating_v, date_v, review_v)
    }
    
    all_pages(tripadvisor_urls)
    

    当我查看生成的数据帧时,我看到有重复项:

    duplicated(tripadvisor)
    

    我做错了什么?我想这与不断向向量添加新元素有关。最好的解决方法是什么?

    注意:我已请求TripAdvisor的许可,因此我没有违反他们的服务条款。

    1 回复  |  直到 7 年前
        1
  •  1
  •   IRTFM    7 年前

    这似乎是因为您从url读取了两次。如果删除创建 rating_list 以及随后的引用,在 tripadvisor 数据帧。

    如果在对象上运行此操作,则会得到:

    which( tripadvisor$id_list %in% "rn576426120")
    #[1] 1 83
    

    如果你听从我的建议,你现在只会得到 1 。您可以通过在循环外插入此调试行来进一步确认此理论,并可能看到复制发生的位置:

    ; lapply( list(id_list, headline_quote_list, date_list, rating_list, review_list), function(x) print(length(x)))
    

    这个 allpages() 立即调用生成:

    > all_pages(tripadvisor_urls)
    [1] 82
    [1] 82
    [1] 82
    [1] 164
    [1] 82