使用rvest软件包进行网络抓取的过程为空

时间:2019-07-29 14:38:42

标签: r parsing web-scraping rvest

在下面的链接中有一个按国家(地区)分类的税表,我想将其刮入带有“国家(地区)”和“税收(Tax)”列的数据框中。

我尝试如下使用rvest软件包来获取“国家/地区”列,但生成的列表为空,我不明白为什么。

对于解决这个问题,我将不胜感激。

library(rvest)
d1 <- read_html(
  "http://taxsummaries.pwc.com/ID/Corporate-income-tax-(CIT)-rates"
  )
TaxCountry <- d1 %>%
  html_nodes('.countryNameQC') %>%
  html_text()

1 个答案:

答案 0 :(得分:1)

在浏览器中运行javascript时,将动态加载数据并更改DOM。 rvest不会发生这种情况。

在浏览器中,以下选择器将隔离您的节点:

.twoCountryWrapper .countryNameAndYearQC:nth-child(1) .countryNameQC
.twoCountryWrapper .countryNameAndYearQC:nth-child(1) .countryYear 
.twoCountryWrapper .countryNameAndYearQC:nth-child(2) .countryNameQC
.twoCountryWrapper .countryNameAndYearQC:nth-child(2) .countryYear

但是,这些类甚至都没有出现在rvest返回中。

感兴趣的数据实际上存储在几个节点中;所有ID的公共前缀都为dspQCLinks。内部数据如下所示:

enter image description here

因此,您可以使用css attribute = value以运算符(^)开头的语法来收集所有这些节点:

html_nodes(page, "[id^=dspQCLinks]")

然后提取文本并合并为一个字符串

paste(html_text(html_nodes(page, "[id^=dspQCLinks]")), collapse = '')

现在中的每一行都由!,分隔,因此我们可以对其进行拆分以生成行:

info = strsplit(paste(html_text(html_nodes(page, "[id^=dspQCLinks]")), collapse = ''),"!,")[[1]]

示例行将如下所示:

"Albania@/uk/taxsummaries/wwts.nsf/ID/Albania-Corporate-Taxes-on-corporate-income@15"

如果我们在@上拆分每一行,则所需数据位于索引1和3:

arr = strsplit(i, '@')[[1]]
country <- arr[1]
tax <- arr[3]

由于@Brian的反馈,我删除了构建数据框所必需的循环,并用引号@Brian代替, str_split_fixed(info, "@", 3) [哪个]为您提供了一个字符矩阵,可以将其直接强制转换为数据框。

df <- data.frame(str_split_fixed(info, "@", 3))

然后删除df底部的空行。

 df <- df[df$Country != "",] 

df示例:

enter image description here


R

library(rvest)
library(stringr)
library(magrittr)

page <- read_html('http://taxsummaries.pwc.com/ID/Corporate-income-tax-(CIT)-rates')
info =  strsplit(paste(html_text(html_nodes(page, "[id^=dspQCLinks]")), collapse = ''),"!,")[[1]]
df <- data.frame(str_split_fixed(info, "@", 3))
colnames(df) <- c("Country","Link","Tax")
df <- subset(df, select = c("Country","Tax"))
df <- df[df$Country != "",] 
View(df)

Python:

我首先在python中这样做,对我来说更快:

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd

r = requests.get('http://taxsummaries.pwc.com/ID/Corporate-income-tax-(CIT)-rates')
soup = bs(r.content, 'lxml')
text = ''

for i in soup.select('[id^=dspQCLinks]'):
    text+= i.text

rows = text.split('!,')
countries = []
tax_info = []

for row in rows:
    if row:
        items = row.split('@')
        countries.append(items[0])
        tax_info.append(items[2])

df = pd.DataFrame(list(zip(countries,tax_info)))
print(df)

阅读:

  1. str_split_fixed