- Konu sahibi
- #1
İlk paragrafta ana yanıtı, izlenecek yolu ve ulaşılabilecek sonucu doğrudan ver. Konunun önemini öven genel açılış veya bu makalede anlatacağız vaadiyle başlama. Okuru asıl bilgiye ulaşmak için gereksiz paragraflar okumaya zorlama.
Bir web sayfasındaki veriyi Python ile çekmek için önce sayfanın HTML içeriğini HTTP isteğiyle alır, ardından HTML içindeki etiketleri ayrıştırarak aradığınız metni veya bağlantıyı seçersiniz. Basit ve sunucu tarafından oluşturulmuş sayfalarda
Aşağıdaki örnek, varsayımsal olarak bir sayfadaki başlıkları alır ve ekrana yazdırır. Kodun çalışması için önce gerekli paketleri kurun:
Ardından Python dosyanıza şu kodu ekleyin:
Kod çalıştığında sayfanın
Bir sayfadaki bütün başlıkları almak yerine belirli bir HTML sınıfını seçebilirsiniz. Örneğin hedef içerik şu yapıya sahipse:
Ürün adını ve fiyatını almak için seçiciyi sınıf adına göre daraltın:
Burada
Birden fazla ürün veya kayıt için
Seçiciyi tahmin etmek yerine tarayıcının geliştirici araçlarında ilgili öğenin HTML yapısını inceleyin. Ancak sınıf adları veya etiket yapısı değişebileceği için kodun doğru çalışması, verinin her zaman aynı yerde kalacağını kanıtlamaz. Veri gelmemeye başladığında önce sayfanın HTML yapısını yeniden kontrol edin.
Veriyi yalnızca ekrana yazdırmak yerine CSV dosyasına kaydedebilirsiniz. CSV, tablo verilerini satır ve sütunlar hâlinde saklayan basit bir metin biçimidir.
Dosya oluştuğunda satır sayısı, sayfada seçilen HTML öğesi sayısıyla uyumlu olmalıdır. Dosyanın boş olması verinin kesinlikle bulunmadığını kanıtlamaz; yanlış CSS seçicisi kullanılmış olabilir veya içerik JavaScript ile sonradan yükleniyor olabilir.
HTML kaynağında veri gerçekten bulunuyor mu, yoksa tarayıcı açıldıktan sonra mı oluşturuluyor sorusu yöntemi belirler.
Örneğin
Tarayıcıda görünen bir veri
API kullanırken yanıtın gerçekten JSON olup olmadığını ve beklenen alanları içerip içermediğini kontrol edin:
Bu örnekte
Çok sayıda sayfa çekerken her isteğe zaman aşımı ekleyin, istekler arasında makul bekleme bırakın ve aynı içeriği gereksiz yere tekrar indirmeyin. Kimlik doğrulama bilgilerini, çerezleri veya API anahtarlarını kaynak koduna sabitlemeyin; gerekiyorsa ortam değişkenlerinden okuyun. Kişisel verileri toplamak, saklamak veya paylaşmak için ayrıca hukuki dayanak ve uygun güvenlik önlemleri gerekebilir.
Önce tek bir URL ile çalışan küçük bir örnek hazırlayın. HTML seçicisinin doğru sonuç verdiğini gördükten sonra sayfalama, tekrar deneme, kayıt tutma ve dosyaya yazma gibi özellikleri ekleyin. Birden fazla sayfa işlenecekse hata alan URL’yi ve durum kodunu kaydetmek, sorunun veri yapısından mı yoksa erişimden mi kaynaklandığını ayırmanızı sağlar.
Python’da web sayfasından veri çekilir?
Bir web sayfasındaki veriyi Python ile çekmek için önce sayfanın HTML içeriğini HTTP isteğiyle alır, ardından HTML içindeki etiketleri ayrıştırarak aradığınız metni veya bağlantıyı seçersiniz. Basit ve sunucu tarafından oluşturulmuş sayfalarda
requests ile BeautifulSoup yeterlidir. Sayfa veriyi JavaScript çalıştıktan sonra oluşturuyorsa yalnızca HTML isteği beklediğiniz içeriği vermeyebilir; bu durumda sayfanın kullandığı API’yi incelemek veya tarayıcı otomasyonu kullanmak gerekir.Aşağıdaki örnek, varsayımsal olarak bir sayfadaki başlıkları alır ve ekrana yazdırır. Kodun çalışması için önce gerekli paketleri kurun:
Bash:
python -m pip install requests beautifulsoup4
Ardından Python dosyanıza şu kodu ekleyin:
Python:
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
headers = {
"User-Agent": "Mozilla/5.0 (compatible; VeriCekmeBot/1.0)"
}
response = requests.get(url, headers=headers, timeout=15)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
for baslik in soup.find_all(["h1", "h2", "h3"]):
metin = baslik.get_text(" ", strip=True)
if metin:
print(metin)
Kod çalıştığında sayfanın
h1, h2 ve h3 etiketlerindeki metinleri satır satır görürsünüz. response.text alınan HTML belgesidir; BeautifulSoup bu belgeyi gezinilebilir bir yapıya dönüştürür. find_all ise belirtilen etiketleri seçer. example.com yalnızca örnek adres olduğundan gerçek veriyi almak için hedef sayfanın adresini yazmalısınız.Belirli bir veriyi seçme
Bir sayfadaki bütün başlıkları almak yerine belirli bir HTML sınıfını seçebilirsiniz. Örneğin hedef içerik şu yapıya sahipse:
HTML:
<div class="urun">
<h2>Örnek ürün</h2>
<span class="fiyat">249 TL</span>
</div>
Ürün adını ve fiyatını almak için seçiciyi sınıf adına göre daraltın:
Python:
urun = soup.select_one("div.urun")
if urun is not None:
ad = urun.select_one("h2")
fiyat = urun.select_one(".fiyat")
print("Ürün:", ad.get_text(" ", strip=True) if ad else "Bulunamadı")
print("Fiyat:", fiyat.get_text(" ", strip=True) if fiyat else "Bulunamadı")
else:
print("Ürün bloğu bulunamadı.")
Burada
select_one ilk eşleşen öğeyi döndürür. Öğenin bulunamaması durumunda None dönebileceği için doğrudan .get_text() çağırmak hata oluşturabilir. Önce öğenin varlığını kontrol etmek, sayfanın yapısı değiştiğinde programın tamamen durmasını önler.Birden fazla ürün veya kayıt için
select kullanılır:
Python:
for urun in soup.select("div.urun"):
ad = urun.select_one("h2")
fiyat = urun.select_one(".fiyat")
if ad and fiyat:
print(
ad.get_text(" ", strip=True),
fiyat.get_text(" ", strip=True)
)
Seçiciyi tahmin etmek yerine tarayıcının geliştirici araçlarında ilgili öğenin HTML yapısını inceleyin. Ancak sınıf adları veya etiket yapısı değişebileceği için kodun doğru çalışması, verinin her zaman aynı yerde kalacağını kanıtlamaz. Veri gelmemeye başladığında önce sayfanın HTML yapısını yeniden kontrol edin.
Sonucu dosyaya kaydetme
Veriyi yalnızca ekrana yazdırmak yerine CSV dosyasına kaydedebilirsiniz. CSV, tablo verilerini satır ve sütunlar hâlinde saklayan basit bir metin biçimidir.
Python:
import csv
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
response = requests.get(url, timeout=15)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
kayitlar = []
for baslik in soup.select("h2"):
metin = baslik.get_text(" ", strip=True)
if metin:
kayitlar.append({"baslik": metin})
with open("basliklar.csv", "w", newline="", encoding="utf-8-sig") as dosya:
alanlar = ["baslik"]
yazici = csv.DictWriter(dosya, fieldnames=alanlar)
yazici.writeheader()
yazici.writerows(kayitlar)
print(f"{len(kayitlar)} kayıt basliklar.csv dosyasına yazıldı.")
Dosya oluştuğunda satır sayısı, sayfada seçilen HTML öğesi sayısıyla uyumlu olmalıdır. Dosyanın boş olması verinin kesinlikle bulunmadığını kanıtlamaz; yanlış CSS seçicisi kullanılmış olabilir veya içerik JavaScript ile sonradan yükleniyor olabilir.
Sayfa türüne göre doğru yöntemi seçme
HTML kaynağında veri gerçekten bulunuyor mu, yoksa tarayıcı açıldıktan sonra mı oluşturuluyor sorusu yöntemi belirler.
| Sayfa durumu | Uygun yöntem | Kontrol edilmesi gereken sonuç |
|---|---|---|
| Veri doğrudan HTML içinde | requests ve BeautifulSoup | İstenen öğeler içinde bulunmalı |
| Veri bir JSON API’den geliyor | API yanıtını requests ile almak | Yanıtın durum kodu ve JSON alanları |
| Veri JavaScript ile oluşturuluyor | Önce API’yi incelemek, gerekirse tarayıcı otomasyonu kullanmak | İlk HTML yanıtında öğelerin bulunmaması |
| Erişim engelleniyor veya hata dönüyor | İsteği, yetkiyi ve site kurallarını incelemek | Durum kodu ve sunucunun döndürdüğü açıklama |
response.status_code değeri 200 ise sunucu isteğe yanıt vermiştir; bu, aradığınız verinin alındığını garanti etmez. 403 erişim izninin reddedildiğini, 404 adresin bulunamadığını, 429 ise çok kısa sürede fazla istek gönderilmiş olabileceğini gösterir. Hata durumunda önce URL’yi, durum kodunu, yanıt başlıklarını ve sayfanın HTML içeriğinde aranan öğenin bulunup bulunmadığını kontrol edin.JavaScript ile yüklenen veriyi ayırt etme
Tarayıcıda görünen bir veri
requests.get() sonucunda görünmüyorsa sayfa büyük olasılıkla veriyi JavaScript ile sonradan yüklüyordur. Bunu anlamak için alınan HTML içinde aradığınız metni arayın. Metin yoksa ancak tarayıcıda görünüyorsa, geliştirici araçlarının ağ bölümünde sayfa açılırken yapılan JSON isteklerini inceleyin. Uygun ve erişilebilir bir API isteği bulunursa doğrudan o yanıtı almak, bütün tarayıcıyı çalıştırmaktan daha sade ve genellikle daha kararlı olur.API kullanırken yanıtın gerçekten JSON olup olmadığını ve beklenen alanları içerip içermediğini kontrol edin:
Python:
import requests
api_url = "https://example.com/api/items"
response = requests.get(api_url, timeout=15)
response.raise_for_status()
veri = response.json()
for kayit in veri.get("items", []):
print(kayit.get("name"))
Bu örnekte
items alanının API yanıtında gerçekten bulunması gerekir. Alan adı farklıysa veya yanıt liste biçimindeyse kodu gerçek JSON yapısına göre düzenlemelisiniz. API’nin çalışması, veriyi sınırsız veya izinsiz kullanabileceğiniz anlamına gelmez; sitenin kullanım koşullarını, erişim kurallarını ve kişisel veri içeren alanları ayrıca değerlendirin.İstekleri güvenli ve kararlı hâle getirme
Çok sayıda sayfa çekerken her isteğe zaman aşımı ekleyin, istekler arasında makul bekleme bırakın ve aynı içeriği gereksiz yere tekrar indirmeyin. Kimlik doğrulama bilgilerini, çerezleri veya API anahtarlarını kaynak koduna sabitlemeyin; gerekiyorsa ortam değişkenlerinden okuyun. Kişisel verileri toplamak, saklamak veya paylaşmak için ayrıca hukuki dayanak ve uygun güvenlik önlemleri gerekebilir.
Önce tek bir URL ile çalışan küçük bir örnek hazırlayın. HTML seçicisinin doğru sonuç verdiğini gördükten sonra sayfalama, tekrar deneme, kayıt tutma ve dosyaya yazma gibi özellikleri ekleyin. Birden fazla sayfa işlenecekse hata alan URL’yi ve durum kodunu kaydetmek, sorunun veri yapısından mı yoksa erişimden mi kaynaklandığını ayırmanızı sağlar.
Sık sorulan sorular
() neden tarayıcıda görünen veriyi vermiyor?
Çünkü tarayıcı, ilk HTML yanıtından sonra JavaScript çalıştırarak ek veri yüklüyor olabilir.
response.text içinde aradığınız metni bulunamıyorsa önce sayfanın kullandığı API isteğini inceleyin. API yoksa veya erişim için gerçek tarayıcı davranışı gerekiyorsa tarayıcı otomasyonu değerlendirilir.403 veya 429 hatasında ne yapılmalı?
403 sunucunun isteğe izin vermediğini, 429 ise istek hızının sınırlandırılmış olabileceğini gösterir. URL’yi ve isteğin gerektirdiği yetkiyi kontrol edin, istek sıklığını azaltın ve sitenin erişim kurallarına aykırı davranmayın. Hata sürüyorsa hata kodu, istek zamanı ve kullanılan adresle birlikte site yöneticisinden erişim koşullarını öğrenin; engeli aşmaya çalışmak yerine izin verilen yöntemi kullanın.