Python kullanarak Yahoo Images'dan görseller nasıl kazınır?

Yorumlar: 0

Yahoo Image Search'ten görüntüleri kazımak, görüntü veri setleri oluştururken önemlidir. Bu kılavuz, HTML ayrıştırma teknikleri için lxml ile birlikte Python ve Requests kütüphanesini kullanarak Yahoo Image Search'ten görüntülerin nasıl kazınacağını açıklamaktadır. Ayrıca Yahoo bot tespit sistemleri tarafından yakalanmamak için proxy kullanımına da değinmektedir.

Gerekli araçlar ve kütüphaneler

Yahoo Images'dan görüntüleri kazımak için aşağıdaki Python kütüphanelerine ihtiyacınız olacak:

  • İstekler: HTTP istekleri yapmak için.
  • lxml: HTML ayrıştırmak için.
  • Proxy'ler: Kapsamlı kazıma sırasında IP yasaklarından kaçınmak için.

Üçüncü taraf kütüphaneleri yükleme

Gerekli tüm kütüphanelerin kurulu olduğundan emin olun. Bunları pip kullanarak yükleyin:

pip install requests
pip install lxml

Ya da tek bir komut kullanın:

pip install requests lxml

Python ile kazıma için adım adım kılavuz

İlk olarak, kazıyıcımız için gerekli kütüphaneleri içe aktarmamız gerekiyor.

import requests
from lxml import html

Yahoo Images araması gerçekleştirin

Ardından, Yahoo Images üzerinde bir arama yapacağız.

Burada bir arama sorgusunu yavru köpekler olarak tanımlayacağız ve Yahoo Images aramasına gerekli başlıklarla birlikte bir GET isteği göndereceğiz. İstek başlıkları, bazı temel bot algılama mekanizmalarını atlamaya yardımcı olan bir tarayıcı isteğini taklit etmek için önemlidir.

# Tarayıcı isteğini taklit etmek için üstbilgileri tanımlayın
headers = {
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "accept-language": "en-IN,en;q=0.9",
    "cache-control": "max-age=0",
    "dnt": "1",
    "priority": "u=0, i",
    "sec-ch-ua": '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Linux"',
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "none",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
}

# Arama sorgusunu tanımlayın
search_query = "puppies"

# Yahoo Images arama sayfasına bir GET isteği yapın
response = requests.get(
    url=f"https://images.search.yahoo.com/search/images?p={search_query}",
    headers=headers
)

Resim URL'lerini lxml ile ayrıştırma

Yahoo'dan yanıtı aldıktan sonra, görüntü URL'lerini çıkarmak için HTML'yi ayrıştırmamız gerekir. Bu amaç için lxml kullanıyoruz.

# HTML yanıtını ayrıştırma
parser = fromstring(response.text)

# XPath kullanarak görüntü URL'lerini ayıklama
images_urls = parser.xpath("//li[contains(@id, 'resitem-')]/a//@src")

fromstring işlevi HTML yanıt metnini ayrıştırmak için kullanılır. Xpath, görüntülerin URL'lerini çıkarmak için kullanılır. Aşağıdaki ekran görüntüsü xpath'in nasıl elde edildiğini göstermektedir.

yaho.png

Görselleri indirin

Resim URL'lerinin listesiyle, şimdi her bir resmi indirmemiz gerekiyor.

Burada, hem sayıyı (dizin) hem de url'yi (adres) çıkarmak için images_urls listesi boyunca döngü yapacağız. Daha sonra her resim, ilgili url'ye bir GET isteği gönderilerek indirilecektir.

# Her bir resmi indirin ve bir dosyaya kaydedin
for count, url in enumerate(images_urls):
    response = requests.get(url=url, headers=headers)

Görüntüleri kaydetme

Son olarak, indirilen görüntüleri yerel dosya sistemine kaydediyoruz. Dosya kaydetme işlemini gerçekleştiren bir download_file fonksiyonu tanımlıyoruz.

Bu fonksiyon sayıyı (benzersiz dosya adları oluşturmak için) ve yanıtı (görüntü verilerini içeren) alır. Content-Type başlığından dosya uzantısını belirler ve dosyayı ./images/ dizinine kaydeder.

def download_file(count, response):
    # Dosya uzantısını Content-Type başlığından alın
    extension = response.headers.get("Content-Type").split("/")[1]
    filename = "./images/" + str(count) + f".{extension}"

    # Dizin mevcut değilse oluşturun
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    # Yanıt içeriğini dosyaya yazın
    with open(filename, "wb") as f:
        f.write(response.content)

Bu fonksiyonu döngü içinde çağırarak, indirilen her görüntüyü kaydederiz:

for count, url in enumerate(images_urls):
    response = requests.get(url=url, headers=headers)
    download_file(count, response)

Yahoo'nun bot tespit mekanizmaları

Yahoo'dan veri kazırken, Yahoo'nun bot tespit mekanizmalarının farkında olmak önemlidir. Yahoo bu teknikleri çoğunlukla otomatik botları tespit etmek ve engellemek için kullanır:

  • IP Hız Sınırlaması: Yahoo, tek bir IP adresinden gelen isteklerin oranını izler. Bir IP'den gelen aşırı istekler geçici veya kalıcı yasaklara yol açabilir.
  • CAPTCHA'lar: Yahoo, kullanıcılara insan olduklarını doğrulamak için CAPTCHA'lar uygulayabilir.

Tespit edilmekten kaçınmak için proxy kullanımı

Yahoo bot algılama mekanizması tarafından engellenmekten kaçınmak için, özellikle aynı IP'den birden fazla istek yaparken, IP adresimizi maskelemek için proxy'ler kullanıyoruz.

İsteklerimizi farklı proxy'ler üzerinden yönlendirerek, kazıma faaliyetimizi birden fazla IP adresine dağıtabilir ve böylece tespit edilme olasılığını azaltabiliriz.

proxies = {
    'http': 'http://USER:PASS@HOST:PORT',
    'https': 'http://USER:PASS@HOST:PORT'
}
response = requests.get(url, headers=headers, proxies=proxies, verify=False)

Tamamlanmış kod

İşte proxy kullanarak Yahoo Images arama sonuçlarından resim kazımak için eksiksiz komut dosyası:

import os
import requests
from lxml.html import fromstring


def download_file(count, response):
    """
    Bir yanıtın içeriğini ./images/ dizinindeki bir dosyaya kaydeder.

    Args:
        count (int): Dosya için benzersiz bir tanımlayıcı.
        response (requests.Response): Dosya içeriğini içeren HTTP yanıtı.

    """
    # Dosya uzantısını Content-Type başlığından alın
    extension = response.headers.get("Content-Type").split("/")[1]
    filename = "./images/" + str(count) + f".{extension}"

    # Dizin mevcut değilse oluşturun
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    # Yanıt içeriğini dosyaya yazın
    with open(filename, "wb") as f:
        f.write(response.content)


def main():
    """
    Görüntüleri aramak ve indirmek için ana işlev.

    Bu işlev aşağıdaki adımları gerçekleştirir:
    1. İstek başlıklarını ayarlar.
    2. Yahoo'da yavru köpek resimleri arar.
    3. Resim URL'lerini çıkarmak için HTML yanıtını ayrıştırır.
    4. Her resmi indirir ve ./images/ dizinine kaydeder.

    """
    # Tarayıcı isteğini taklit etmek için üstbilgileri tanımlayın
    headers = {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "accept-language": "en-IN,en;q=0.9",
        "cache-control": "max-age=0",
        "dnt": "1",
        "priority": "u=0, i",
        "sec-ch-ua": '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Linux"',
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "none",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
    }

    # Hız sınırlamasını atlamak için proxy'leri tanımlama
    proxies = {"http": "http://USER:PASS@HOST:PORT", "https": "http://USER:PASS@HOST:PORT"}

    # Arama sorgusunu tanımlayın
    search_query = "puppies"

    # Yahoo Images arama sayfasına bir GET isteği yapın
    response = requests.get(
        url=f"https://images.search.yahoo.com/search/images?p={search_query}",
        headers=headers,
        proxies=proxies,
        verify=False
    )

    # HTML yanıtını ayrıştırma
    parser = fromstring(response.text)

    # XPath kullanarak görüntü URL'lerini ayıklama
    images_urls = parser.xpath("//li[contains(@id, 'resitem-')]/a//@src")

    # Her bir resmi indirin ve bir dosyaya kaydedin
    for count, url in enumerate(images_urls):
        response = requests.get(url=url, headers=headers, proxies=proxies, verify=False)
        download_file(count, response)


if __name__ == "__main__":
    main()

Python kullanarak Yahoo Image Search'ten görüntüleri kazımak, veri toplama ve analiz görevlerini otomatikleştirmek için güçlü bir tekniktir. HTTP istekleri için Requests kütüphanesini ve HTML ayrıştırma için lxml kütüphanesini kullanarak, görüntü URL'lerini verimli bir şekilde çıkarabilir ve görüntüleri indirebilirsiniz. Proxy'leri dahil etmek, kapsamlı kazıma faaliyetleri sırasında tespit edilmekten kaçınmanıza ve IP yasaklarını önlemenize yardımcı olur.

Yorumlar:

0 yorumlar