Birkaç satır kodla web’den nasıl veri kazınır?

Veri çağında yaşıyoruz. Önümüz arkamız sağımız solumuz veri. Hükümetler, uluslararası kuruluşlar, haber merkezleri verilerini kullanıma açıyor, bu veriler, araştırma, geliştirme, gazetecilik vb amaçları için kullanılıyor ve yeniden dağıtıma sokuluyor. Ama üretilen ve paylaşılan her veri indirilemiyor, indirilse dahi uygun formatta olmadığı için kullanılamıyor. Hâl böyle olunca web verisini kazımak tercih edilen en uygun seçeneklerden birisi olarak karşımıza çıkıyor. Veri gazeteciliği süreçlerinden biri olarak da kabul edilen veri kazıma işlemi, web tasarım dilini çözebilen, okuyabilen eklentiler (web scraper, data scraper) veya siteler (import.io) yardımıyla yapılabiliyor. Fakat bu işlemi üçüncü parti eklentilere veya sitelere ihtiyaç duymadan birkaç satır R koduyla yapmak mümkün. Peki nasıl? Bu yazıda R kullanarak uygulamalı olarak anlatacağım.

Anlatacağım yöntemle web sitelerindeki metin verileri (cümleler, paragraflar) de kazınabilir. Fakat bu pratikte web sayfalarına hapsedilmiş veri tablolarını kazıyacağız. Veri kazıma pratiği için iki ayrı web site adresinden yararlanacağız. İlki Yök Tez Merkezi İstatistikleri.

İkincisi Maçkolik Süper Lig Gol istatistikleri.

Her iki adresteki veriler de tablo formatında. O hâlde her biri için ayrı bir yöntem kullanarak, bu verileri kazıyalım.

1. Kullanılacak paketler ve ön hazırlık

Veri kazıma pratiğinde rvest paketini kullanacağız. Bunun yanı sıra tidyverse ve janitor paketleri de kazınan verinin düzenlenmesi ve görselleştirilmesi için işimize yarayacak.

library("rvest")
library("tidyverse")
library("janitor")

Paketleri çağırdıktan sonra yapmamız gereken kazıyacağımız web sayfalarının adresilerini R’a aktarmak. read_html fonksiyonu ile adresleri tanımlayarak bunu yapabiliriz. Bundan sonraki adımda tanımladığımız yok_link ve mackolik ögeleriyle işlemler yapacağız.

yok_link <- read_html("https://tez.yok.gov.tr/UlusalTezMerkezi/IstatistikiBilgiler?islem=3")
mackolik <- read_html("https://www.mackolik.com/puan-durumu/t%C3%BCrkiye-spor-toto-s%C3%BCper-lig/istatistik/482ofyysbdbeoxauk19yg7tdt")

2. Yök Tez Merkezi verilerini kazıyalım

Veri tablosu içeren html tabanlı tüm web sayfalarını rvest paketinin html_table() fonksiyonuyla kazıyabiliriz. Aşağıdaki işlemde YÖK Tez Merkezi verilerinin bulunduğu adresi html_table ile kazıdık. fill = TRUE argümanı sayesinde R, veri tablosunda eksik verileri NA, yani eksik veri olarak okuyor. Ayrıca, kazıdığımız verileri yok_tez isimli yeni bir ögeye kaydettik, çünkü kazıdığımız veri henüz istediğimiz tablo formatında değil. View(yok_tez) kodu ile verinin ne kadar dağınık olduğuna göz atabiliriz.

yok_tez <- yok_link %>% html_table(fill = TRUE)
View(yok_tez)

Kazıdığımız veri yok_tez şu an R’ın veri formatlarından biri olan liste formatında. Listedeki [[1]] ve [[2]] numaraları iki ayrı veri tablosundan oluştuğunu ifade ediyor. O hâlde her iki veri tablosuna göz atalım. Bakalım hangisi Yök tez verileri.

[[1]] ve [[2]] ye dikkat
yok_tez[[1]]
Evet acayip kirli bir veri seti…

Birinci veri tablosu işimize yaramayacak (junk) veriler içeriyor. İkinci tabloda ise konulara ve derecelere göre tez sayılarını görebiliyoruz. Tek veri tablosu ismi ve sütun isimleri değer olarak yer alıyor.

head(yok_tez[[2]])
X1
<chr>
X2
<chr>
X3
<chr>
X4
<chr>
X5
<chr>
X6
<chr>
1 Konulara göre Konulara göre Konulara göre Konulara göre Konulara göre Konulara göre
2 Konu Bakınız Ayrıca Bkz. Yüksek Lisans Doktora Tıpta Uzmanlık
3 Adli Tıp 734 248 374
4 Ağaç İşleri 551 91 0
5 Aile Hekimliği 53 11 1254
6 Aile Planlaması 71 17 18
yok_tablo <- as.data.frame(yok_tez[[2]])

Yukarıdaki işlemle veri tablosunu yok_tablo olarak kaydettik. Bu aşamadan sonra eğer isterseniz bu veriyi dışarı aktarıp Excel’de veya istediğiniz veri aracında temizleyerek kullanabilirsiniz. Dışarı aktarmak için aşağıdaki kodu kullanabilirsiniz.

write_csv(yok_tablo, "~/desktop/yok_tablo1.csv")

Bir diğer yol “R ekosisteminde dağınık veriler nasıl temizlenir?” yazımda ele aldığım gibi bu veri tablosunu temizleyebilir, derli hâle getirebiliriz. Fakat bu aşamada sütun isimlerini düzenlememiz yeterli olacaktır. Bunun için dplyr ve janitor paketlerini kullanacağız.

İlk olarak select komutuyla 1,4,5,10.’cu sütunları seçiyoruz. Sonrasında row_to_names fonksiyonu ile hangi satırın sütun ismi olarak seçeceksek row_number argümanına belirtiyoruz. Bu veri setinde istediğimiz isimler 2. satırda. Diğer tanımladığımız argümanlar ise sütun isimleri olarak belirlediğimiz satırdaki verileri (remove_row) ve üst satırlardaki değerleri (remove_rows_above) temizlememizi sağlıyor.

yok_derli <- yok_tablo %>% select(1,4,5,10) %>% row_to_names(row_number = 2, remove_row = TRUE, remove_rows_above = TRUE)
View(yok_derli)

Kazıma işlemini tamamladık hatta kazıdığımız veriyi biraz temizledik. Şimdiye kadar anlattığım işlem uzun görünüyor olabilir. Ama kullandığım tüm kodları birbirine bağladığımızda sadece 4 satırda YÖK verilerini kazıyabiliyoruz.

Evet yanlış okumadınız, 4 satır!

Bundan sonraki adımda metin verisi olarak algılanan Yüksek Lisans, Doktora ve Toplam değişkenleri sayı verisine dönüştürülerek analiz devam ettirilebilir. Şimde geçelim ikinci veri kazıma pratiğine.

3. Maçkolik süperlig gol istatistiklerini kazıyalım

İkinci pratikte Maçkolik süperlig gol istatistiklerini yine html_table ile çekebiliriz. Ama işimizi kolaylaştırmayalım. Gol istatistiklerini metin verisi olarak çekip R’da birleştirelim. Bazı durumlarda html_table() fonksiyonu düzgün çalışmayabiliyor.

İkinci adım ilkine göre biraz meşakkatli. Bu adımda tablolardaki veriyi çekmek için sırasıyla html_node ve html_text komutlarını kullanacağız. Çünkü kazıyacağımız veriler, html ve css node’ları içerisinde web sayfasında görüntüleniyor. Veri tablosuna karşılık gelen node’ları daha kolay bulabilmek için bir tarayıcı eklentisi kullanacağız: selector gadget. Bu eklenti tarayıcılardaki inspect seçeneğiyle aynı görevi görüyor. Farkı veri tablolarına karşılık gelen node’u zaman kaybetmeden elde ediyoruz.

Node: .p0c-competition-player-ranking__player-name

Mackolik.com’dan süper lig gol istatistiklerine açıyoruz ve eklenti ile oyuncu ismi üzerine tıklıyoruz. Sağ altta eklenti bize ilgili node’u verdi. Sonrasında node’u aşağıdaki olduğu gibi html_nodes() komutu içerisine ekleyebiliriz. Ve son olarak html_text() kullanarak node’daki verileri metin verisine dönüştürdük. Veriyi oyuncu ögesine kaydettik. Neyi kazıdığımızı görmek için R konsola oyuncu ögesini yazdırarak göz atabiliriz.

oyuncu <- mackolik %>% html_nodes(".p0c-competition-player-ranking__player-name") %>% html_text(trim = TRUE)
print(oyuncu)’da aynı değerleri verecektir

Bundan sonraki adımlarda takım ve gol_sayısı içinde gerekli node’ları seçtikten sonra aynı işlemi tekrarlayabiliriz. Bu arada trim = TRUE metin verisindeki gereksiz boş alanları kaldırıyor.

Her üç sütundaki değerleri kazıdık. Şimdi elimizdeki parçaları birleştirerek bir veri tablosu oluşturalım. Bu aşamada metin verisinden oluşan üç öğeyi tibble komutuyla tablo formatına dönüştürelim. tibbleas.data.frame komutunun modern hâli diyebiliriz. Ayrıca Yeni Zelanda İngilizcesinde tablo anlamına geliyor.

mackolik_derli <- tibble(oyuncu, takım, gol_sayisi)

head(mackolik_derli)
oyuncu
<chr>
takım
<chr>
gol_sayisi
<chr>
M. Diagne Galatasaray 23
H. Rodallega Trabzonspor 12
P. Cissé Alanyaspor 12
Burak Yılmaz Beşiktaş 11
H. Onyekuru Galatasaray 11
V. Muriqi Çaykur Rizespor 11
E. Višća İstanbul Başakşehir 10
Robinho İstanbul Başakşehir 10
A. Koné Sivasspor 9
D. Aleksić Yeni Malatyaspor 9

Veri tablosunu oluşturduk ama gol_sayisi metin verisi olarak algılanmış. as.numeric komutu ile gol_sayısı değişkenini sayı formatına dönüştürelim.

mackolik_derli$gol_sayisi <- as.numeric(mackolik_derli$gol_sayisi)

head(mackolik_derli)
oyuncu
<chr>
takım
<chr>
gol_sayisi
<dbl>
M. Diagne Galatasaray 23
H. Rodallega Trabzonspor 12
P. Cissé Alanyaspor 12
Burak Yılmaz Beşiktaş 11
H. Onyekuru Galatasaray 11
V. Muriqi Çaykur Rizespor 11
E. Višća İstanbul Başakşehir 10
Robinho İstanbul Başakşehir 10
A. Koné Sivasspor 9
D. Aleksić Yeni Malatyaspor 9
ggplot(mackolik_derli, aes(fct_reorder(oyuncu, gol_sayisi),gol_sayisi, fill = takım, label = gol_sayisi))+
  geom_col(show.legend = FALSE)+ 
  geom_text(check_overlap = TRUE, hjust = -0.2)+
  scale_fill_manual(values = palette)+
  labs(x="",y="",title = "Süper Ligin Golcüleri 2018/2019", subtitle ="Sadece 4 takımın oyuncuları için renk kullanılmıştır" ,caption = "@demirelsadettin / kaynak: maçkolik")+
  coord_flip()+theme_custom1()

Bu pratikte ve grafikte kullandığım detaylı kodlara buradan ulaşabilirsiniz. Ayrıca temizlenen veri setleri ve kullanılan tüm kodları GitHub’dan indirebilirsiniz.

Yazar hakkında

Sadettin Demirel

Araştırmacı & Eğitmen - Üsküdar Üniversitesi İletişim Fakültesi'nde Araştırmacı olarak çalışıyor. Veri Okuryazarlığı Derneği (VOYD) yönetim kurulu üyesi. Yeni Medya ve Araştırmacı Gazetecilik olmak üzere iki ayrı alanda yüksek lisans derecesine sahip. Eylül 2023'te İstanbul Üniversitesi Gazetecilik Bilim Dalında Doktora eğitimini tamamlayarak Doktor unvanı aldı. İlgilendiği konular arasında sosyal medya, metin madenciliği, duygu analizi, yeni medya, veri gazeteciliği, veri görselleştirme, ve programlama yer alıyor.