gohorsejobs/JobScraper_MultiSite/main_scraper.py
Tiago Yamamoto 8856357acd feat: add JobScraper_MultiSite Python project
- main_scraper.py: Main entry point, consolidates data from all sources
- scrapers/programathor_scraper.py: Scraper for ProgramaThor
- scrapers/geekhunter_scraper.py: Scraper for GeekHunter
- requirements.txt: Python dependencies (requests, beautifulsoup4, pandas)
- README.md: Documentation with usage instructions
- Modular architecture for easy addition of new sites
2025-12-14 09:10:17 -03:00

130 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""
🐴 JobScraper MultiSite - Raspador de Vagas Multi-Plataforma
=============================================================
Consolida vagas de emprego de múltiplos sites de tecnologia.
"""
import pandas as pd
from datetime import datetime
import os
# Imports dos scrapers
from scrapers.programathor_scraper import scrape_programathor
from scrapers.geekhunter_scraper import scrape_geekhunter
# Configuração: Sites a serem raspados
SITES = {
'programathor': scrape_programathor,
'geekhunter': scrape_geekhunter,
}
# Pasta de output
OUTPUT_DIR = 'output'
def ensure_output_dir():
"""Cria a pasta de output se não existir."""
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
print(f"📁 Pasta '{OUTPUT_DIR}' criada.")
def run_scrapers(sites_to_run: list = None) -> pd.DataFrame:
"""
Executa os scrapers configurados e consolida os resultados.
Args:
sites_to_run: Lista de sites para raspar. Se None, raspa todos.
Returns:
DataFrame consolidado com todas as vagas.
"""
if sites_to_run is None:
sites_to_run = list(SITES.keys())
all_vagas = []
print("=" * 60)
print("🐴 JobScraper MultiSite - Iniciando raspagem...")
print("=" * 60)
for site_name in sites_to_run:
if site_name not in SITES:
print(f"⚠️ Site '{site_name}' não configurado. Pulando...")
continue
print(f"\n📡 Processando: {site_name.upper()}")
print("-" * 40)
scraper_func = SITES[site_name]
df = scraper_func()
if not df.empty:
all_vagas.append(df)
if all_vagas:
consolidated_df = pd.concat(all_vagas, ignore_index=True)
# Remover duplicatas baseado no link
consolidated_df.drop_duplicates(subset=['link'], inplace=True)
return consolidated_df
return pd.DataFrame()
def save_results(df: pd.DataFrame, filename: str = None) -> str:
"""
Salva o DataFrame consolidado em CSV.
Args:
df: DataFrame com as vagas.
filename: Nome do arquivo (opcional).
Returns:
Caminho do arquivo salvo.
"""
ensure_output_dir()
if filename is None:
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f'vagas_consolidadas_{timestamp}.csv'
filepath = os.path.join(OUTPUT_DIR, filename)
df.to_csv(filepath, index=False, encoding='utf-8-sig')
return filepath
def main():
"""Função principal."""
# Executar scrapers
df = run_scrapers()
print("\n" + "=" * 60)
if df.empty:
print("❌ Nenhuma vaga encontrada.")
return
# Estatísticas
print(f"📊 Total de vagas coletadas: {len(df)}")
print(f"📊 Fontes: {df['fonte'].value_counts().to_dict()}")
# Salvar resultados
filepath = save_results(df)
print(f"\n💾 Vagas salvas em: {filepath}")
# Também salvar versão "latest"
latest_path = save_results(df, 'vagas_consolidadas.csv')
print(f"💾 Versão atual: {latest_path}")
print("=" * 60)
print("✅ Raspagem concluída com sucesso!")
# Preview
print("\n📋 Preview das vagas:")
print(df[['titulo', 'empresa', 'fonte']].head(10).to_string(index=False))
if __name__ == "__main__":
main()