Jak zeskrobać Reddit za pomocą Pythona

Komentarze: 0

Scraping Reddit oferuje bogactwo informacji na temat popularnych tematów, zaangażowania społeczności i popularnych postów. Chociaż oficjalne API Reddit jest powszechnym narzędziem dostępu do takich treści, ma ograniczenia, które scraping może przezwyciężyć, zapewniając większą elastyczność w wyborze danych. Ten samouczek poprowadzi cię przez użycie asynchronicznej biblioteki Playwright do zarządzania dynamiczną zawartością i biblioteki lxml do wyodrębniania danych, umożliwiając kompleksowe podejście do skrobania Reddit.

Krok 1: Konfiguracja środowiska

Przed rozpoczęciem upewnij się, że masz zainstalowany Python i wymagane biblioteki:

pip install playwright
pip install  lxml

Po zainstalowaniu niezbędnych bibliotek, należy zainstalować pliki binarne przeglądarki Playwright:

playwright install

Aby zainstalować przeglądarkę chromium, użyj następującego polecenia:

Playwright install chromium

Narzędzia te pomogą nam wchodzić w interakcje z dynamiczną zawartością Reddita, analizować HTML i wyodrębniać wymagane dane.

Krok 2: Pobieranie zawartości strony za pomocą Playwright

Playwright to potężne narzędzie, które pozwala nam kontrolować przeglądarkę i wchodzić w interakcje ze stronami internetowymi tak, jak robiłby to ludzki użytkownik. Użyjemy go do załadowania strony Reddit i uzyskania zawartości HTML.

Oto kod asynchroniczny Playwright do załadowania strony Reddit:

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

# Pobieranie zawartości strony
page_content = asyncio.run(fetch_page_content())

Używanie serwerów proxy

Podczas skrobania można napotkać takie problemy, jak ograniczenie szybkości lub blokowanie adresów IP. Aby je złagodzić, można użyć serwerów proxy do rotacji adresu IP i niestandardowych nagłówków, aby naśladować rzeczywiste zachowanie użytkownika. Serwery proxy mogą być używane do rotacji adresów IP i unikania wykrycia. Może to być obsługiwane przez dostawcę usług, zapewniając zarządzanie pulą adresów IP i ich rotację w razie potrzeby.

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

Krok 3: Parsowanie zawartości HTML za pomocą lxml

Gdy mamy już zawartość HTML, następnym krokiem jest przeanalizowanie jej i wyodrębnienie odpowiednich danych za pomocą lxml.

from lxml import html

# Parsowanie zawartości HTML
parser = html.fromstring(page_content)

Identyfikacja elementów do skrobania

Najlepsze posty na subreddicie Reddit r/technology są zawarte w elementach artykułów. Elementy te mogą być celem przy użyciu następującego XPath:

# Wyodrębnianie poszczególnych elementów postów
elements = parser.xpath('//article[@class="w-full m-0"]')

Używanie XPath do ekstrakcji danych

XPath to solidne narzędzie do nawigacji i wybierania węzłów z dokumentu HTML. Użyjemy go do wyodrębnienia tytułu, linku i tagu z każdego postu.

Oto konkretne ścieżki XP dla każdego punktu danych:

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()

Krok 4: Wyodrębnianie danych z każdego postu

Teraz, gdy mamy już wybrane elementy, możemy iterować po każdym poście i wyodrębnić wymagane dane.

posts_data = []

# Iteracja po każdym elemencie posta
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)

Krok 5: Zapisywanie danych jako JSON

Po wyodrębnieniu danych musimy zapisać je w ustrukturyzowanym formacie. JSON jest szeroko stosowanym formatem do tego celu.

import json

# Zapisywanie danych w pliku JSON
with open('reddit_posts.json', 'w') as f:
    json.dump(posts_data, f, indent=4)

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

Kompletny kod

Oto kompletny kod do pobierania najlepszych postów Reddit z r/technology i zapisywania danych jako JSON:

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

# Pobieranie zawartości strony
page_content = asyncio.run(fetch_page_content())

# Parsowanie zawartości HTML przy użyciu lxml
parser = html.fromstring(page_content)

# Wyodrębnianie poszczególnych elementów postów
elements = parser.xpath('//article[@class="w-full m-0"]')

# Inicjalizacja listy do przechowywania wyodrębnionych danych
posts_data = []

# Iteracja po każdym elemencie posta
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)

# Zapisywanie danych w pliku JSON
with open('reddit_posts.json', 'w') as f:
    json.dump(posts_data, f, indent=4)

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

Metoda ta umożliwia skrobanie różnych subredditów, gromadząc wnikliwe informacje z bogatych dyskusji w społecznościach Reddit. Ważne jest, aby używać obrotowych serwerów proxy w celu zminimalizowania ryzyka wykrycia przez Reddit. Korzystanie z mobilnych i mieszkaniowych dynamicznych serwerów proxy, które mają najwyższy współczynnik zaufania online, zapewnia gromadzenie danych bez uruchamiania captcha lub blokad, ułatwiając w ten sposób płynniejsze skrobanie.

Komentarze:

0 komentarze