Rvest,html_nodes返回空列表和字符串,使用网站

时间:2019-07-15 02:52:51

标签: css r web-scraping rvest

对于该网站: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)

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

1 个答案:

答案 0 :(得分:0)

如果在浏览器中禁用javascript,则会看到该内容未加载。如果您随后检查html,您将看到数据存储在script标签中。可能是在浏览器中运行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))))
  }
}