Cara mengikis Reddit menggunakan Python

Komentar: 0

Scraping Reddit menawarkan banyak informasi tentang topik yang sedang tren, keterlibatan komunitas, dan postingan populer. Meskipun API resmi Reddit adalah alat yang umum digunakan untuk mengakses konten semacam itu, API ini memiliki keterbatasan yang dapat diatasi oleh scraping dengan memberikan fleksibilitas yang lebih besar dalam pemilihan data. Tutorial ini akan memandu Anda dalam menggunakan pustaka Playwright asinkron untuk mengelola konten dinamis dan pustaka lxml untuk mengekstrak data, yang memungkinkan pendekatan komprehensif untuk mengikis Reddit.

Langkah 1: Menyiapkan lingkungan

Sebelum memulai, pastikan Anda telah menginstal Python dan pustaka yang diperlukan:

pip install playwright
pip install  lxml

Setelah menginstal pustaka yang diperlukan, Anda perlu menginstal binari peramban Playwright:

playwright install

Untuk menginstal peramban kromium, gunakan perintah berikut:

Playwright install chromium

Alat-alat ini akan membantu kita berinteraksi dengan konten dinamis Reddit, mengurai HTML, dan mengekstrak data yang diperlukan.

Langkah 2: Mengambil konten halaman dengan Playwright

Playwright adalah alat canggih yang memungkinkan kita mengontrol peramban dan berinteraksi dengan halaman web seperti yang dilakukan oleh pengguna manusia. Kita akan menggunakannya untuk memuat halaman Reddit dan mendapatkan konten HTML.

Berikut adalah kode asinkronisasi Playwright untuk memuat halaman 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

# Mengambil konten halaman
page_content = asyncio.run(fetch_page_content())

Ketika melakukan scraping, Anda mungkin akan menemukan masalah seperti pembatasan kecepatan atau pemblokiran IP. Untuk mengatasi hal ini, Anda dapat menggunakan proxy untuk memutar alamat IP Anda dan header khusus untuk meniru perilaku pengguna yang sebenarnya.

Menggunakan proksi

Saat melakukan scraping, Anda mungkin mengalami masalah seperti pembatasan kecepatan atau pemblokiran IP. Untuk mengatasinya, Anda dapat menggunakan proksi untuk memutar alamat IP dan header khusus untuk meniru perilaku pengguna yang sebenarnya. Proksi dapat digunakan untuk memutar alamat IP dan menghindari deteksi. Hal ini bisa ditangani oleh penyedia layanan Anda, memastikan bahwa mereka mengelola kumpulan IP dan merotasinya sesuai kebutuhan.

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

Langkah 3: Mengurai konten HTML dengan lxml

Setelah kita memiliki konten HTML, langkah selanjutnya adalah mem-parsing dan mengekstrak data yang relevan dengan menggunakan lxml.

from lxml import html

# Mengurai konten HTML
parser = html.fromstring(page_content)

Mengidentifikasi elemen-elemen yang akan dikikis

Postingan teratas di subreddit r/teknologi Reddit terkandung di dalam elemen artikel. Elemen-elemen ini dapat ditargetkan dengan menggunakan XPath berikut ini:

# Mengekstrak masing-masing elemen postingan
elements = parser.xpath('//article[@class="w-full m-0"]')

Menggunakan XPath untuk ekstraksi data

XPath adalah alat yang kuat untuk menavigasi dan memilih node dari dokumen HTML. Kita akan menggunakannya untuk mengekstrak judul, tautan, dan tag dari setiap tulisan.

Berikut adalah XPath spesifik untuk setiap titik data:

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

Langkah 4: Mengekstrak data dari setiap postingan

Setelah kita menargetkan elemen-elemennya, kita dapat mengulang-ulang setiap postingan dan mengekstrak data yang diperlukan.

posts_data = []

# Lakukan pengulangan pada setiap elemen postingan
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)

Langkah 5: Menyimpan data sebagai JSON

Setelah mengekstrak data, kita perlu menyimpannya dalam format terstruktur. JSON adalah format yang banyak digunakan untuk tujuan ini.

import json

# Menyimpan data ke file 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")

Kode lengkap

Berikut ini adalah kode lengkap untuk mengambil postingan teratas Reddit dari r/technology dan menyimpan datanya sebagai 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

# Mengambil konten halaman
page_content = asyncio.run(fetch_page_content())

# Mengurai konten HTML menggunakan lxml
parser = html.fromstring(page_content)

# Mengekstrak masing-masing elemen postingan
elements = parser.xpath('//article[@class="w-full m-0"]')

# Inisialisasi daftar untuk menampung data yang diekstrak
posts_data = []

# Lakukan pengulangan pada setiap elemen postingan
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)

# Menyimpan data ke file 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")

Metode ini memungkinkan penggalian di berbagai subreddit, mengumpulkan informasi mendalam dari diskusi yang kaya di dalam komunitas Reddit. Sangat penting untuk menggunakan proxy bergilir untuk meminimalkan risiko terdeteksi oleh Reddit. Menggunakan proxy dinamis seluler dan residensial, yang memiliki faktor kepercayaan tertinggi secara online, memastikan data dapat dikumpulkan tanpa memicu captcha atau blokir, sehingga memfasilitasi pengalaman scraping yang lebih lancar.

Komentar:

0 komentar