DATA SCRAPING NEDİR? BEAUTIFULSOUP MODÜLÜ NEDİR? JSON FORMATINDA WEB KAZIMA ÖRNEĞİ

KOGLAK
4 min readDec 28, 2020

Merhaba, bu yazımda gittigidiyor sitesindeki çok okunan listesindeki kitapları adım adım dataframe aktaracağım, yani web scraping yapacağım.

Web Scrapping yani veri kazıma işlemi, web sitelerindeki datayı, veri analizine uygun bir hale getirmek için kullanılır. Bu sitelerdeki datalar çekilerek, tablo formatına/excel’e ya da dataframe’e aktarılır.

Bunun için en çok kullanılan yöntem ise BeautifulSoup’tur. Siteyi döküman okuyarak kendinizi geliştirmek için incelemenizi öneririm.

Dediğim gibi ben Gittigidiyor sitesindeki bu sayfada bulunan kitapların adlarını, fiyatlarını, kategorilerini ve firmalarını bir tabloya dönüştüreceğim. Python ile bu işlem oldukça kısa sürüyor. Ancak sitelerdeki veriler html formatının içine gömülü olduğu için eğer aşına değilseniz, html etiketlerine kısaca göz gezdirmenizi öneririm. Div, span, a, body gibi etiketlerin ne olduğu hakkında bilgi sahibi olmanız hem adımları anlamanızı kolaylaştırır hem de web siteleri hakkında bir ön bilgi sahibi olabilirsiniz.

Son olarak web sitelerinde genelde bilgiler JSON formatında yer almaktadır. Biz de bu örnekte JSON formatındaki verileri çekeceğiz. Dolayısıyla yine bu format hakkında bilgi sahibi değilseniz, kısa bir araştırma sizin faydanıza olacaktır.

Hadi başlayalım.

İlk önce kütüphaneleri import edelim.

import requests
from bs4 import BeautifulSoup
import re
import pandas as pd

İlk önce sitemize az önce yüklediğimiz requests kütüphanesi sayesinde istekte bulunuruz. Siz başka bir örnek üzerinden yapacaksınız, datayı çekeceğiniz sitenin linkini aşağıdaki gibi yapıştırmanız gereklidir.

r = requests.get('https://www.gittigidiyor.com/arama/?cmpg=6525')

r yazıp enterlarsanız Response[200] görmeniz gerekir. Bunun anlamı requests.get isteği almıştır.

Aynı şekilde r.url yazarsanız ise isteği aldığınız sitenin adresini görüntüleyebilirsiniz.

r.text yazarsanız, sitenin html kodunu görüntüleyebilirsiniz!

BeautifulSoup, HTML veya XML dosyalarını işlemek için oluşturulmuş güçlü ve hızlı bir kütüphanedir. Adını Alice harikalar diyarında içerisindeki bir kaplumbağanın söylediği hikayeden alır. BeautifulSoup ile request ettiğimiz r objesini xml formatında çekmiş oluruz. lxml yerine aşağıdaki parametrelerde kullanılabilir.

  • html.parser
  • lxml-xml
  • html5lib
soup = BeautifulSoup(r.content,"lxml")

Şimdi bir test yapalım. Sitenin title’ını bulmasını istediğimizde aşağıdaki sonuca ulaşıyorum. Yani soup objesine xml formatını aktarabilmişim!

soup parametresini yazdırdığımda sayfanın bütün html formatını görebiliyorum. Ancak oldukça uzun bir çıktı. Bunun için bu çıktıyı ben kopyaladım ve bir not defterine yapıştırdım. Şimdi bu çıktıyı inceleyip, kitap adı, yazarı vs. bilgilerinin hangi etiketler altında olduğunu bulmaya çalışacağım. Burası biraz çetrefilli, kodu iyice incelemelisiniz ve HTML etiketlerinden, parents-children özelliğinden haberdar olmanız gerekiyor.

Ben kodu incelediğimde aradığım bilgilerin <script type= “application/ld+json”> </script> arasında olduğunu fark ettim. Bu aralıktaki kodu aşağıdaki gibi res objesine aktardım.

res=soup.find("script",type="application/ld+json")

res yazıp enter dediğimde yukarıda belirttiğim etiket arasındaki bilgiler aşağıdaki gibi geliyor. Resim net değil ama kitap isimleri vs. bu aralıkta. Ve bilgiler JSON formatında geliyor. İnternette formatı aratarak bir genel bilgi elde edebilirsiniz. Kısaca JSON formatı(JavaScript Object Notation — JavaScript Nesne Notasyonu) anahtar ve değerlerden oluşur. Aşağıdaki gibi ifade edilir.

{“sehir”:”Istanbul”, “ulke”:”Turkiye”}

Şimdi bir json_object yarattık.

json_object = json.loads(res.contents[0])

Bizim elimizdeki veride aşağıdaki gibi bir hiyerarşi var. Aslında kitap isimleri ve bilgileri mainEntity->offers->itemOffered altında.

<script type="application/ld+json">
{"@context":"https://schema.org","@type":"WebPage",
"name":null,
"description":null,
"url":"https://www.gittigidiyor.com/arama/",
"inLanguage":"tr-TR","breadcrumb":[],
"mainEntity":{
"@type":"WebPageElement",
"offers":{
"@type":"Offer",
"itemOffered":[{
"@type":"Product",
"name":"Madalyonun İçi Dr. Gülseren Budayıcıoğlu",
"url":"https://www.gittigidiyor.com/kitap-dergi/madalyonun-ici-dr-gulseren-budayicioglu_pdp_636089325",
"image":[],
"offers":{
"itemCondition":"https://schema.org/NewCondition",
"image":"https://mcdn01.gittigidiyor.net/63608/tn50/636089325_tn50_0.jpg",
"availability":"https://schema.org/InStock",
"category":"Roman","price":"26,50",
"priceCurrency":"TRY",
"areaServed":"TR",
"seller":{
"@type":"Organization",
"name":"ttunakitap"},"@type":"Offer"}
},
{"@type":"Product",
"name":"Her Güne Bir Soru: 5 Yıllık Günlük",
"url":"https://www.gittigidiyor.com/kitap-dergi/her-gune-bir-soru-5-yillik-gunluk

Böylece ben de o aralığa ulaşmak için aşağıdaki gibi bir satır yazıyorum ve bu satırları products objesine atıyorum. Artık products içerisinde itemOffered elementinin arasında olan veriler var!

products=json_object['mainEntity']['offers']['itemOffered']

Şimdi df_list isimli boş bir liste oluşturdum. Ardından products altındaki her elemente for döngüsü ile ulaştım. product[‘name’] ile dosya içerisindeki her name elementini aldım. Aynı şekilde price, currency, category, seller ve url içinde aynı adımları izledim. Bunların hepsini df_list’e append ettim.

Böylece sayfadaki bütün kitap bilgilerini liste içerisine aktarmış oldum.

df_list=[]for product in products:
name=product['name']
price=product['offers']['price']
currency=product['offers']['priceCurrency']
category=product['offers']['category']
seller=product['offers']['seller']['name']
url=product['url']
df_list.append({'name':name, 'price':price,'currency':currency, 'category': category,'seller':seller,'url':url})

Artık listemiz hazır. Bunları dataframe df’e aşağıdaki gibi aktardım.

df=pd.DataFrame(df_list,columns=['name','price','currency','category','seller','url'])

df’i yazdırdığımda ise tablom aşağıdaki gibi görünmekte. Sayfada bulunan 47 adet kitabı dataframe’e aktardım.

Bu işlemi sadece bir sayfa için yaptım ancak birden fazla sayfa var. Aynı işlemi for döngüsünde bu sayfaların urlleri içinde yapabilirsiniz. Url’lerdeki tek fark &sd=2 şeklinde sayfa numarasının sona eklenmesi.

https://www.gittigidiyor.com/arama/?cmpg=6525&sf=2

Artık bu dataları analiz etmeye hazırız! Bu faz data wrangling gather adımı olarak geçmektedir. Ve önemli bir adımdır.

Projelerinizde kolay gelsin :)

--

--