2017-01-16 2 views
1

Ich habe ein Problem mit dem Scraping von Informationen aus einem bestimmten XML-Dokument (http://www.bundestag.de/xml/mdb/index.xml).Scraping eines XML-Dokuments (geschachtelte URL-Struktur)

<mdbUebersicht> 
<dokumentInfo> 
<dokumentURL/> 
<dokumentStand/> 
</dokumentInfo> 
<deleteRestore> 
<deleteFlag>0</deleteFlag> 
<deleteDate>20131202170000</deleteDate> 
</deleteRestore> 
<mdbs> 
<mdb fraktion="Die Linke"> 
<mdbID status="Aktiv">1627</mdbID> 
<mdbName status="Aktiv">Aken, Jan van</mdbName> 
<mdbBioURL> 
http://www.bundestag.de/abgeordnete18/biografien/A/aken_jan/258124 
</mdbBioURL> 
<mdbInfoXMLURL> 
http://www.bundestag.de/xml/mdb/biografien/A/aken_jan.xml 
</mdbInfoXMLURL> 
<mdbInfoXMLURLMitmischen>/biografien/A/aken_jan.xml</mdbInfoXMLURLMitmischen> 
<mdbLand>Hamburg</mdbLand> 
<mdbFotoURL> 
http://www.bundestag.de/blueprint/servlet/image/240714/Hochformat__2x3/177/265/83abda4f387877a2b5eeedbfd81e8eba/Yc/aken_jan_gross.jpg 
</mdbFotoURL> 
<mdbFotoGrossURL> 
http://www.bundestag.de/blueprint/servlet/image/240714/Hochformat__2x3/316/475/83abda4f387877a2b5eeedbfd81e8eba/Uq/aken_jan_gross.jpg 
</mdbFotoGrossURL> 
<mdbFotoLastChanged>24.10.2016</mdbFotoLastChanged> 
<mdbFotoChangedDateTime>24.10.2016 12:17</mdbFotoChangedDateTime> 
<lastChanged>30.09.2016</lastChanged> 
<changedDateTime>30.09.2016 12:38</changedDateTime> 
</mdb> 

Das Dokument enthält viele kurze biographische Aspekte von verschiedenen Personen. Unter anderem enthält es URLs zu anderen XML-Dokumenten, die eine detailliertere Biografie enthalten.

ich folgendes versuchen, die Informationen zu bekommen:

Zuerst versuche ich alle URLs für die verschiedenen Unterlagen zu bekommen von der maindocument

mdb_url <- xml_text(xml_find_all(xmlDocu, "//mdbInfoXMLURL")) 

Dann implementiert ich eine for-Schleife, die alle herunterladen xml in meinem Verzeichnis

for (url in mdb_url) { 
    download.file(url, destfile = basename(url)) 
} 

Danach möchte ich eine Liste der Dateien empfangen ...

files <- list.files(pattern = ".xml") 

... einen bestimmten Knoten jedes XML-Dokument erhalten:

Bio1 <- files[1] 

xmlfile <- read_xml(Bio1) 

mdb_ausschuss1 <- xml_text(xml_find_all(xmlfile, "//gremiumName")) 

Jetzt habe ich das Problem, wie ich es für alle XML-Dateien in der Liste tun? Ich habe nicht in der Lage gewesen, für diese Aufgabe eine funktionelle Schleife oder ein Skript zu schreiben ...

Antwort

1
library(xml2) 
library(httr) 
library(rvest) 
library(tools) 
library(tidyverse) 

URL <- "http://www.bundestag.de/xml/mdb/index.xml" 
doc <- read_xml(URL) 
xml_find_all(doc, "//mdbInfoXMLURL") %>% xml_text() -> mdb_urls 

erstellen Ort, um die URL-Liste von der Hauptseite XML Bring sie speichern:

dir.create("docs") 

sie auf die Festplatte schreiben (ich bin Grabbing 10 von ihnen nur, da ich die Daten nicht mehr benötigen, tun Sie :-)

Hinweis t Hut write_disk() wird den Pfad nicht überschreiben, es sei denn, es wurde gesagt, so ist dies eine gute Möglichkeit, die Zwischenspeicherung von Armen-Mann zu tun. Wenn Sie dies in ein reproduzierbares Skript einfügen, müssen Sie versuchen, es zu umbrechen.

walk(mdb_urls[1:10], ~GET(., write_disk(file.path("docs", basename(.))))) 

Erhalten Sie die Dateiliste:

fils <- list.files("docs", pattern=".*.xml", full.names=TRUE) 

Schalten in einen Datenrahmen:

pb <- progress_estimated(length(fils)) # use a progress bar 
map_df(fils, function(x) { 

    pb$tick()$print() # increment the progress bar 

    gremium_doc <- read_xml(x) # read in the file 

    # find all the `gremiumName`s. If there are none, make the value `NA` 
    xml_find_all(gremium_doc, "//gremiumName") %>% xml_text() -> g_names 
    if (length(g_names) == 0) g_names <- NA_character_ 

    # make a tidy data frame 
    data_frame(gremium=file_path_sans_ext(basename(x)), name=g_names) 

}) -> df 

Beweisen Sie es funktioniert

glimpse(df) 
## Observations: 33 
## Variables: 2 
## $ gremium <chr> "aken_jan", "aken_jan", "aken_jan", "aken_jan", "alban... 
## $ name <chr> "Auswärtiger Ausschuss", "Gremium nach § 23c Absatz 8 ... 
+0

funktioniert super! Danke vielmals! –

+0

Vielleicht könntest du mir noch ein letztes Mal helfen: Wie könnte ich die Datenstruktur in diesem Fall von lang auf weit drehen? In diesem Sinne gibt es für jedes neue Gremium eine neue Kolumne mit dem Attribut "Auswärtiger Ausschuss", "Wirtschaftsausschuss" etc. "wahr" oder "nicht". Ich habe den Befehl "resphape" ausprobiert, aber ich komme nicht dorthin. –

+0

völlig separate Frage (SO Regeln/Richtlinien vorschlagen, dass Shld eine neue q sein) – hrbrmstr