Wir möchten uns noch weitere Details zu den Abgeordneten holen, bevor wir mit den Tweets der Abgeordneten weitermachen. Hierzu wollen wir uns insbesondere die Ausschussmitgliedschaften der einzelnen Abgeordneten ansehen. Dabei interessiert uns auch, welche Positionen die MEPs in den Ausschüssen einnehmen (Chair, Vice-Chair, Mitglied oder Ersatz). Tatsächlich gestaltete es sich gar nicht so einfach, diese Daten abzugreifen. Später dazu mehr. Wir laden zunächst folgende Pakete:
library(tidyverse)
library(rvest)
library(furrr)
plan(multiprocess)
Auf den jeweiligen Profilen der MEPs finden ich die Angaben über die Mitgliedschaft in den Ausschüssen. Beispielsweise ist der Abgeordente Asim Ademov Mitglied in den Ausschüssen LIBE und DACP und Ersatzmitglied in den Ausschüssen AFET, DROI und DARP.
Das bereits angesprochene SelectorGadget in Verbindung mit rvest
hilft uns zunächst nur bedingt. Wir können herausfinden, dass read_html(url) %>% html_nodes("#mepPortfolioDiv h4 , #mepPortfolioDiv li") %>% html_text()
uns alle Mitgliedschaften ausgeben. Aber leider würde dabei verloren gehen, in welchen Ausschüssen er welche Position einnimmt.
Wir nutzen hierfür eine andere Mgölichkeit und bedienen uns des xpath
. Ein besonders tiefgreifender Einblick in webscraping mit xpath
findet sich in diesem Tutorial.
get_positions <- function(x){
details <- read_html(x)
id <- x %>% str_extract("-?\\d+")
chair <- details %>%
xml_find_all('//h4[starts-with(.,"Chair")]/following-sibling::ul[1]') %>%
xml_find_all(".//acronym") %>% xml_text() %>% list()
vicechair <- details %>%
xml_find_all('//h4[contains(.,"Vice-Chair")]/following-sibling::ul[1]') %>%
xml_find_all(".//acronym") %>% xml_text() %>% list()
member <- details %>%
xml_find_all('//h4[contains(.,"Member")]/following-sibling::ul[1]') %>%
xml_find_all(".//acronym") %>% xml_text() %>% list()
substitute <- details %>%
xml_find_all('//h4[contains(.,"Substitute")]/following-sibling::ul[1]') %>%
xml_find_all(".//acronym") %>% xml_text() %>% list()
data_frame(id, chair, vicechair, member, substitute)
}
Was macht diese Funktion? Wir suchen auf jeder Seite der Abgeordneten nach der Überschrift “Chair”, “Vice-Chair”, “Member” oder “Substitute” und übernehmen die danach folgende Liste an Acronymen. Somit können wir uns alle Positionen eines jeden Abgeordneten ziehen.
Wir wenden diese Funktion nun auf alle Abgeordneten an.
mep_website <- read_html("http://www.europarl.europa.eu/meps/en/full-list.html?filter=all&leg=") %>%
html_nodes(".mep_name") %>%
html_nodes("a") %>%
html_attr("href") %>%
paste0("http://www.europarl.europa.eu", .)
mep_positions <- future_map_dfr(mep_website, ~get_positions(.), .progress = TRUE)
Wir können überprüfen, ob das ganze funktioniert hat, indem wir uns die Liste Vorsitzenden der Ausschüsse ausgeben lassen.
Wir können die Vorsitzenden von 71 Ausschüssen ausmachen. Das sind ein wenig viele. Hier sind auch sehr viele Delegationen vorhanden, etwa D-ZA (European Parliament’s Delegation for Relations with South Africa). Diese Delegationen interessieren uns aber nicht besonders, wir möchten nur die Daten der wichtigsten Ausschüsse. Dies sind die folgenden:
ep_committees <- read_html("http://www.europarl.europa.eu/committees/en/parliamentary-committees.html")
ep_committees <- data_frame(label = ep_committees %>%
html_nodes(xpath = '//*[@id="content_left"]/div/span/a') %>% html_text(),
title = ep_committees %>%
html_nodes(xpath = '//*[@id="content_left"]/div/h5/a') %>% html_text())
mep_details <- readRDS("data/mep_details.RDS")
committee_chairs <- ep_committees %>%
left_join(mep_positions %>% unnest(chair), by = c("label" = "chair")) %>%
left_join(mep_details, by = "id") %>%
select(label, title, name)
committee_chairs
## # A tibble: 29 x 3
## label title name
## <chr> <chr> <chr>
## 1 AFET Foreign Affairs DavidMcALLISTER
## 2 DROI Human Rights Pier AntonioPANZERI
## 3 SEDE Security and Defence Anna ElżbietaFOTYGA
## 4 DEVE Development LindaMcAVAN
## 5 INTA International Trade BerndLANGE
## 6 BUDG Budgets JeanARTHUIS
## 7 CONT Budgetary Control IngeborgGRÄSSLE
## 8 ECON Economic and Monetary Affairs RobertoGUALTIERI
## 9 EMPL Employment and Social Affairs ThomasHÄNDEL
## 10 ENVI Environment, Public Health and Food Safety Adina-IoanaVĂLEAN
## # ... with 19 more rows
Allerdings weißen 4 Ausschüsse keine Vorsitzenden auf. Es handelt sich um zeitlich begrenzte Ausschüsse, welche ihre bisherige Arbeit eingestellt haben (TAXE, TAX2, EMIS, PANA). Siehe auch diese Übersicht.
Zuletzt speichern wir alle relevanten Daten.
saveRDS(ep_committees, "data/ep_committees.RDS")
saveRDS(mep_positions, "data/mep_positions.RDS")