(Acest articol a fost publicat pentru prima dată pe pacha.dev/blogși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)
Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.
Din cauza întârzierilor cu plata bursei mele, dacă această postare vă este utilă, vă cer cu drag o donație minimă pentru a -mi cumpăra o cafea. Acesta va fi folosit pentru a continua eforturile mele open source. Explicația completă este aici: un mesaj personal de la un contribuabil open source.
Continuând cu postarea anterioară Selenium, acum voi prelucra fiecare ofertă de muncă și voi organiza conținutul acesteia.
Acest lucru necesită pachetul Readxl pentru a citi fișiere XLSX:
if (!require(readxl)) install.packages("readxl")
Pentru a citi XLSX din partea2 și a începe să citești fiecare ofertă cu care încep:
library(RSelenium)
library(rvest)
library(dplyr)
library(purrr)
library(writexl)
library(readxl)
offers_tbl <- read_xlsx("offers_20250821.xlsx")
rmDr <- remoteDriver(port = 4444L, browserName = "chrome")
rmDr$open(silent = TRUE)
Din acest tabel, pot continua să citesc HTML pentru fiecare ofertă de muncă și să văd cum este structurat. Începând cu prima adresă URL:
rmDr$navigate(offers_tbl$link(1)) html <- read_html(rmDr$getPageSource()((1)))
Această ofertă de muncă specifică are următorul conținut:
> html
{html_document}
(1) n
Inspecting the details in the offer as in part 1, the full description is contained in a single HTML division with sub-divisions:
Medico (a) especialista en Anestesiología
Institución
Ministerio de Salud / Servicio de Salud Maule / Hospital de Constitución
Convocatoria
Medico (a) especialista en Anestesiología 44 horas
Nº de Vacantes
1
Área de Trabajo
Salud
Región
Región del Maule
Ciudad
Constitución
Tipo de Vacante
Contrata
...
To organize this in a table, I can do the following amongh other possibilities to get the title, institution, number of offers, city, compensation, and educational requirements:
title <- html %>% html_element("h2 span#lblAvisoTrabajo") %>% html_text(trim = TRUE)
institution <- html %>% html_element("span#lblAvisoTrabajoDatos h3:contains('Institución') + p") %>% html_text(trim = TRUE)
positions <- html %>% html_element("span#lblAvisoTrabajoDatos h3:contains('Nº de Vacantes') + p") %>% html_text(trim = TRUE)
city <- html %>% html_element("span#lblAvisoTrabajoDatos h3:contains('Ciudad') + p") %>% html_text(trim = TRUE)
compensation <- html %>% html_element("span#lblRenta li ul li") %>% html_text(trim = TRUE)
education <- html %>% html_element("span#lblFormacion p") %>% html_text(trim = TRUE)
d <- tibble(
title = title,
institution = institution,
positions = positions,
city = city,
compensation = compensation,
education = education
)
Rezultatul este următorul tabel:
> d
# A tibble: 1 × 6
title institution positions city compensation education
1 Medico (a) especialista en… Ministerio… 1 Cons… Renta Bruta… Título p…
Văd că valoarea compensării are nevoie de ordonare:
> d$compensation
(1) "Renta Bruta6.398.194"
Pentru a -l aranja, pot face acest lucru pentru a elimina separatoarele de text și numere de frunte:
d <- d %>%
mutate(compensation = as.numeric(gsub("Renta Bruta|\.", "", compensation)))
Ceea ce duce la valoarea dorită pentru analiza posterioară:
> d$compensation
(1) 6398194
Pentru a face același lucru cu fiecare dintre cele 545 de oferte salvate, repetăm la fel cu Purrr:
descriptions_tbl <- map_df(
seq_len(nrow(offers_tbl)),
function(x) {
print(x) # just to see at which iteration it fails (if it fails)
rmDr$navigate(offers_tbl$link(x))
html <- read_html(rmDr$getPageSource()((1)))
title <- html %>% html_element("h2 span#lblAvisoTrabajo") %>% html_text(trim = TRUE)
institution <- html %>% html_element("span#lblAvisoTrabajoDatos h3:contains('Institución') + p") %>% html_text(trim = TRUE)
positions <- html %>% html_element("span#lblAvisoTrabajoDatos h3:contains('Nº de Vacantes') + p") %>% html_text(trim = TRUE)
city <- html %>% html_element("span#lblAvisoTrabajoDatos h3:contains('Ciudad') + p") %>% html_text(trim = TRUE)
compensation <- html %>% html_element("span#lblRenta li ul li") %>% html_text(trim = TRUE)
education <- html %>% html_element("span#lblFormacion p") %>% html_text(trim = TRUE)
d <- tibble(
title = title,
institution = institution,
positions = positions,
city = city,
compensation = compensation,
education = education
)
d <- d %>%
mutate(compensation = as.numeric(gsub("Renta Bruta|\.", "", compensation)))
d
}
)
Rezultatul este următorul:
> descriptions_tbl
# A tibble: 545 × 6
title institution positions city compensation education
1 Medico (a) especialista e… Ministerio… 1 Cons… 6398194 "Título …
2 NA NA NA NA NA NA
3 ENFERMERA-O, JORNADA DIUR… Ministerio… 1 Reco… 1906087 "Título …
4 Psiquiatra infanto-juveni… Ministerio… 1 La P… 2333658 ""
5 Neurólogo(a) adulto GES A… Ministerio… 1 Puen… 637926 ""
6 Médico(a) especialista en… Ministerio… 2 Cast… 5328446 "Título …
7 Arquitecto de Software Ministerio… 1 Ñuñoa 2256523 "Profesi…
8 DIRECCIÓN DEL SERVICIO DE… Ministerio… 1 Chil… 1540891 ""
9 01 CARGO DE TENS OPERADOR… Ministerio… 1 Peña… 851161 ""
10 TENS DE CUIDADOS PALIATIV… Ministerio… 2 San … 636462 "Titulo …
# ℹ 535 more rows
Există câteva rânduri goale din cauza legăturilor sub întreținere sau care duc la site -uri municipale externe cu o structură diferită.
Iată o poveste a semifabricilor de pe fiecare câmp:
descriptions_tbl %>%
summarise(
across(
everything(),
list(
na_count = ~sum(is.na(.))
),
.names = "{.col}_{.fn}"
)
)
ceea ce arată că toate valorile goale corespund acelorași observații:
# A tibble: 1 × 6
title_na_count institution_na_count positions_na_count city_na_count
1 187 187 187 187
# ℹ 2 more variables: compensation_na_count , education_na_count
Am primit 547 - 187 = 360 observații bine organizate cu un proces de răzuire care a durat aproximativ cinci minute. Nu-i rău!
Aceasta are nevoie de o copie de rezervă XLSX pentru a evita răzuirea de două ori:
write_xlsx(descriptions_tbl, "descriptions_20250821.xlsx")
Sper că acest lucru a fost util. În părțile următoare voi acoperi câteva analize și comploturi cu aceste date.
