Python kullanarak Reddit nasıl kazınır

Yorumlar: 0

Reddit'i kazımak, trend konular, topluluk katılımı ve popüler gönderiler hakkında zengin bilgiler sunar. Reddit'in resmi API'si bu tür içeriğe erişmek için yaygın bir araç olsa da, veri seçiminde daha fazla esneklik sağlayarak kazımanın üstesinden gelebileceği sınırlamaları vardır. Bu eğitim, dinamik içeriği yönetmek için asenkron Playwright kütüphanesini ve verileri ayıklamak için lxml kütüphanesini kullanarak Reddit'i kazımak için kapsamlı bir yaklaşıma izin verecektir.

Adım 1: Ortamın ayarlanması

Başlamadan önce Python'un ve gerekli kütüphanelerin kurulu olduğundan emin olun:

pip install playwright
pip install  lxml

Gerekli kütüphaneleri yükledikten sonra Playwright tarayıcı ikili dosyalarını yüklemeniz gerekir:

playwright install

Sadece chromium tarayıcısını yüklemek için aşağıdaki komutu kullanın:

Playwright install chromium

Bu araçlar Reddit'in dinamik içeriğiyle etkileşime girmemize, HTML'yi ayrıştırmamıza ve gerekli verileri çıkarmamıza yardımcı olacak.

Adım 2: Playwright ile sayfa içeriğini getirme

Playwright, bir tarayıcıyı kontrol etmemize ve web sayfalarıyla bir insan kullanıcının yapacağı gibi etkileşime girmemize olanak tanıyan güçlü bir araçtır. Reddit sayfasını yüklemek ve HTML içeriğini elde etmek için kullanacağız.

İşte Reddit sayfasını yüklemek için Playwright asenkron kodu:

import asyncio
from playwright.async_api import async_playwright

async def fetch_page_content():
    async with async_playwright() as playwright:
        browser = await playwright.chromium.launch(headless=False)
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto("https://www.reddit.com/r/technology/top/?t=week")
        page_content = await page.content()
        await browser.close()
        return page_content

# Sayfa içeriğini getir
page_content = asyncio.run(fetch_page_content())

Kazıma yaparken hız sınırlaması veya IP engellemesi gibi sorunlarla karşılaşabilirsiniz. Bunları azaltmak için, IP adresinizi döndürmek için proxy'ler ve gerçek kullanıcı davranışını taklit etmek için özel başlıklar kullanabilirsiniz.

Proxy'leri kullanma

Kazıma yaparken hız sınırlaması veya IP engellemesi gibi sorunlarla karşılaşabilirsiniz. Bunları hafifletmek için IP adresinizi döndürmek üzere proxy'ler ve gerçek kullanıcı davranışını taklit etmek için özel başlıklar kullanabilirsiniz. Proxy'ler IP adreslerini döndürmek ve tespit edilmekten kaçınmak için kullanılabilir. Bu, hizmet sağlayıcınız tarafından bir IP havuzunu yönetmeleri ve gerektiğinde bunları döndürmeleri sağlanarak halledilebilir.

async def fetch_page_content_with_proxy():
    async with async_playwright() as playwright:
        browser = await playwright.chromium.launch(headless=True, proxy={
            "server": "http://proxy-server:port",
            "username": "your-username",
            "password": "your-password"
        })
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto("https://www.reddit.com/r/technology/top/?t=week", wait_until='networkidle')
        page_content = await page.content()
        await browser.close()
        return page_content

Adım 3: HTML içeriğini lxml ile ayrıştırma

HTML içeriğine sahip olduğumuzda, bir sonraki adım bunu ayrıştırmak ve lxml kullanarak ilgili verileri çıkarmaktır.

from lxml import html

# HTML içeriğini ayrıştırma
parser = html.fromstring(page_content)

Kazınacak öğelerin belirlenmesi

Reddit'in r/technology alt dizinindeki en iyi gönderiler makale öğeleri içinde yer alır. Bu öğeler aşağıdaki XPath kullanılarak hedeflenebilir:

# Tek tek gönderi öğelerini ayıklama
elements = parser.xpath('//article[@class="w-full m-0"]')

Veri ayıklama için XPath kullanımı

XPath, bir HTML belgesindeki düğümlerde gezinmek ve bunları seçmek için kullanılan sağlam bir araçtır. Her gönderiden başlığı, bağlantıyı ve etiketi çıkarmak için kullanacağız.

İşte her veri noktası için özel XPath'ler:

Title: @aria-label
Link: .//div[@class="relative truncate text-12 xs:text-14 font-semibold mb-xs "]/a/@href
Tag: .//span[@class="bg-tone-4 inline-block truncate max-w-full text-12 font-normal align-text-bottom text-secondary box-border px-[6px] rounded-[20px] leading-4 relative top-[-0.25rem] xs:top-[-2px] my-2xs xs:mb-sm py-0 "]/div/text()

Adım 4: Her gönderiden veri çıkarma

Artık öğeleri hedeflediğimize göre, her gönderi üzerinde yineleme yapabilir ve gerekli verileri çıkarabiliriz.

posts_data = []

# Her gönderi öğesi üzerinde yinele
for element in elements:
    title = element.xpath('@aria-label')[0]
    link = element.xpath('.//div[@class="relative truncate text-12 xs:text-14 font-semibold  mb-xs "]/a/@href')[0]
    tag = element.xpath('.//span[@class="bg-tone-4 inline-block truncate max-w-full text-12 font-normal align-text-bottom text-secondary box-border px-[6px] rounded-[20px] leading-4  relative top-[-0.25rem] xs:top-[-2px] my-2xs xs:mb-sm py-0 "]/div/text()')[0].strip()
    
    post_info = {
        "title": title,
        "link": link,
        "tag": tag
    }
    
    posts_data.append(post_info)

Adım 5: Verileri JSON olarak kaydetme

Verileri çıkardıktan sonra, yapılandırılmış bir formatta kaydetmemiz gerekir. JSON bu amaç için yaygın olarak kullanılan bir formattır.

import json

# Verileri bir JSON dosyasına kaydedin
with open('reddit_posts.json', 'w') as f:
    json.dump(posts_data, f, indent=4)

print("Data extraction complete. Saved to reddit_posts.json")

Tamamlanmış kod

Reddit'in en iyi gönderilerini r/technology'den kazımak ve verileri JSON olarak kaydetmek için eksiksiz kodu burada bulabilirsiniz:

import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json

async def fetch_page_content():
    async with async_playwright() as playwright:
        browser = await playwright.chromium.launch(headless=True, proxy={
            "server": "IP:port",
            "username": "your-username",
            "password": "your-password"
        })
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto("https://www.reddit.com/r/technology/top/?t=week", wait_until='networkidle')
        page_content = await page.content()
        await browser.close()
        return page_content

# Sayfa içeriğini getir
page_content = asyncio.run(fetch_page_content())

# HTML içeriğini lxml kullanarak ayrıştırma
parser = html.fromstring(page_content)

# Extract individual post elements
elements = parser.xpath('//article[@class="w-full m-0"]')

# Çıkarılan verileri tutmak için bir liste başlatın
posts_data = []

# Her gönderi öğesi üzerinde yinele
for element in elements:
    title = element.xpath('@aria-label')[0]
    link = element.xpath('.//div[@class="relative truncate text-12 xs:text-14 font-semibold  mb-xs "]/a/@href')[0]
    tag = element.xpath('.//span[@class="bg-tone-4 inline-block truncate max-w-full text-12 font-normal align-text-bottom text-secondary box-border px-[6px] rounded-[20px] leading-4  relative top-[-0.25rem] xs:top-[-2px] my-2xs xs:mb-sm py-0 "]/div/text()')[0].strip()
    
    post_info = {
        "title": title,
        "link": link,
        "tag": tag
    }
    
    posts_data.append(post_info)

# Verileri bir JSON dosyasına kaydedin
with open('reddit_posts.json', 'w') as f:
    json.dump(posts_data, f, indent=4)

print("Data extraction complete. Saved to reddit_posts.json")

Bu yöntem, Reddit topluluklarındaki zengin tartışmalardan içgörülü bilgiler toplayarak çeşitli alt dizinlerde kazıma yapılmasını sağlar. Reddit tarafından tespit edilme riskini en aza indirmek için dönen proxy'ler kullanmak önemlidir. Çevrimiçi ortamda en yüksek güven faktörüne sahip olan mobil ve konut dinamik proxy'lerinin kullanılması, verilerin captcha'ları veya blokları tetiklemeden toplanabilmesini sağlar ve böylece daha sorunsuz bir kazıma deneyimini kolaylaştırır.

Yorumlar:

0 yorumlar