Web Scraping - Özel Parametreli Etiketler Sayfadan Çekilemiyor

Bayağı uğraştım, zihnim bana cevap veremeyince sormak istedim.

chaleno | Dart Package adresindeki dart paketini kullanmaya çalışıyorum, kullanımı dökümantasyonda görüldüğü gibi çok basit.

Scraping yapmaya çalıştığım kaynak ise Haftalık Yayın Akışı TRT Çocuk. Buranın kaynak kodlarına baktığımızda (img etiketleri için örnek verecem) şu iki tarz etiket yapısı ortaya çıkıyor;

<img data-v-0d7994c3 src="https://cdn-i.pr.trt.com.tr/trtcocuk//w150/q60/12298533.png" alt="İstiklal Marşı">
<img src="https://cdn-i.pr.trt.com.tr/trtcocuk/trtcocuk-logo.svg" alt="TRT Çocuk">

Söz konusu dökümantasyonda belirtilen parser.querySelectorAll('secici_adi'); metodu ile img etiketlerini liste olarak almaya çalışıyorum. Liste olarak aldığım img etiketleri sadece yukarıda verdiğim 2 örnekten alttaki gibi olanlar.

<img data-... ile başlayan hiç bir etiketi çekemiyorum. <img src="... biçimindeki etiketleri kolayca liste olarak alabilmekteyim. Bunun sebebi nedir? data-v-0d7994c3 parametresi sizce neden işi bozuyor?

Fonksiyonu results = parser.querySelectorAll('img'); şeklinde kullanıyorum, hata almıyorum. Sadece bahsettiğim data parametresine sahip etiketleri çekemiyorum.

Not: Siz söz konusu sitenin kaynak kodlarına baktığınızda bahsettiğim data’lı kısım değişir mi, o kısım dinamik mi bilmiyorum. Ben kaynak kodlara baktığımda data-v-0d7994c3 bilgisi yazıyordu.

Merhaba,

Daha önce hiç dart veya chaleno kullanmadım. Yayın akışı js ile dinamik bir şekilde oluşturuluyor. requests ve bs4 kütüphaneleri bu yüzden işe yaramadılar. Sonra selenium kütüphanesi ile denedim ve data-v-0d7994c3 ifadesine başvurmadan, aşağıdaki gibi bir algoritma izleyerek yayın akışını çektim.

import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options


url = "https://www.trtcocuk.net.tr/yayin-akisi/"
options = Options()
options.add_argument("-headless")
driver = webdriver.Firefox(options=options)
driver.get(url)
time.sleep(5)

streaming = []

elements = driver.find_elements(By.CLASS_NAME, "film-wrapper")
for element in elements:
    day = element.find_element(By.XPATH, "..").find_element(By.TAG_NAME, "h5").get_attribute("innerHTML").strip()
    for a in element.find_elements(By.TAG_NAME, "a"):
        img = a.find_element(By.XPATH, "./img")
        data_played = a.find_element(By.XPATH, "..").get_attribute("data-played")
        href = a.get_attribute("href")
        alt = img.get_attribute("alt")
        src = img.get_attribute("src")
        data_src = img.get_attribute("data-src")
        streaming.append({
            "day": day,
            "alt": alt,
            "href": href,
            "src": src,
            "data-src": data_src,
            "data-played": data_played
        })

for stream in streaming:
    print(stream)
{'day': '21 Ocak Pazar', 'alt': 'Dedektif Reptır', 'href': 'https://www.trtcocuk.net.tr/dedektif-reptir', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15439403.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15439403.png', 'data-played': '12:20'}
{'day': '21 Ocak Pazar', 'alt': 'Çizgi Film "SER-a"', 'href': 'https://www.trtcocuk.net.tr/yayin-akisi/', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/q60/epg.jpg', 'data-src': None, 'data-played': '12:35'}
{'day': '21 Ocak Pazar', 'alt': 'Emiray Çevre Müfettişi', 'href': 'https://www.trtcocuk.net.tr/emiray-cevre-mufettisi-2409', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15440370.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15440370.png', 'data-played': '12:45'}
{'day': '21 Ocak Pazar', 'alt': 'Sagun', 'href': 'https://www.trtcocuk.net.tr/sagun', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/14445072.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/14445072.png', 'data-played': '13:00'}
{'day': '21 Ocak Pazar', 'alt': 'Bulmaca Kulesi', 'href': 'https://www.trtcocuk.net.tr/bulmaca-kulesi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/9800922.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/9800922.png', 'data-played': '13:15'}
{'day': '21 Ocak Pazar', 'alt': 'Rafadan Tayfa', 'href': 'https://www.trtcocuk.net.tr/rafadan-tayfa', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/8021688.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/8021688.png', 'data-played': '13:30'}
{'day': '21 Ocak Pazar', 'alt': 'Z Takımı', 'href': 'https://www.trtcocuk.net.tr/z-takimi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/10165433.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/10165433.png', 'data-played': '14:00'}
{'day': '21 Ocak Pazar', 'alt': 'Ekip: SİBERAY', 'href': 'https://www.trtcocuk.net.tr/ekip-siberay', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/14943596.png', 'data-played': '14:25'}
{'day': '21 Ocak Pazar', 'alt': 'Çizgi Film "Babamın Gölgesi 1918"', 'href': 'https://www.trtcocuk.net.tr/yayin-akisi/', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/q60/epg.jpg', 'data-src': None, 'data-played': '14:35'}
{'day': '21 Ocak Pazar', 'alt': 'İbi Galaktik Serüven', 'href': 'https://www.trtcocuk.net.tr/ibi-galaktik-seruven', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/17114846.png', 'data-played': '14:50'}
{'day': '21 Ocak Pazar', 'alt': 'Variloto', 'href': 'https://www.trtcocuk.net.tr/variloto', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/13135609.png', 'data-played': '15:15'}
{'day': '21 Ocak Pazar', 'alt': 'Vikingler', 'href': 'https://www.trtcocuk.net.tr/vikingler', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7908249.png', 'data-played': '15:40'}
{'day': '21 Ocak Pazar', 'alt': 'Hazine Takipçileri', 'href': 'https://www.trtcocuk.net.tr/hazine-takipcileri', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15159362.png', 'data-played': '16:05'}
{'day': '21 Ocak Pazar', 'alt': 'Heidi', 'href': 'https://www.trtcocuk.net.tr/heidi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7907075.png', 'data-played': '16:30'}
{'day': '21 Ocak Pazar', 'alt': 'Nasreddin Hoca Zaman Yolcusu', 'href': 'https://www.trtcocuk.net.tr/nasreddin-hoca-zaman-yolcusu', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7712838.png', 'data-played': '16:55'}
{'day': '21 Ocak Pazar', 'alt': 'Rafadan Tayfa', 'href': 'https://www.trtcocuk.net.tr/rafadan-tayfa', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/8021688.png', 'data-played': '17:20'}
{'day': '21 Ocak Pazar', 'alt': 'Kehribar ile Boncuk', 'href': 'https://www.trtcocuk.net.tr/kehribar-ile-boncuk', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/14444455.png', 'data-played': '17:50'}
{'day': '21 Ocak Pazar', 'alt': 'Nils ve Uçan Kaz', 'href': 'https://www.trtcocuk.net.tr/nils-ve-ucan-kaz', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/11674640.png', 'data-played': '18:05'}
{'day': '21 Ocak Pazar', 'alt': 'Dennis ve Gnasher', 'href': 'https://www.trtcocuk.net.tr/dennis-ve-gnasher', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15439672.png', 'data-played': '18:30'}
{'day': '21 Ocak Pazar', 'alt': 'Z Takımı', 'href': 'https://www.trtcocuk.net.tr/z-takimi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/10165433.png', 'data-played': '18:55'}
{'day': '21 Ocak Pazar', 'alt': 'Kız Kulesi Masalları', 'href': 'https://www.trtcocuk.net.tr/kiz-kulesi-masallari', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/11021428.png', 'data-played': '19:20'}
{'day': '21 Ocak Pazar', 'alt': 'Taktik 6', 'href': 'https://www.trtcocuk.net.tr/taktik-6', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/15500173.png', 'data-played': '19:30'}
{'day': '21 Ocak Pazar', 'alt': 'Heidi', 'href': 'https://www.trtcocuk.net.tr/heidi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7907075.png', 'data-played': '19:45'}
{'day': '21 Ocak Pazar', 'alt': 'Kehribar ile Boncuk', 'href': 'https://www.trtcocuk.net.tr/kehribar-ile-boncuk', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/14444455.png', 'data-played': '20:10'}
{'day': '21 Ocak Pazar', 'alt': 'Rafadan Tayfa', 'href': 'https://www.trtcocuk.net.tr/rafadan-tayfa', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/8021688.png', 'data-played': '20:35'}
{'day': '21 Ocak Pazar', 'alt': 'Çizgi Film "Babamın Gölgesi 1915"', 'href': 'https://www.trtcocuk.net.tr/yayin-akisi/', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/q60/epg.jpg', 'data-src': None, 'data-played': '21:00'}
{'day': '21 Ocak Pazar', 'alt': 'Nasreddin Hoca Zaman Yolcusu', 'href': 'https://www.trtcocuk.net.tr/nasreddin-hoca-zaman-yolcusu', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7712838.png', 'data-played': '21:25'}
{'day': '21 Ocak Pazar', 'alt': 'Ege ile Gaga', 'href': 'https://www.trtcocuk.net.tr/ege-ile-gaga', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7713637.png', 'data-played': '00:05'}
{'day': '21 Ocak Pazar', 'alt': 'Bulmaca Kulesi', 'href': 'https://www.trtcocuk.net.tr/bulmaca-kulesi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/9800922.png', 'data-played': '00:30'}
{'day': '21 Ocak Pazar', 'alt': 'Erdem', 'href': 'https://www.trtcocuk.net.tr/erdem', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7713036.png', 'data-played': '00:55'}
{'day': '21 Ocak Pazar', 'alt': "Aslan'ın Deney Odası", 'href': 'https://www.trtcocuk.net.tr/aslanin-deney-odasi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/17182183.png', 'data-played': '01:20'}
{'day': '21 Ocak Pazar', 'alt': 'Doru', 'href': 'https://www.trtcocuk.net.tr/doru', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7712649.png', 'data-played': '01:45'}
{'day': '21 Ocak Pazar', 'alt': 'Elif ve Arkadaşları', 'href': 'https://www.trtcocuk.net.tr/elif-ve-arkadaslari', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7703886.png', 'data-played': '02:10'}
{'day': '21 Ocak Pazar', 'alt': 'Maysa ve Bulut', 'href': 'https://www.trtcocuk.net.tr/maysa-ve-bulut', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7712477.png', 'data-played': '02:35'}
{'day': '21 Ocak Pazar', 'alt': 'Nasreddin Hoca Zaman Yolcusu', 'href': 'https://www.trtcocuk.net.tr/nasreddin-hoca-zaman-yolcusu', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7712838.png', 'data-played': '03:00'}
{'day': '21 Ocak Pazar', 'alt': 'Kare', 'href': 'https://www.trtcocuk.net.tr/kare', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7710963.png', 'data-played': '03:25'}
{'day': '21 Ocak Pazar', 'alt': 'Kaptan Pengu ve Arkadaşları', 'href': 'https://www.trtcocuk.net.tr/kaptan-pengu-ve-arkadaslari', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/9240911.png', 'data-played': '03:50'}
{'day': '21 Ocak Pazar', 'alt': 'İbi Galaktik Serüven', 'href': 'https://www.trtcocuk.net.tr/ibi-galaktik-seruven', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/17114846.png', 'data-played': '04:15'}
{'day': '21 Ocak Pazar', 'alt': 'İstiklal Marşı', 'href': 'https://www.trtcocuk.net.tr/istiklal-marsi', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/12298662.png', 'data-played': '04:27'}
{'day': '21 Ocak Pazar', 'alt': 'Ciciki', 'href': 'https://www.trtcocuk.net.tr/ciciki', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7703841.png', 'data-played': '04:30'}
{'day': '21 Ocak Pazar', 'alt': 'Ege ile Gaga', 'href': 'https://www.trtcocuk.net.tr/ege-ile-gaga', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7713637.png', 'data-played': '04:55'}
{'day': '21 Ocak Pazar', 'alt': 'Kare', 'href': 'https://www.trtcocuk.net.tr/kare', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7710963.png', 'data-played': '05:20'}
{'day': '21 Ocak Pazar', 'alt': 'Elif ve Arkadaşları', 'href': 'https://www.trtcocuk.net.tr/elif-ve-arkadaslari', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7703886.png', 'data-played': '05:40'}
{'day': '21 Ocak Pazar', 'alt': 'Akıllı Tavşan Momo', 'href': 'https://www.trtcocuk.net.tr/akilli-tavsan-momo', 'src': 'https://cdn-i.pr.trt.com.tr/trtcocuk/EPG_Cover_Placeholder.png', 'data-src': 'https://cdn-i.pr.trt.com.tr/trtcocuk//w480/h134/q60/7707734.png', 'data-played': '06:05'}
[...]
2 Beğeni

Uğraşmışsınız teşekkürler, tüm html kaynağını string olarak alıp string metotlarıyla içinden dilediğimi ayıklamaya çalışayım. Bakayım ne sonuç alacam.

HTML içeriğinin bir kısmı, özellikle sizin almaya çalıştığınız kısım olan yayın akışı kısmı js kodları ile oluşturuluyor. Bu yüzden sayfanın kaynak kodlarını requests ile çektiğimiz zaman içinde yayın akışını göremiyoruz. Ancak browser’ı simüle edebilen bir kütüphane ile web scraping yaparsanız, elementlere daha rahat bir şekilde ulaşabilirsiniz. Elementlerin DOM ilişkisine göre de istediğiniz elementlerin ve bunların niteliklerinin bilgilerini alabilirsiniz. str metodlarını string metodlarına ihtiyaç duyduğunuzda başvurursunuz, ama istediğiniz DOM elementlerine ulaşmak için bunun için tasarlanmış bir kütüphane kullanmak işinizi ziyadesiyle kolaylaştıracaktır.

1 Beğeni

Hocam https://www.trthaber.com/yayin-akisi/trt-cocuk/21-01-2024 bağlantısından çekebildim. Bağlantıdaki adres kısmının sonundaki tarih kısmını değiştirerek kolaylıkla yayın akışı alınabiliyor. TRT’nin web ekibine kanalların yayın akışlarının xml ya da kullanışlı farklı bir formatla sunulması hususunda ayrıca mail attım. Dikkate alırlar mı bilmem.

Dart chaleno paketi ile bağlantıda dilediğim kısımları aşağıdaki kodla alabiliyorum.

var timeResults = parser.querySelectorAll('div[class="time"]');
var nameResults = parser.querySelectorAll('div[class="program-name"]');

querySelectorAll methodundan gelen Result nesnelerinden oluşan listenin her bir elemanı, <div>..</div> gibi class adına göre filtrelediğiniz elementler oluyor. Result nesnesi ile gelen bir html elementinin text, src, href, height vs. değerlerine kolaylıkla ulaşılabiliyor.

Şimdilik bu işimi gördü. Sen ilk paylaştığım sayfanın js ile dinamik değiştiğini belirtmeseydin uğraşmaya devam edecektim. DOM’dan bahsettiğin için ayrıca teşekkürler, araştırıp ne olduğuna baktım bir şeyler daha öğrenmiş oldum.

1 Beğeni