Как извлечь данные из категории Digida: различия между версиями
Материал из Поле цифровой дидактики
Patarakin (обсуждение | вклад) Новая страница: «{{Scripting Tutorials |Description=Мы хотим проанализировать тексты, которые хранятся в статья определенной категории поля цифровой дидактики. Есть 2 способа - экспорт статей и использование MediaWiki API |Field_of_knowledge=Лингвистика, Статистика |Возрастная категория=16 |Environment=R, S...» |
Patarakin (обсуждение | вклад) Нет описания правки |
||
| (не показано 6 промежуточных версий этого же участника) | |||
| Строка 5: | Строка 5: | ||
|Environment=R, Semantic MediaWiki, MediaWiki API | |Environment=R, Semantic MediaWiki, MediaWiki API | ||
}} | }} | ||
== Использовать Экспорт статей == | |||
Воспользоваться [[Служебная:Экспорт]] и скачать все статьи из категории | |||
== Использовать R == | |||
<syntaxhighlight lang="R" line> | |||
library(httr2) | |||
library(jsonlite) | |||
library(tidyverse) | |||
library(ggplot2) | |||
library(quanteda) | |||
library(stopwords) | |||
getwd() | |||
base_url <- "http://digida.mgpu.ru/api.php" | |||
ua <- "digida-research-bot/0.1 (contact: patarakined@mgpu.ru)" ## Agent | |||
############# Перечень статей в категории | |||
get_category_pages <- function(category_name, limit = 500) { | |||
params <- list( | |||
action = "query", | |||
list = "categorymembers", | |||
cmtitle = paste0("Category:", category_name), | |||
cmlimit = limit, | |||
cmtype = "page", | |||
format = "json" | |||
) | |||
response <- request(base_url) %>% | |||
req_headers( | |||
`User-Agent` = ua, | |||
`Api-User-Agent` = ua | |||
) %>% | |||
req_url_query(!!!params) %>% | |||
req_perform() | |||
data <- resp_body_string(response) %>% fromJSON() | |||
return(data$query$categorymembers) # оставить | |||
} | |||
################# | |||
get_page_content <- function(page_title) { | |||
params <- list( | |||
action = "query", | |||
titles = page_title, | |||
prop = "revisions", | |||
rvprop = "content", | |||
format = "json" | |||
) | |||
response <- request(base_url) %>% | |||
req_headers( | |||
`User-Agent` = ua, | |||
`Api-User-Agent` = ua | |||
) %>% | |||
req_url_query(!!!params) %>% | |||
req_perform() | |||
data <- resp_body_string(response) %>% fromJSON() | |||
pages_data <- data$query$pages | |||
page_info <- pages_data[[1]] | |||
if (!is.null(page_info$revisions) && nrow(page_info$revisions) > 0) { | |||
page_text <- page_info$revisions$`*`[1] | |||
} else { | |||
page_text <- NA | |||
} | |||
result <- list( | |||
pageid = page_info$pageid, | |||
title = page_info$title, | |||
content = page_text | |||
) | |||
return(result) | |||
} | |||
################ Все тексты категории | |||
get_all_category_content <- function(category_name, limit = 500, sleep_sec = 0.5) { | |||
pages_df <- get_category_pages(category_name, limit = limit) | |||
all_content <- vector("list", nrow(pages_df)) | |||
for (i in seq_len(nrow(pages_df))) { | |||
page_title <- pages_df$title[i] | |||
cat("Working with page", i, "from", nrow(pages_df), ":", page_title, "\n") | |||
tryCatch({ | |||
content <- get_page_content(page_title) | |||
all_content[[i]] <- content | |||
}, error = function(e) { | |||
cat("Mistake in", page_title, ":", e$message, "\n") | |||
}) | |||
Sys.sleep(sleep_sec) | |||
} | |||
return(all_content) # | |||
} | |||
################# | |||
data <- get_all_category_content("Работы историков ИГН", limit = 50) | |||
</syntaxhighlight> | |||
; В результате получаем: | |||
> test_all <- get_all_category_content("Работы историков ИГН", limit = 50) | |||
Working with page 1 from 40 : Адаптация европейских новшеств в XV-XVII в Русской повседневности | |||
Working with page 2 from 40 : Афганская война в советской прессе (1979 - 1989) | |||
Working with page 3 from 40 : Бургхард Кристоф Миних. Историография | |||
Working with page 4 from 40 : Взаимодействие опричной и земской администраций | |||
=== Очистка и подготовка текста === | |||
<syntaxhighlight lang="R" line> | |||
## Only text | |||
texts_vec <- vapply(test_all, function(x) x$content, FUN.VALUE = character(1)) | |||
#### | |||
clean_mediawiki_text <- function(text) { | |||
text <- gsub("\\{\\{[^}]*\\}\\}", "", text, perl = TRUE) # шаблоны {{...}} | |||
text <- gsub("\\[\\[([^|\\]]*\\|)?([^\\]]+)\\]\\]", "\\2", text) # [[ссылка|текст]] | |||
text <- gsub("\\[https?://[^ ]+ ([^\\]]+)\\]", "\\1", text) # [url текст] | |||
text <- gsub("https?://\\S+", "", text) # голые URL | |||
text <- gsub("'{2,}", "", text) # ''курсив'' | |||
text <- gsub("={2,}", " ", text) # заголовки == | |||
text <- gsub("<[^>]+>", " ", text) # HTML‑теги | |||
text <- gsub("\\s+", " ", text) | |||
trimws(text) | |||
} | |||
cleaned_vec <- vapply(texts_vec, clean_mediawiki_text, FUN.VALUE = character(1)) | |||
corp <- corpus(texts_vec) | |||
# токенизация с базовой очисткой | |||
toks <- tokens( | |||
corp, | |||
remove_punct = TRUE, # убрать пунктуацию | |||
remove_symbols = TRUE, | |||
remove_numbers = TRUE | |||
) | |||
# приводим к нижнему регистру | |||
toks <- tokens_tolower(toks) | |||
# приводим к нижнему регистру | |||
toks <- tokens_tolower(toks) | |||
# стоп-слова (русский + английский, при необходимости) | |||
sw_ru <- stopwords("ru") # из пакета stopwords | |||
sw_en <- stopwords("en") | |||
toks <- tokens_remove(toks, c(sw_ru, sw_en)) | |||
# удалить совсем короткие токены (<=2 символа) | |||
toks <- tokens_keep(toks, min_nchar = 3) | |||
all_tokens <- unlist(toks) | |||
voyant_text <- paste(all_tokens, collapse = " ") | |||
outfile <- "digida_Histoty_for_voyant.txt" | |||
writeLines(voyant_text, outfile, useBytes = TRUE) | |||
</syntaxhighlight> | |||
; В результате мы получили '''digida_Histoty_for_voyant.txt''' и использовали его в комбинации с [[VOYANT Tools]] на странице [[:Обсуждение_категории:Работы_историков_ИГН]] | |||
== Voyant Tool== | |||
{{#widget:iframe | |||
|url=https://voyant-tools.org/tool/CollocatesGraph/?query=%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&query=%D1%80%D0%BE%D1%81%D1%81%D0%B8%D0%B8&query=%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%BA%D0%BE&query=%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F&query=%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5&query=%D0%B3%D0%BE%D0%B4%D0%B0&query=%D0%B8%D0%B3%D0%BD&query=%D0%B0%D0%B2%D1%82%D0%BE%D1%80&context=19&corpus=000039133f62c60828435423b97abd4e | |||
|width=600 | |||
|height=600}} | |||
Текущая версия от 20:46, 8 декабря 2025
| Описание | Мы хотим проанализировать тексты, которые хранятся в статья определенной категории поля цифровой дидактики. Есть 2 способа - экспорт статей и использование MediaWiki API |
|---|---|
| Область знаний | Лингвистика, Статистика |
| Область использования (ISTE) | |
| Возрастная категория | 16
|
| Поясняющее видео | |
| Близкие рецепту понятия | |
| Среды и средства для приготовления рецепта: | R, Semantic MediaWiki, MediaWiki API |
Использовать Экспорт статей
Воспользоваться Служебная:Экспорт и скачать все статьи из категории
Использовать R
library(httr2)
library(jsonlite)
library(tidyverse)
library(ggplot2)
library(quanteda)
library(stopwords)
getwd()
base_url <- "http://digida.mgpu.ru/api.php"
ua <- "digida-research-bot/0.1 (contact: patarakined@mgpu.ru)" ## Agent
############# Перечень статей в категории
get_category_pages <- function(category_name, limit = 500) {
params <- list(
action = "query",
list = "categorymembers",
cmtitle = paste0("Category:", category_name),
cmlimit = limit,
cmtype = "page",
format = "json"
)
response <- request(base_url) %>%
req_headers(
`User-Agent` = ua,
`Api-User-Agent` = ua
) %>%
req_url_query(!!!params) %>%
req_perform()
data <- resp_body_string(response) %>% fromJSON()
return(data$query$categorymembers) # оставить
}
#################
get_page_content <- function(page_title) {
params <- list(
action = "query",
titles = page_title,
prop = "revisions",
rvprop = "content",
format = "json"
)
response <- request(base_url) %>%
req_headers(
`User-Agent` = ua,
`Api-User-Agent` = ua
) %>%
req_url_query(!!!params) %>%
req_perform()
data <- resp_body_string(response) %>% fromJSON()
pages_data <- data$query$pages
page_info <- pages_data[[1]]
if (!is.null(page_info$revisions) && nrow(page_info$revisions) > 0) {
page_text <- page_info$revisions$`*`[1]
} else {
page_text <- NA
}
result <- list(
pageid = page_info$pageid,
title = page_info$title,
content = page_text
)
return(result)
}
################ Все тексты категории
get_all_category_content <- function(category_name, limit = 500, sleep_sec = 0.5) {
pages_df <- get_category_pages(category_name, limit = limit)
all_content <- vector("list", nrow(pages_df))
for (i in seq_len(nrow(pages_df))) {
page_title <- pages_df$title[i]
cat("Working with page", i, "from", nrow(pages_df), ":", page_title, "\n")
tryCatch({
content <- get_page_content(page_title)
all_content[[i]] <- content
}, error = function(e) {
cat("Mistake in", page_title, ":", e$message, "\n")
})
Sys.sleep(sleep_sec)
}
return(all_content) #
}
#################
data <- get_all_category_content("Работы историков ИГН", limit = 50)
- В результате получаем
> test_all <- get_all_category_content("Работы историков ИГН", limit = 50)
Working with page 1 from 40 : Адаптация европейских новшеств в XV-XVII в Русской повседневности
Working with page 2 from 40 : Афганская война в советской прессе (1979 - 1989)
Working with page 3 from 40 : Бургхард Кристоф Миних. Историография
Working with page 4 from 40 : Взаимодействие опричной и земской администраций
Очистка и подготовка текста
## Only text
texts_vec <- vapply(test_all, function(x) x$content, FUN.VALUE = character(1))
####
clean_mediawiki_text <- function(text) {
text <- gsub("\\{\\{[^}]*\\}\\}", "", text, perl = TRUE) # шаблоны {{...}}
text <- gsub("\\[\\[([^|\\]]*\\|)?([^\\]]+)\\]\\]", "\\2", text) # [[ссылка|текст]]
text <- gsub("\\[https?://[^ ]+ ([^\\]]+)\\]", "\\1", text) # [url текст]
text <- gsub("https?://\\S+", "", text) # голые URL
text <- gsub("'{2,}", "", text) # ''курсив''
text <- gsub("={2,}", " ", text) # заголовки ==
text <- gsub("<[^>]+>", " ", text) # HTML‑теги
text <- gsub("\\s+", " ", text)
trimws(text)
}
cleaned_vec <- vapply(texts_vec, clean_mediawiki_text, FUN.VALUE = character(1))
corp <- corpus(texts_vec)
# токенизация с базовой очисткой
toks <- tokens(
corp,
remove_punct = TRUE, # убрать пунктуацию
remove_symbols = TRUE,
remove_numbers = TRUE
)
# приводим к нижнему регистру
toks <- tokens_tolower(toks)
# приводим к нижнему регистру
toks <- tokens_tolower(toks)
# стоп-слова (русский + английский, при необходимости)
sw_ru <- stopwords("ru") # из пакета stopwords
sw_en <- stopwords("en")
toks <- tokens_remove(toks, c(sw_ru, sw_en))
# удалить совсем короткие токены (<=2 символа)
toks <- tokens_keep(toks, min_nchar = 3)
all_tokens <- unlist(toks)
voyant_text <- paste(all_tokens, collapse = " ")
outfile <- "digida_Histoty_for_voyant.txt"
writeLines(voyant_text, outfile, useBytes = TRUE)
- В результате мы получили digida_Histoty_for_voyant.txt и использовали его в комбинации с VOYANT Tools на странице Обсуждение_категории:Работы_историков_ИГН
Voyant Tool
