【问题标题】:How to scrape 'In more languages' table on Wikidata?如何在 Wikidata 上抓取“更多语言”表?
【发布时间】:2022-06-23 17:21:55
【问题描述】:

我正在尝试在 Wikidata 页面上抓取整个“更多语言”表,例如https://www.wikidata.org/wiki/Q3044

我在 R 中尝试了 2 种方法:

library(rvest)
url <- "https://www.wikidata.org/wiki/Q3044"
pg <- url %>% read_html

pg <- pg %>% 
  html_nodes(".wikibase-entitytermsforlanguagelistview") %>%
  html_table()

table <- pg[[1]]

但这仅返回英文部分(1 行)。

我也试过了:

library(tidywikidatar)
tw_get_label(id = c("Q3044"),language = "nl")

但这只会返回一个标签。但是,我想要 Wikidata 上的所有“也称为”类别。

任何帮助将不胜感激!

【问题讨论】:

    标签: r wikidata


    【解决方案1】:

    真是个好问题。您只获得了表格的第一行,因为这就是页面最初加载的全部内容,并且在后台发生了一些 JavaScript 魔术以在页面加载后加载表格的其余部分。如果您重新加载页面并仔细观察,您会看到这种情况 - 我在下面添加了一个 gif 来展示这一点。由于 R 没有运行所有额外的魔法,它得到的只是原始页面。

    然而,这意味着我们需要寻找一个不同的 URL 来获取整个表。使用 Chrome 的开发者工具,我们了解到该表来自https://www.wikidata.org/wiki/Special:EntityData/Q3044.json,而这正是我们真正想要抓取的页面。如果我们使用jsonLite 下载它,我们不会准确地得到表格,但我们可以使用一些dplyr 工具重新组装它。这是执行此操作的 sn-p 代码:

    
    wiki_data <- jsonlite::read_json("https://www.wikidata.org/wiki/Special:EntityData/Q3044.json")
    table_data <- wiki_data$entities$Q3044
    
    library(dplyr)
    label_col <- bind_rows(table_data$labels) %>% rename(label=value)
    desc_col <- bind_rows(table_data$descriptions) %>% rename(description=value)
    alias_col <- bind_rows(table_data$aliases) %>% 
      rename(alias=value) %>%
      group_by(language) %>%
      summarise(alias=paste(alias, collapse = ", "))
    
    full_table <- label_col %>%
      left_join(desc_col) %>%
      left_join(alias_col)
    

    输出的前几行如下所示:

    > full_table
    # A tibble: 157 x 4
       language label                         description                                        alias
       <chr>    <chr>                         <chr>                                              <chr>
     1 fr       Charlemagne                   empereur d'Occident et roi des Francs              Char~
     2 en       Charlemagne                   King of the Franks, King of Italy, and Holy Roman~ Karo~
     3 it       Carlo Magno                   re dei Franchi e dei Longobardi e primo imperator~ NA   
     4 ilo      Karlomagno                    Ari dagiti Pranko ken Lombardo ken Emperador ti N~ NA   
    

    【讨论】:

      【解决方案2】:

      这也可以通过tidywikidatar 实现,因为标签和别名都包含在对tw_get() 的响应中。

      您可以通过使用相关语言代码作为参数来获取给定语言的标签和别名,或者如文档中所述,如果您对所有可用语言的标签和别名感兴趣,请使用all_available。请参阅下面的 reprex 以供参考:

      library("tidywikidatar")
      item_df <- tw_get(id = c("Q3044"),
                        language = "all_available")
      
      item_df %>%
        dplyr::filter(stringr::str_starts(string = property, pattern = "label"))
      #> # A tibble: 158 × 4
      #>    id    property  value                         rank 
      #>    <chr> <chr>     <chr>                         <chr>
      #>  1 Q3044 label_fr  Charlemagne                   <NA> 
      #>  2 Q3044 label_en  Charlemagne                   <NA> 
      #>  3 Q3044 label_it  Carlo Magno                   <NA> 
      #>  4 Q3044 label_ilo Karlomagno                    <NA> 
      #>  5 Q3044 label_af  Karel die Grote               <NA> 
      #>  6 Q3044 label_gsw Karl dr Gross                 <NA> 
      #>  7 Q3044 label_an  Carlos Magno                  <NA> 
      #>  8 Q3044 label_ang Carl sē Micel Francena Cyning <NA> 
      #>  9 Q3044 label_ar  شارلمان                       <NA> 
      #> 10 Q3044 label_arz شارلمان                       <NA> 
      #> # … with 148 more rows
      
      item_df %>%
        dplyr::filter(stringr::str_starts(string = property, pattern = "alias"))
      #> # A tibble: 55 × 4
      #>    id    property value                                rank 
      #>    <chr> <chr>    <chr>                                <chr>
      #>  1 Q3044 alias_en Karolus Magnus                       <NA> 
      #>  2 Q3044 alias_en Charles the Great                    <NA> 
      #>  3 Q3044 alias_en Emperor Charlemagne                  <NA> 
      #>  4 Q3044 alias_en Karl the Great                       <NA> 
      #>  5 Q3044 alias_en Carolus Magnus                       <NA> 
      #>  6 Q3044 alias_en King of the Franks Charles the Great <NA> 
      #>  7 Q3044 alias_en King of the Franks Charlemagne       <NA> 
      #>  8 Q3044 alias_en Charlemagne the Franc                <NA> 
      #>  9 Q3044 alias_en Charles I                            <NA> 
      #> 10 Q3044 alias_fr Charles Ier                          <NA> 
      #> # … with 45 more rows
      
      item_df %>%
        dplyr::filter(stringr::str_starts(string = property, pattern = "label")|stringr::str_starts(string = property, pattern = "alias"))
      #> # A tibble: 213 × 4
      #>    id    property  value                         rank 
      #>    <chr> <chr>     <chr>                         <chr>
      #>  1 Q3044 label_fr  Charlemagne                   <NA> 
      #>  2 Q3044 label_en  Charlemagne                   <NA> 
      #>  3 Q3044 label_it  Carlo Magno                   <NA> 
      #>  4 Q3044 label_ilo Karlomagno                    <NA> 
      #>  5 Q3044 label_af  Karel die Grote               <NA> 
      #>  6 Q3044 label_gsw Karl dr Gross                 <NA> 
      #>  7 Q3044 label_an  Carlos Magno                  <NA> 
      #>  8 Q3044 label_ang Carl sē Micel Francena Cyning <NA> 
      #>  9 Q3044 label_ar  شارلمان                       <NA> 
      #> 10 Q3044 label_arz شارلمان                       <NA> 
      #> # … with 203 more rows
      

      reprex package (v2.0.1) 于 2022 年 6 月 23 日创建

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多