Como fazer scraping do Reddit usando Python

Comentários: 0

A raspagem do Reddit oferece uma grande quantidade de informações sobre tópicos de tendência, envolvimento da comunidade e postagens populares. Embora a API oficial do Reddit seja uma ferramenta comum para acessar esse conteúdo, ela tem limitações que a raspagem pode superar, fornecendo maior flexibilidade na seleção de dados. Este tutorial irá guiá-lo através do uso da biblioteca Playwright assíncrona para gerenciar o conteúdo dinâmico e a biblioteca lxml para extrair os dados, permitindo uma abordagem abrangente para raspar o Reddit.

Passo 1: Configurando o ambiente

Antes de começar, verifique se você tem o Python instalado e as bibliotecas necessárias:

pip install playwright
pip install  lxml

Depois de instalar as bibliotecas necessárias, terá de instalar os binários do browser Playwright:

playwright install

Para instalar apenas o navegador chromium, utilize o seguinte comando:

Playwright install chromium

Estas ferramentas ajudar-nos-ão a interagir com o conteúdo dinâmico do Reddit, a analisar o HTML e a extrair os dados necessários.

Passo 2: Buscando o conteúdo da página com o Playwright

O Playwright é uma ferramenta poderosa que nos permite controlar um navegador e interagir com páginas da Web como um usuário humano faria. Vamos usá-lo para carregar a página do Reddit e obter o conteúdo HTML.

Aqui está o código assíncrono do Playwright para carregar a página do 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

# Obter o conteúdo da página
page_content = asyncio.run(fetch_page_content())

Ao fazer scraping, pode deparar-se com problemas como a limitação da taxa ou o bloqueio de IP. Para atenuar estes problemas, pode utilizar proxies para rodar o seu endereço IP e cabeçalhos personalizados para imitar o comportamento de um utilizador real.

Utilização de proxies

Ao fazer scraping, você pode encontrar problemas como limitação de taxa ou bloqueio de IP. Para atenuar estes problemas, pode utilizar proxies para rodar o seu endereço IP e cabeçalhos personalizados para imitar o comportamento de um utilizador real. Os proxies podem ser utilizados para rodar endereços IP e evitar a deteção. Isso pode ser feito pelo seu provedor de serviços, garantindo que ele gerencie um pool de IPs e os gire conforme necessário.

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

Passo 3: Analisando o conteúdo HTML com lxml

Assim que tivermos o conteúdo HTML, o próximo passo é analisá-lo e extrair os dados relevantes usando lxml.

from lxml import html

# Analisar o conteúdo HTML
parser = html.fromstring(page_content)

Identificando os elementos a serem extraídos

As principais postagens no subreddit r/technology do Reddit estão contidas em elementos de artigo. Esses elementos podem ser direcionados usando o seguinte XPath:

# Extrair elementos individuais do post
elements = parser.xpath('//article[@class="w-full m-0"]')

Utilização do XPath para extração de dados

O XPath é uma ferramenta robusta para navegar e selecionar nós de um documento HTML. Vamos usá-lo para extrair o título, o link e a tag de cada post.

Aqui estão os XPaths específicos para cada ponto de dados:

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

Passo 4: Extraindo dados de cada post

Agora que segmentamos os elementos, podemos iterar sobre cada post e extrair os dados necessários.

posts_data = []

# Iterar sobre cada elemento do post
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)

Passo 5: Salvando os dados como JSON

Depois de extrair os dados, precisamos salvá-los em um formato estruturado. O JSON é um formato amplamente usado para essa finalidade.

import json

# Guardar os dados num ficheiro 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")

Código completo

Aqui está o código completo para raspar os principais posts do Reddit de r/technology e salvar os dados como 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

# Obter o conteúdo da página
page_content = asyncio.run(fetch_page_content())

# Analisar o conteúdo HTML utilizando lxml
parser = html.fromstring(page_content)

# Extrair elementos individuais do post
elements = parser.xpath('//article[@class="w-full m-0"]')

# Inicializar uma lista para guardar os dados extraídos
posts_data = []

# Iterar sobre cada elemento do post
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)

# Guardar os dados num ficheiro 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")

Este método permite fazer scraping em vários subreddits, recolhendo informações perspicazes das ricas discussões nas comunidades do Reddit. É importante utilizar proxies rotativos para minimizar o risco de deteção pelo Reddit. A utilização de proxies dinâmicos móveis e residenciais, que possuem o maior fator de confiança online, garante que os dados podem ser recolhidos sem despoletar captchas ou bloqueios, facilitando assim uma experiência de scraping mais suave.

Comentários:

0 Comentários