我无法使用 R 抓取 Glassdoor.com 的一个元素
I cannot scrape one element of Glassdoor.com using R
我正在尝试从 Glassdoor.com 中为一个项目抓取一些数据。这是我到目前为止的代码:
## Load libraries
library(httr)
library(xml2)
library(rvest)
library(purrr)
library(tidyverse)
library(lubridate)
# URLS for scraping
start_url <- "https://www.glassdoor.co.uk/Reviews/Company-Reviews-"
settings_url <- ".htm?sort.sortType=RD&sort.ascending=false&filter.iso3Language=eng"
### Scrape Reviews
map_df(1:1, function(i){
Sys.sleep(3)
tryCatch({
pg_reviews <- read_html(GET(paste(start_url, "E8450", "_P", i, settings_url, sep = "")))
table = pg_reviews %>%
html_elements(".mb-0")
data.frame(date = pg_reviews %>%
html_elements(".middle.common__EiReviewDetailsStyle__newGrey") %>%
html_text2(),
summary = pg_reviews %>%
html_elements(".reviewLink") %>%
html_text(),
rating = pg_reviews %>%
html_elements("#ReviewsFeed .mr-xsm") %>%
html_text(),
employee_type = pg_reviews %>%
html_elements(".eg4psks0") %>%
html_text(),
pros = pg_reviews %>%
html_elements(".v2__EIReviewDetailsV2__fullWidth:nth-child(1) span") %>%
html_text(),
cons = pg_reviews %>%
html_elements(".v2__EIReviewDetailsV2__fullWidth:nth-child(2) span") %>%
html_text()
)}, error = function(e){
NULL
})
}) -> reviews_df
到这里一切正常。但是,我也想在某些评论中删除个人评分:
picture
但我真的很难找到与这些评级相关的特定元素。我很乐意提出我的看法,但我完全迷失了这一点。我已尝试使用 SelectorGadget 并检查页面,但我似乎无法管理。
有什么建议吗?
定位数据
检查这些评级中的星星,显示它们具有以下 HTML 结构:
...
<div class="content">
<ul class="pl-0">
<li>
<div>Work/Life Balance</div>
<div font-size="sm" class="css-18v8tui e1hd5jg10">
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
</div>
</li>
<li>
<div>Culture & Values</div>
<div font-size="sm" class="css-18v8tui e1hd5jg10">
...
CSS定义了其中有多少个是彩色的,通过'Work/Life Balance'下的div的class,例如:
<div font-size="sm" class="css-18v8tui e1hd5jg10">
我们在文档的其他地方找到对应的CSS:
<style data-emotion-css="18v8tui">
.css-18v8tui {
display: inline-block;
line-height: 1;
background: linear-gradient(90deg, #0caa41 40%, #dee0e3 40%);
-webkit-letter-spacing: 3px;
-moz-letter-spacing: 3px;
-ms-letter-spacing: 3px;
letter-spacing: 3px;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
background
值中的 40%
将 div 的 40% 设置为黄色,使本例中 40% 的星星点亮。
提取数据
首先我们加载页面
url = "https://www.glassdoor.co.uk/Reviews/PwC-Reviews-E8450.htm?sort.sortType=RD&sort.ascending=false&filter.iso3Language=eng"
pg_reviews = read_html(url)
然后我们提取所有 <style>
个元素,在本例中每个元素都包含一个 class。我们将 CSS class 中的任何 ...% 值和 divide 中的任何值乘以 20,以将百分比转换为星数。我们将这个数量的星星保存在一个命名向量中,其中每个字段的名称是对应的 CSS class 的名称。这将使我们能够将评级的 CSS class 与许多星相关联。
class.ratings = c()
styles = pg_reviews %>% html_elements('style')
for(s in styles) {
class = s %>% html_attr('data-emotion-css')
class = paste0('css-', class)
rating = str_match(s %>% html_text2(), '(\d+)%')[2]
class.ratings[class] = as.numeric(rating)/20
}
> class.ratings
css-animation-1fypb1g css-197m635 css-67i7qe
NA 5.0 5.0
css-3x0lbp css-hdvrkk css-8hewl0
NA 5.0 5.0
css-1x8evti css-1ohf0ui css-1htgz7a
NA NA 5.0
...
并非我们发现的每个百分比都与 star-rating 真正相关,但这没关系。
最后我们抓取所有评论,每个评论都在 class gdReview
的元素中。对于每条评论,我们都会获取所有 star-rating,每个都在 class content
的元素中,在 li
元素中。对于每个 star-rating 我们提取文本标签和 CSS class 作为星星的数量。我不做任何导出结果,只是将它们输出到控制台:
reviews = pg_reviews %>% html_elements('.gdReview')
for(re in reviews) {
ratings = re %>% html_elements('.content') %>% html_elements('li')
for(ra in ratings) {
label = ra %>% html_element('div') %>% html_text()
classes = ra %>% html_elements('div[font-size="sm"]') %>% html_attr('class')
class = str_split(classes, ' ')[[1]][1] # take the first class attribute
cat(label, class.ratings[class], '\n')
}
cat('\n')
}
输出:
Work/Life Balance 5
Culture & Values 5
Diversity & Inclusion 5
Career Opportunities 5
...
由于并非每个评论都包含这些 star-rating 每个子类别,因此会有一些空白字段。
我正在尝试从 Glassdoor.com 中为一个项目抓取一些数据。这是我到目前为止的代码:
## Load libraries
library(httr)
library(xml2)
library(rvest)
library(purrr)
library(tidyverse)
library(lubridate)
# URLS for scraping
start_url <- "https://www.glassdoor.co.uk/Reviews/Company-Reviews-"
settings_url <- ".htm?sort.sortType=RD&sort.ascending=false&filter.iso3Language=eng"
### Scrape Reviews
map_df(1:1, function(i){
Sys.sleep(3)
tryCatch({
pg_reviews <- read_html(GET(paste(start_url, "E8450", "_P", i, settings_url, sep = "")))
table = pg_reviews %>%
html_elements(".mb-0")
data.frame(date = pg_reviews %>%
html_elements(".middle.common__EiReviewDetailsStyle__newGrey") %>%
html_text2(),
summary = pg_reviews %>%
html_elements(".reviewLink") %>%
html_text(),
rating = pg_reviews %>%
html_elements("#ReviewsFeed .mr-xsm") %>%
html_text(),
employee_type = pg_reviews %>%
html_elements(".eg4psks0") %>%
html_text(),
pros = pg_reviews %>%
html_elements(".v2__EIReviewDetailsV2__fullWidth:nth-child(1) span") %>%
html_text(),
cons = pg_reviews %>%
html_elements(".v2__EIReviewDetailsV2__fullWidth:nth-child(2) span") %>%
html_text()
)}, error = function(e){
NULL
})
}) -> reviews_df
到这里一切正常。但是,我也想在某些评论中删除个人评分: picture
但我真的很难找到与这些评级相关的特定元素。我很乐意提出我的看法,但我完全迷失了这一点。我已尝试使用 SelectorGadget 并检查页面,但我似乎无法管理。
有什么建议吗?
定位数据
检查这些评级中的星星,显示它们具有以下 HTML 结构:
...
<div class="content">
<ul class="pl-0">
<li>
<div>Work/Life Balance</div>
<div font-size="sm" class="css-18v8tui e1hd5jg10">
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
<span class="gd-ui-star css-vk03c5 e7cj4650" color="#0caa41" font-size="sm" tabindex="0" role="presentation">★</span>
</div>
</li>
<li>
<div>Culture & Values</div>
<div font-size="sm" class="css-18v8tui e1hd5jg10">
...
CSS定义了其中有多少个是彩色的,通过'Work/Life Balance'下的div的class,例如:
<div font-size="sm" class="css-18v8tui e1hd5jg10">
我们在文档的其他地方找到对应的CSS:
<style data-emotion-css="18v8tui">
.css-18v8tui {
display: inline-block;
line-height: 1;
background: linear-gradient(90deg, #0caa41 40%, #dee0e3 40%);
-webkit-letter-spacing: 3px;
-moz-letter-spacing: 3px;
-ms-letter-spacing: 3px;
letter-spacing: 3px;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
background
值中的 40%
将 div 的 40% 设置为黄色,使本例中 40% 的星星点亮。
提取数据
首先我们加载页面
url = "https://www.glassdoor.co.uk/Reviews/PwC-Reviews-E8450.htm?sort.sortType=RD&sort.ascending=false&filter.iso3Language=eng"
pg_reviews = read_html(url)
然后我们提取所有 <style>
个元素,在本例中每个元素都包含一个 class。我们将 CSS class 中的任何 ...% 值和 divide 中的任何值乘以 20,以将百分比转换为星数。我们将这个数量的星星保存在一个命名向量中,其中每个字段的名称是对应的 CSS class 的名称。这将使我们能够将评级的 CSS class 与许多星相关联。
class.ratings = c()
styles = pg_reviews %>% html_elements('style')
for(s in styles) {
class = s %>% html_attr('data-emotion-css')
class = paste0('css-', class)
rating = str_match(s %>% html_text2(), '(\d+)%')[2]
class.ratings[class] = as.numeric(rating)/20
}
> class.ratings
css-animation-1fypb1g css-197m635 css-67i7qe
NA 5.0 5.0
css-3x0lbp css-hdvrkk css-8hewl0
NA 5.0 5.0
css-1x8evti css-1ohf0ui css-1htgz7a
NA NA 5.0
...
并非我们发现的每个百分比都与 star-rating 真正相关,但这没关系。
最后我们抓取所有评论,每个评论都在 class gdReview
的元素中。对于每条评论,我们都会获取所有 star-rating,每个都在 class content
的元素中,在 li
元素中。对于每个 star-rating 我们提取文本标签和 CSS class 作为星星的数量。我不做任何导出结果,只是将它们输出到控制台:
reviews = pg_reviews %>% html_elements('.gdReview')
for(re in reviews) {
ratings = re %>% html_elements('.content') %>% html_elements('li')
for(ra in ratings) {
label = ra %>% html_element('div') %>% html_text()
classes = ra %>% html_elements('div[font-size="sm"]') %>% html_attr('class')
class = str_split(classes, ' ')[[1]][1] # take the first class attribute
cat(label, class.ratings[class], '\n')
}
cat('\n')
}
输出:
Work/Life Balance 5
Culture & Values 5
Diversity & Inclusion 5
Career Opportunities 5
...
由于并非每个评论都包含这些 star-rating 每个子类别,因此会有一些空白字段。