【问题标题】:Rvest, html_nodes return empty list and string, wield websiteRvest,html_nodes 返回空列表和字符串,使用网站
【发布时间】:2019-11-23 17:49:52
【问题描述】:

对于这个网站:https://www.coinopsy.com/dead-coins/,我正在使用 R 和 rvest 包来抓取名称、摘要等信息,以制作我自己的表单。我在其他网站上做过这个,确实很成功,但是这个很奇怪。

我在以前的工作中使用了 SelectorGadget,这很有用,可以计算 css 节点的名称,但是 html_nodeshtml_text 返回空字符,我不知道是不是因为网站的结构如下完全不同的格式!

css代码示例:

td class="all sorting_1">a class="coin_name" href="007coin">007Coin /a>/td>

a class="coin_name" href="007coin">007Coin /a>

url <- "https://www.coinopsy.com/dead-coins/"

webpage <- read_html(url)

Item_html <- html_nodes(webpage,'.coin_name')

Item <- html_text(Item_html)

> Item

character(0)

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: css r web-scraping rvest


    【解决方案1】:

    如果您在浏览器中禁用 javascript,您将看到该内容未加载。如果您随后检查 html,您将看到数据存储在脚本标记中;大概是在浏览器中运行 javascript 时加载到表中的。 Javascript 无法使用您使用的方法运行。您可以从响应 html 中提取数组的 javascript 数组。然后解析成一个数据框。我是 R 的新手,所以研究在这种情况下如何做到这一点。我将在最后包含一个完整的 python 示例。如果我的研究有成果,我会更新。否则,您可以从data 中返回的字符串中正则表达式输出内容。

    library(rvest)
    library(stringr)
    library(magrittr)
    
    url = 'https://www.coinopsy.com/dead-coins/'
    r <- read_html(url) %>%
      html_node('body') %>%
      html_text() %>%
      toString()
    data <- str_match_all(r,'var table_data = (.*?);')
    data <- data[[1]][,2]  # string representation of list of lists
    #step to convert string to object
    #step to convert object to dataframe
    

    在python中有ast库,它使转换变得容易,下面的结果就是你在页面上看到的表格。

    import requests
    import re
    import ast
    import pandas as pd
    
    r = requests.get('https://www.coinopsy.com/dead-coins/')
    p = re.compile(r'var table_data = (.*?);')   #p1 = re.compile(r'(\[".*?"\])')
    data = p.findall(r.text)[0]
    listings = ast.literal_eval(data)
    df = pd.DataFrame(listings)
    print(df)
    

    编辑:

    目前我找不到可以进行我提到的转换的库。下面是丑陋的组合方式,感觉效率低下。我会欢迎有关改进的建议(尽管这可能会在以后进行代码审查)。我还在看这个,所以会更新。

    library(rvest)
    library(stringr)
    library(magrittr)
    
    url = 'https://www.coinopsy.com/dead-coins/'
    headers <- c("Column To Drop","Name","Summary","Project Start Date","Project End Date","Founder","urlId")
    # https://www.coinopsy.com/dead-coins/bigone-token/  where bigone-token is urlId
    
    r <- read_html(url) %>%
      html_node('body') %>%
      html_text() %>%
      toString()
    data <- str_match_all(r,'var table_data = (.*?);')
    data <- data[[1]][,2]
    
    z <- substr(data, start = 2, stop = nchar(data)-1) %>% str_match_all(., "\\[(.*?)\\]")
    z <- z[[1]][,2]
    
    for(i in seq(1,length(z))){
      if(i==1){
        df <- rapply(as.list(strsplit(z[i], ",")[[1]][2:7]), function(x) trimws(sub("'(.*?)'", "\\1", x)))
      }else{
        df <- rbind(df,rapply(as.list(strsplit(z[i], ",")[[1]][2:7]), function(x) trimws(sub("'(.*?)'", "\\1", x))))
      }
    }
    

    【讨论】:

    • 这与你所追求的一致吗?
    • 抱歉,回复晚了,您的代码运行得非常好,我认为这根本不是丑陋的方式,这几乎是我们现在可以做的,我可能对理解您的代码有一些疑问以后想多打扰你,当我深入研究的时候,祝你一切顺利..
    【解决方案2】:

    也许它会对某人有所帮助,我遇到了同样的问题,解决方案是一开始我必须指定脚本要指向的标签,然后是“。”。在您的情况下,您想要处理一个名为 coin_name 的类,在 html_nodes 函数中指定该类时,您没有指定标签,就像我一样。为了解决这个问题,我只需要指定标签,在你的例子中是“a”标签,它看起来像这样。

    Item_html <- html_nodes(webpage,'a.coin_name')
    

    这样 html_nodes 函数就不会返回空。 我知道你已经解决了,但我希望有人能帮助你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多