-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscrap-stack.Rmd
More file actions
258 lines (173 loc) · 9.43 KB
/
scrap-stack.Rmd
File metadata and controls
258 lines (173 loc) · 9.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
---
title: "R Notebook"
output:
html_document:
keep_md: yes
---
# Scraping a stackoverflow
Hace poco me encontraba platicando con un amigo, se encuentra muy interesado por aprender a programar, y la pregunta natural es ¿Qué lenguaje debería de aprender? mi primer respuesta fue que en la ciencia de datos los mas demandados son Python y R, y era obvia para mi esta respuesta ya que al ser mi formación como economista mi primer puerta de entrada a la programación fue por R, sin embargo él no hablaba para algo especifico como la ciencia de datos.
En este [articulo](http://varianceexplained.org/r/year_data_scientist/) el autor analiza las preguntas mas populares de [stackoverflow](https://stackoverflow.com/tags) pagina que todos conocemos y si aun no lo haces faltara poco para que lo hagas.
De tal manera que este será un tutorial para entender como funciona el [web scraping](https://es.wikipedia.org/wiki/Web_scraping) y observar que lenguajes son mas populares por el numero de preguntas en [stackoverflow](https://stackoverflow.com/tags) y ver de que manera se relacionan entre si los tags de preguntas.
## Hora de ensuciarse las manos!
Estos son los paquete necesitaremos de igual manera usaremos un plugin de [google chrome](https://chrome.google.com/webstore/detail/selectorgadget/mhjhnkcfbdhnjickkkdbjoemdmbfginb)(también disponible para firefox)
```{r message=FALSE, warning=FALSE}
library(tidyverse)
library(rvest)
library(dplyr)
library(tidygraph)
```
Visitemos la url [https://stackoverflow.com/tags?page=1&tab=popular](https://stackoverflow.com/tags?page=1&tab=popular) como podemos ver en esta url tiene un tag "page=1" el cual nos sirve para identificar la pagina en la que estamos y el tag "tab=popular" lo que nos indica que está ordenado del mas popular al menos popular para nuestro ejemplo solo tomaremos los 36 primeros ranks(cada pagina contiene 36 tags)

```{r}
#guardamos la URL
url <- 'https://stackoverflow.com/tags?page=1&tab=popular'
```
SelectorGadget nos ayuda a encontrar el nombre del nodo que nos interesa para la extracción de la información, como podemos ver en la siguiente imagen, después de seleccionar el plugin es posible seleccionar el elemento que nos interesa para ver el nombre del nodo, primero veamos el nombre del nodo que indica el tag para después elegir el nodo que indica el número de preguntas para ese tag


Como vemos los nodos que nos importan son **".post-tag"** y **".item-multiplier-count"**
```{r}
# nombre de los nodos en el archivo html que nos importan
node_name <- c('.post-tag','.item-multiplier-count')
```
Creamos la función **info_extract** la cual se encargara de extraer y convertir en un data frame la información de los nodos que busquemos
```{r}
info_extract <- function(url,names,node_name) {
#leemos la url
webpage <- read_html(url)
# ciclo for para cada nodo
for (i in 1:length(node_name)) {
#extraemos la información del nodo
html <- html_nodes(webpage,node_name[i])
#lo convertimos en texto
name <- html_text(html)
if(i==1){
result <- name
}else {
result <- cbind(result,name)
}
}
#lo convertimos en un dataframe
result <- data.frame(result,stringsAsFactors = F)
names(result) <- names
result
}
```
Crearemos el data frame
```{r}
# nombre de las columnas que crearemos
names <- c("name_topic","number_question")
extract <- info_extract(url,names,node_name)
head(extract)
```
Creamos la función **related_tags** para obtener un data.frame con los tags que mas se relacionan a los tags populares
```{r}
related_tags <- function(lenguaje) {
# creamos esta bandera para identificar que es el primer ciclo for
flag_first <- T
for (i in lenguaje) {
cat("----------------------\n",
"Extrayendo: ",i,"\n",
"======================\n")
#en caso de que el nombre sea "c#" la url de stackoverflow la convierte en el tag
# "c%223" lo mismo sucede con "c++" lo vuelve "c%2b%2b" por lo tanto haremos lo mismo
i <- ifelse(i=="c#","c%23",i)
i <- ifelse(i=="c++","c%2b%2b",i)
# creamos la url con el nombre del tag
url <- paste0('https://stackoverflow.com/questions/tagged/',i)
webpage <- read_html(url)
# buscamos el nombre de los lenguajes que mas se taggean con los tags populares
rank_data_html <- html_nodes(webpage,'.js-gps-related-tags')
character<- as.character(rank_data_html)
strsplit <- strsplit(character," ")%>% unlist()
# buscamos cuantas veces el tag secundario se asocia con el tag popular
count_html <- html_nodes(webpage,'.item-multiplier-count')
count <- html_text(count_html)
#despues de separar buscamos en que filas se encuentran los tag que nos importan
grep <- grep(paste0("/questions/tagged/",i),strsplit, value = T)
grep <- gsub(paste0("href=\"/questions/tagged/",i,"+"),"",grep)
grep <- gsub("\"","",grep)
second_tag <- substr(grep,2,nchar(grep))
popular <- rep(i,length(substr))
cbind <- cbind(popular,second_tag) %>% cbind(count)
if(flag_first) {
related_tags <- cbind
flag_first <- F
}else {related_tags <- rbind(related_tags,cbind)}
}
related_tags <- related_tags %>%
data.frame(stringsAsFactors = F)
related_tags$count <- related_tags$count %>%
as.numeric()
related_tags
}
```
Básicamente lo que haremos es visitar uno a uno el URL correspondiente a cada tag popular por ejemplo la URL del tag "Android" se compone de la siguiente manera _https://stackoverflow.com/questions/tagged/android_ como vemos después de _tagged/_ se encuentra **Android** indicando la URL de interés.
En esta dirección los nodos que nos importan son **".item-multiplier-count"** y **".js-gps-related-tags"**, nos indican cuantas veces el tag secundario se ah tageado junto al tag popular, después creamos un data frame con la información anterior para cada uno de los tags populares, recorriendo uno a uno los 36 tags populares.

```{r}
tabla_result <- related_tags(extract$name_topic)
```
```{r}
tabla_result %>% head()
```
Ordenaremos de forma descendiente el conteo donde aparecen juntos el tag popular con el secundario y nos quedaremos con las primeras 150 filas de manera que sea mas cómodo el manejo de los datos
```{r}
muestra <- tabla_result %>%
arrange(desc(count)) %>%
head(150)
```
```{r}
library(htmlwidgets)
library(visNetwork)
library(tidygraph)
sources <- tabla_result %>%
distinct(popular) %>%
rename(label = popular)
destinations <- muestra %>%
distinct(second_tag) %>%
rename(label = second_tag)
nodes <- full_join(sources, destinations, by = "label")
#nodes
nodes <- nodes %>% rowid_to_column("id")
#nodes
per_route <- muestra %>%
group_by(popular, second_tag) %>%
summarise(weight = sum(count)) %>%
ungroup() %>% arrange(desc(popular )) %>%
arrange(desc(weight ))
per_route
edges <- per_route %>%
left_join(nodes, by = c("popular" = "label")) %>%
rename(from = id)
edges <- edges %>%
left_join(nodes, by = c("second_tag" = "label")) %>%
rename(to = id)
edges <- select(edges, from, to, weight)
#edges
edges <- mutate(edges, width = weight/(max(weight)-min(weight))*10 )
visNetwork <- visNetwork(nodes, edges) %>%
visIgraphLayout(layout = "layout_with_fr") %>%
visEdges(arrows = "middle")
htmlwidgets::saveWidget(visNetwork,"visNetwork.html")
```
Después de ver las conexiones que existen entre los diferentes tags, vemos que **JavaScript**, **JQuery**, **HTML** y **PHP** son tecnologías de las mas populares y que se encuentran relacionadas con muchas tecnologías

También podemos ver como se agrupan las tecnologías como Android y java

Y hablando de ciencia de datos vemos como se relacionan Python con otras tecnologías, y al ser un lenguaje multipropósito es normal que la ciencia de datos no sea lo único a su alrededor, y mucho menos lo mas importante.

Y bueno ¿a todo esto donde se encuentra R?

ok... ok.... quizás no se encuentra relacionado a muchas tecnologías (al menos no en el volumen necesario para destacar en este análisis) como los tags anteriores, pero esto no significa que no sea popular ya que se encuentra dentro de los 36 mas tageados
# Conclusiones
Sin duda la tecnología (en este caso el lenguaje) mas popular en stackoverflow es JavaScript lo cual lo reafirmamos con la gran cantidad de tecnologías que se asocian a esta.
El web scraping es realmente divertido, ya que puedes obtener información que esta ahí pero no a simple vista, basta adentrarse para encontrarla, estructurarla y analizarla.
### Acontinuacion puedes analizar por ti mismo la red creada, hacer zoom, mover los nodos etc.
```{r}
htmltools::includeHTML("./visNetwork.html")
```
### Referencias
http://varianceexplained.org/r/year_data_scientist/
https://www.jessesadler.com/post/network-analysis-with-r/
https://www.analyticsvidhya.com/blog/2017/03/beginners-guide-on-web-scraping-in-r-using-rvest-with-hands-on-knowledge/