Skip to main content

Playwright-based scraper implementation for The Pudim Hunter platform

Project description

Pudim Hunter Driver Scraper 🍮

Python 3.9 Pytest 7.4 CI codecov PyPI version

A Python package that provides a Playwright-based scraper implementation for The Pudim Hunter platform. This package extends the pudim-hunter-driver interface to provide a common base for implementing job board scrapers.

Table of Contents

  1. Features
  2. Installation
  3. Usage
  4. Development Setup
  5. Project Structure
  6. Testing
  7. Contributing
  8. License

Features

  • Playwright-based web scraping
  • Headless browser automation
  • Easy-to-extend base classes for job board implementations
  • Built-in error handling and resource management
  • Type hints and validation using Pydantic
  • Advanced anti-detection scraping with PhantomPlaywrightScraper
    • WebDriver detection evasion
    • WebGL vendor spoofing
    • Chrome properties emulation
    • Plugin spoofing
    • Language preferences customization
    • And more stealth features

Installation

PyPI Installation

You can install the package directly from PyPI:

pip install pudim-hunter-driver-scraper

Or add to your requirements.txt:

pudim-hunter-driver-scraper>=0.0.1  # Replace with the version you need

Development Installation

For development:

git clone git@github.com:luismr/pudim-hunter-driver-scraper.git
cd pudim-hunter-driver-scraper
pip install -e .

Usage

Interface Overview

This package provides the base scraper implementation for job search drivers. To create a scraper for a specific job board, you'll need to extend the ScraperJobDriver class and implement the required methods.

  1. ScraperJobDriver (ABC) - The base scraper class that implements JobDriver:

    • build_search_url(query: JobQuery) -> str
    • get_selectors() -> Dict[str, str]
    • extract_raw_job_data() -> Optional[List[Dict[str, Any]]]
    • transform_job(data: Dict[str, Any]) -> Optional[Job]
  2. PlaywrightScraper - The base scraper implementation:

    • Handles browser lifecycle
    • Provides navigation and data extraction methods
    • Context manager support with with statement
  3. PhantomPlaywrightScraper - Enhanced scraper with anti-detection:

    • All features of base PlaywrightScraper
    • Advanced bot detection evasion
    • Stealth mode configurations
  4. Exceptions:

    • Inherits all exceptions from pudim-hunter-driver
    • Adds scraper-specific error handling

Example Implementation

from typing import Dict, Any, Optional, List
from pudim_hunter_driver.models import JobQuery, Job
from pudim_hunter_driver_scraper import ScraperJobDriver
from pudim_hunter_driver_scraper.driver import ScraperType

class MyPhantomJobDriver(ScraperJobDriver):
    def __init__(self):
        super().__init__(scraper_type=ScraperType.PHANTOM)
    
    def build_search_url(self, query: JobQuery) -> str:
        """Build the search URL for the job board."""
        return f"https://example.com/jobs?q={query.keywords}&l={query.location}"
    
    def get_selectors(self) -> Dict[str, str]:
        """Define CSS selectors for job elements."""
        return {
            "job_list": ".job-listing",
            "title": ".job-title",
            "company": ".company-name",
            "location": ".job-location"
        }
    
    def extract_raw_job_data(self) -> Optional[List[Dict[str, Any]]]:
        """Extract job data from the page."""
        jobs_data = []
        job_elements = self.scraper._page.query_selector_all(self.get_selectors()["job_list"])
        
        for job in job_elements:
            title = job.query_selector(self.get_selectors()["title"])
            company = job.query_selector(self.get_selectors()["company"])
            
            if title and company:
                jobs_data.append({
                    "title": title.inner_text(),
                    "company": company.inner_text()
                })
        
        return jobs_data
    
    def transform_job(self, data: Dict[str, Any]) -> Optional[Job]:
        """Transform raw job data into Job model."""
        if not data.get("title"):
            return None
            
        return Job(
            id=f"job-{hash(data['title'])}",
            title=data["title"],
            company=data["company"],
            location="",
            description="",
            url="",
            remote=False,
            source="Example",
            posted_at=datetime.now()
        )

Usage Examples

# Using the driver
driver = MyPhantomJobDriver()
query = JobQuery(
    keywords="software engineer",
    location="San Francisco",
    page=1,
    items_per_page=20
)

job_list = driver.fetch_jobs(query)
for job in job_list.jobs:
    print(f"{job.title} at {job.company}")

For more detailed examples, check the test files:

  • tests/test_driver_phantom.py: Complete job driver implementation example
  • tests/test_scraper_phantom.py: Anti-detection features testing
  • tests/test_scraper_phantom_sites.py: Real-world site scraping examples

Development Setup

Virtual Environment

We strongly recommend using a virtual environment for development and testing.

Prerequisites

  • Python 3.9 or higher
  • pip (Python package installer)
  • venv module (usually comes with Python 3)

Setup Instructions

  1. Create and activate virtual environment:
python3.9 -m venv venv
source venv/bin/activate  # On Windows: .\venv\Scripts\activate
  1. Install dependencies:
pip install -r requirements.txt
pip install -e .
  1. Install Playwright browsers:
playwright install chromium

Project Structure

pudim-hunter-driver-scraper/
├── src/
│   └── pudim_hunter_driver_scraper/
│       ├── __init__.py          # Package initialization
│       ├── scraper.py           # PlaywrightScraper implementation
│       └── driver.py            # ScraperJobDriver implementation
├── tests/                       # Test directory
│   └── __init__.py
├── README.md                    # This file
├── requirements.txt             # Direct dependencies
├── setup.py                     # Package setup
└── pyproject.toml              # Project configuration

Testing

Run the tests:

pytest tests/

Key test files:

  • test_driver_phantom.py: Tests for phantom job driver implementation
  • test_scraper_phantom.py: Tests for anti-detection capabilities
  • test_scraper_phantom_sites.py: Tests for real-world site scraping

Contributing

Getting Started

  1. Fork and clone the repository:
git clone git@github.com:luismr/pudim-hunter-driver-scraper.git
cd pudim-hunter-driver-scraper
  1. Create your feature branch:
git checkout -b feature/amazing-feature
  1. Set up development environment:
python3.9 -m venv venv
source venv/bin/activate
pip install -e .

Pull Request Process

  1. Update documentation as needed
  2. Add/update tests as needed
  3. Ensure all tests pass
  4. Submit PR for review

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Copyright (c) 2024-2025 Luis Machado Reis

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pudim-hunter-driver-scraper-0.0.12.tar.gz (1.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pudim_hunter_driver_scraper-0.0.12-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file pudim-hunter-driver-scraper-0.0.12.tar.gz.

File metadata

File hashes

Hashes for pudim-hunter-driver-scraper-0.0.12.tar.gz
Algorithm Hash digest
SHA256 f8faf506bd0ec5f8e7ce8d82d6168ddde33312612f6b1ae14683f15b436e24aa
MD5 734aed44e7cbd43d6f3cdb22e80483b9
BLAKE2b-256 a875648a08c3db231a6517ea383309621cbe7ff1503bf8573d9cbe17796fe45b

See more details on using hashes here.

File details

Details for the file pudim_hunter_driver_scraper-0.0.12-py3-none-any.whl.

File metadata

File hashes

Hashes for pudim_hunter_driver_scraper-0.0.12-py3-none-any.whl
Algorithm Hash digest
SHA256 4ea9c5902e979b9d42faac9da49d5ce7726f1b77965c51fb1858e818c36f584e
MD5 e8a8d54abbbab52e973e68b968e426d8
BLAKE2b-256 9a517a62a77878e170ac74e4b690a18c2ab30adb235f170bd6bb417300045722

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page