Python ile Selenium ve BeautifulSoup Hatası

Arkadaşlar merhaba.
Bir kitap sitesinden verileri çekmek istiyorum seleniumdan sonra BeautifulSoup denemek istedim
selenium ile sayfa kaynağını alıp yoluma devam etmek istedim
ama bir türlü olmuyor yardım eder misiniz?

from bs4 import BeautifulSoup
import requests
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys

driver_path = "C:/chromedriver.exe"
browser = webdriver.Chrome(driver_path)

#bkm kitap

kitap_adi = input("Kitap adını giriniz: ")
yayin_evi = input("Yayınevini giriniz: ")

browser.get("https://www.google.com/")

bkm_kitap_veri_girisi = browser.find_element_by_css_selector(".gLFyf.gsfi") # noktaları kendım koydum dıkkat et
bkm_kitap_veri_girisi.send_keys(kitap_adi+ " " +yayin_evi+" "+"site:bkmkitap.com")
time.sleep(2)

bkm_kitap_veri_girisi.send_keys(Keys.ENTER)
time.sleep(2)

bkm_kitap_veri_tiklama = browser.find_element_by_xpath("//*[@id='rso']/div[1]/div/div/div[1]/div/a/h3")
time.sleep(2)
bkm_kitap_veri_tiklama.click()

# BS4 İLE YAPIYORUZ ARTIK

bkm_kitap_sayfa = browser.page_source
bkm_kitap_soup = BeautifulSoup(bkm_kitap_sayfa, "lxml")

bkm_kitap_bilgiler = bkm_kitap_soup.find("div",attrs={"id","productInfo"})
print(bkm_kitap_bilgiler)


Hata olarak ise None değerini alıyorum boş dönüyor sanırım neden böyle oluyor nerede hata yapıyorum arkadaşlar?

Selenium hakknda bilgim kısıtlı ama bunu requests ilede halledebilirsiniz gibi görünüyo örnek olsun diye fiyat ve isimlerini aldığım basit bir kod yazdım belki size yardımcı olabilir

import requests
import json
from bs4 import BeautifulSoup

url="https://www.bkmkitap.com/edebiyat-kitaplari"
res=requests.post(url)
kk1 = BeautifulSoup(res.content,"lxml")
xv1 =kk1.find_all('div',attrs={'class':'fl col-12 catalogWrapper'})
xv1=BeautifulSoup(str(xv1),"lxml")
xv2=xv1.find_all("script")
for i in xv2:
    dc=(json.loads(i.text[30:-4].replace('\\',"")))
    isim=(dc["url"])
    fiyat=(dc["sale_price"])
    print(f"Kitap: {isim}   Fiyat: {fiyat}")
    

ÇIKTI

Kitap: gece-yarisi-kutuphanesi   Fiyat: 38.53
Kitap: hayvan-ciftligi-513296   Fiyat: 9.98
Kitap: atespare-1-hediyeli-ozel-kutu   Fiyat: 79.98
Kitap: kaplanin-sirtinda   Fiyat: 55.25
Kitap: 1984-515278   Fiyat: 19.95
Kitap: sokak-nobetcileri-2-ciltli-644231   Fiyat: 69.61
Kitap: cati-kati-755977   Fiyat: 58.29
Kitap: banana-fish-1   Fiyat: 56.16
Kitap: bizimle-basladi-bizimle-bitti   Fiyat: 54.95
Kitap: yaban-cicegi-755708   Fiyat: 45
Kitap: bir-yaz-boyunca   Fiyat: 50.25
Kitap: var-misin-514641   Fiyat: 45.51
Kitap: bilinmeyen-bir-kadinin-mektubu-739589   Fiyat: 8.68

Ben burda kolay olsun diye scriptden aldım ama siz alıcağınız bilgiye göre html kodlarını incelersiniz

Edit:
Name değeri yerine urlleri aldım bazı isimler oyüzden doğru çıkmamış

hocam elinize sağlık denedım oldu
fakat ben kullanıcının girmek istediği kitap ve yayın evine bağlı olarak bkmkitap,kitap yurdundaki ucuz kitapları getirmek istedim

page.source kısmında sorun yaşadım sayfanın kaynağını alamadım bir türlü

Aynı yöntemi kullanabilirsiniz sadece çekmek istediğiniz veriye göre değişiklik yapmanız gerekiyo temelde hepsi aynı mantıkla işliyo kodları biraz inceleyin çekmek istediğiniz sayfanında kaynak kodlarını inceleyin olayı daha iyi anlarsınız

soruyu soralı epey olmuş fakat selenium bu tip işlerde yavaş kalabilir. genelde web scraping yaparken doğru olan şey daima arkada çalışan api varsa bunları kontrol etmektir. örneğin bkmkitapta olağanüstü bir gece sorgusu yaptığımızda https://bkm.wawlabs.com/avx_wse?cm=conv&f=True&d=True&q=ola%C4%9Fan%C3%BCst%C3%BC%20bir%20gece linkine istek gider ve dönen cevap sitede gösterilir. örnek olması açısından senin için şöyle bir script yazdım. inceleyip anlamadığın yer olursa çekinmeden yazabilirsin.

import requests
import json

class BkmKitap:
    def __init__(self, book_title):
        self.book_title = book_title
    
    def get_books(self):
        data = {
            "cm":"conv",
            "f":True,
            "d":True,
            "q":self.book_title
        }
        r = requests.get("https://bkm.wawlabs.com/avx_wse", params=data)
        return r.text
    
    def parse_books(self):
        books = self.get_books()
        jsonify = json.loads(books)
        results = []
        for book in jsonify["res"]:
            result = {}
            result["book_title"] = book["Title_txt_tr"]
            result["book_author"] = book["Brand_txt_tr"]
            result["book_price"] = book["Price_txt_tr"]
            result["book_sale_price"] = book["Sale_Price_txt_tr"]
            result["book_publisher"] = book["Publisher"]
            result["book_rating"] = book["Rating"]
            results.append(result)
        return results

if __name__ == "__main__":
    book_input = input("Kitap adı giriniz: ")
    data = BkmKitap(book_input).parse_books()
    print("--SORGU SONUCU GELEN KİTAP BİLGİLERİ--")
    for i in data:
        print(f"Kitap Adı: {i['book_title']}\nKitap Yazarı: {i['book_author']}\nKitap Fiyatı: {i['book_price']}\nKitap İndirimli Fiyatı: {i['book_sale_price']}")
        print(f"Yayımcı: {i['book_publisher']}\nKitap Puanı: {i['book_rating']}\n")

1 Beğeni

Hocam biraz acemice olcak kusura bakmayın

Selenium anladım
Request ve bs4 anladım
Apiyi anlayamıyorum

Apiyi anladım ama requests varken apiye gerek var mı?
Apiyi hangi ihtiyaclarda kullanırız?

Kodun cogunu anladım ama daha iyi oturmasi icin aciklama yazar mısın?

api çok daha hızlı sonuç getirir. bir web sayfasını yüklerken onlarca css, font, image, javascript indirirsin ama api’da sadece istediğin şeyi alabilirsin. ayrıca api değişmediği sürece bir sorun çıkmaz. bs4 ile aldığında bazen html tagleri ya da class isimleri vs. sık sık değişebiliyor ve bozabiliyor scraper’ı.

Tesekkur ederim hocam
Birde bir sorum olacak
Siz pyqt de progressbar kullandiniz mi?

maalesef hiç pyqt ile bir işim olmadı üzgünüm :frowning:

kodu açıklama kısmına gelirsek. seve seve anlatırım tabii.

class BkmKitap:
    def __init__(self, book_title):
        self.book_title = book_title

init methoduna book_title veriyoruz çünkü sorguyu buna göre atacağız. sanırım yayınevi vs. gibi şeyler için de çalışıyor bu ama emin değilim denemedim.

def get_books(self):
        data = {
            "cm":"conv",
            "f":True,
            "d":True,
            "q":self.book_title
        }
        r = requests.get("https://bkm.wawlabs.com/avx_wse", params=data)
        return r.text

asıl işimizi bu method yapıyor. sanırım bunu init methodunun içine koymak daha mantıklı bilemiyorum. çünkü response’un içerisindeki farklı bilgilerle farklı işler yapan methodlar yazmak gerektiğinde sürekli get_books methodunu çağırıp sürekli istek atmak mantıklı değil. bir kere istek atıp dönen cevabın içeriğiyle oynamak daha mantıklı göründü şu an. neden öyle yazmışım anlamak güç :smiley:

def parse_books(self):
        books = self.get_books()
        jsonify = json.loads(books)
        results = []
        for book in jsonify["res"]:
            result = {}
            result["book_title"] = book["Title_txt_tr"]
            result["book_author"] = book["Brand_txt_tr"]
            result["book_price"] = book["Price_txt_tr"]
            result["book_sale_price"] = book["Sale_Price_txt_tr"]
            result["book_publisher"] = book["Publisher"]
            result["book_rating"] = book["Rating"]
            results.append(result)
        return results

bu kısımda da parse ediyorum dönen sonucu. aşağı yukarı ne yaptığımı anlamışsındır zaten.

if __name__ == "__main__":
    book_input = input("Kitap adı giriniz: ")
    data = BkmKitap(book_input).parse_books()
    print("--SORGU SONUCU GELEN KİTAP BİLGİLERİ--")
    for i in data:
        print(f"Kitap Adı: {i['book_title']}\nKitap Yazarı: {i['book_author']}\nKitap Fiyatı: {i['book_price']}\nKitap İndirimli Fiyatı: {i['book_sale_price']}")
        print(f"Yayımcı: {i['book_publisher']}\nKitap Puanı: {i['book_rating']}\n")

burayı da pek anlatmaya gerek yok sanırım.
burada asıl önemli olan api’ı nereden nasıl bulacağın. bunun için developer tools’a giriyorsun (sağ tıklayıp öğeyi denetle dediğin kısım) daha sonra yukarıdaki sekmelerden network kısmına tıklıyorsun (sende ‘ağ’ yazıyor olabilir)
image_2022-09-13_135734689
buradan Fetch/XHR seçiyorsun
daha sonra tekrar bkmkitap sitesine gelip bir arama yapıyorsun. arama yaptıktan sonra developer tools’un içerisine bir şeylerin dolduğunu göreceksin. örnek:


daha sonra bunlara tıklıyorum ve içerisinde ne var ona bakıyorum


örneğin wa.wawlabs com’da işime yarar hiçbir şey yok. hepsine tek tek bakıyorum işime yarayacak bilgiyi hangisinde bulabilirim onu araştırıyoruz aslında şu an.

avx_wse ile başlayan response’un içinde işime yarayacak şeyler var gibi görünüyor. brands’de yazarlar catste kategoriler var bana kitaplar lazım. bunlar da res’in içerisinde.

inan ne kadar açık yazdım bilmiyorum. konu hakkında başka bir sorun olursa discord üzerinden de detaylıca anlatmaya çalışırım. ayrıca küçük bir not da düşeyim tüm siteler api ile haberleşmez direkt db’den alıyor olabilir. o durumda developer tools’a işine yarar bir şey düşmeyebilir bilgin olsun.

3 Beğeni

elınıze saglık hocam cok teşekkür ederim