gmodstore-py 0.1.0
Python client library for scraping the GmodStore Job Market
Requires Python: >=3.8
Keywords: gmodstore, jobs, scraper, selenium, web-scraping, garry's-mod, gmod

# 🎮 GmodStore Jobs Python SDK

> Python client library for scraping the GmodStore Job Market

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## 📋 Overview

**gmodstore-py** is a Python SDK for scraping job listings from the [GmodStore Job Market](https://www.gmodstore.com/jobmarket). Since GmodStore doesn't provide a public API, this library uses Selenium WebDriver to extract job data from the website.

## ✨ Features

- 🔍 **Job Scraping** - Fetch job listings from GmodStore Job Market
- 📊 **Pagination Support** - Automatically fetch jobs from multiple pages
- 🎯 **Job Details** - Get complete information about specific jobs
- 🤖 **Headless Browser** - Uses headless Chrome for efficient scraping
- 📝 **Type Hints** - Full typing support for better IDE integration
- ⚡ **Performance Optimized** - Disables images and CSS for faster scraping
- 🐳 **Docker Ready** - Works in containerized environments

## 📦 Installation

```bash
pip install gmodstore-py
```

### System Requirements

This package requires Chrome/Chromium and ChromeDriver:

**Ubuntu/Debian:**
```bash
sudo apt install chromium chromium-driver
```

**macOS:**
```bash
brew install chromium chromedriver
```

**Docker:**
```dockerfile
RUN apt-get update && apt-get install -y chromium chromium-driver
```

## 🚀 Quick Start

```python
from gmodstore import GmodStoreClient

# Initialize client
client = GmodStoreClient()

# Fetch job list (basic info)
jobs = client.get_jobs(limit=10)

for job in jobs:
    print(f"{job.title} - {job.url}")

# Get detailed information
job_details = client.get_job_details(jobs[0].id)
print(f"Budget: {job_details.budget}")
print(f"Description: {job_details.description}")
```

## 📚 Usage Examples

### Fetch Job Listings

```python
from gmodstore import GmodStoreClient

client = GmodStoreClient()

# Get first 20 jobs
jobs = client.get_jobs(limit=20)

# With pagination (fetch from multiple pages)
jobs = client.get_jobs(limit=50, max_pages=3)

for job in jobs:
    print(f"[{job.id}] {job.title}")
    print(f"   URL: {job.url}")
```

### Get Job Details

```python
# Get detailed information about a specific job
job = client.get_job_details(job_id="12345")

if job:
    print(f"Title: {job.title}")
    print(f"Budget: {job.budget}")
    print(f"Category: {job.category}")
    print(f"Description: {job.description}")
    print(f"Applications: {job.applications}")
```

### Custom Configuration

```python
client = GmodStoreClient(
    headless=True,           # Run browser in headless mode
    timeout=10,              # Page load timeout in seconds
    user_agent="MyBot/1.0"   # Custom user agent
)
```

### Context Manager

```python
with GmodStoreClient() as client:
    jobs = client.get_jobs(limit=10)
    for job in jobs:
        details = client.get_job_details(job.id)
        print(f"{details.title}: {details.budget}")
# Driver automatically closed
```

## 🏗️ API Reference

### `GmodStoreClient`

Main client class for interacting with GmodStore Job Market.

#### Methods

##### `get_jobs(limit=20, max_pages=3) -> List[Job]`

Fetch a list of jobs from the job market.

**Parameters:**
- `limit` (int): Maximum number of jobs to return
- `max_pages` (int): Maximum number of pages to scrape

**Returns:** List of `Job` objects with basic information

##### `get_job_details(job_id) -> Optional[Job]`

Fetch detailed information about a specific job.

**Parameters:**
- `job_id` (str): The job ID (can include 'gmodstore_' prefix or not)

**Returns:** `Job` object with complete information or None

##### `get_job_details_by_url(job_url) -> Optional[Job]`

Fetch job details using a direct URL.

**Parameters:**
- `job_url` (str): Full URL to the job page

**Returns:** `Job` object with complete information or None

### `Job`

Job data model.

#### Attributes

```python
job.id              # str: Unique job ID (with 'gmodstore_' prefix)
job.title           # str: Job title
job.url             # str: Full URL to job posting
job.source          # str: Always 'gmodstore'
job.description     # Optional[str]: Job description
job.budget          # Optional[str]: Budget information
job.category        # Optional[str]: Job category
job.applications    # Optional[str]: Number of applications
job.created_at      # Optional[datetime]: Creation timestamp
```

### Exceptions

```python
from gmodstore import (
    GmodStoreException,    # Base exception
    ScrapingError,         # Scraping failed
    DriverError,           # Chrome driver error
)
```

## ⚙️ Configuration

### Environment Variables

```bash
# Chrome binary location (optional)
CHROME_BINARY=/usr/bin/chromium

# ChromeDriver location (optional)
CHROMEDRIVER_PATH=/usr/bin/chromedriver
```

### Performance Tuning

The client automatically optimizes performance by:
- ✅ Disabling images
- ✅ Disabling CSS
- ✅ Using `eager` page load strategy
- ✅ Minimizing wait times

## 🐳 Docker Support

```dockerfile
FROM python:3.12-slim

# Install Chrome and ChromeDriver
RUN apt-get update && apt-get install -y \
    chromium \
    chromium-driver \
    && rm -rf /var/lib/apt/lists/*

# Install package
RUN pip install gmodstore-py

# Your application
COPY . /app
WORKDIR /app
CMD ["python", "app.py"]
```

## 🧪 Testing

```bash
# Run tests
pytest

# Run with coverage
pytest --cov=gmodstore

# Run specific test
pytest tests/test_client.py
```

## ⚠️ Important Notes

### Rate Limiting

Be respectful of GmodStore's servers:
- Add delays between requests
- Don't scrape too frequently
- Use reasonable page limits

```python
import time

client = GmodStoreClient()
jobs = client.get_jobs(limit=20)

for job in jobs:
    details = client.get_job_details(job.id)
    time.sleep(1)  # Wait 1 second between requests
```

### Legal & Ethical Considerations

- ⚖️ Web scraping may violate GmodStore's Terms of Service
- 🤝 Use responsibly and ethically
- 💼 Consider contacting GmodStore for official API access
- 🚫 Do not use for commercial purposes without permission

## 📊 Examples

See the [examples/](examples/) directory for more usage examples:

- `basic_scraping.py` - Simple job fetching
- `detailed_scraping.py` - Get full job details
- `batch_scraping.py` - Fetch multiple pages
- `monitoring.py` - Job monitoring script

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## 👤 Author

**Sycatle**
- GitHub: [@Sycatle](https://github.com/Sycatle)

## 📝 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## ⚠️ Disclaimer

This is an **unofficial** scraper and is not affiliated with or endorsed by GmodStore. Use at your own risk and in compliance with GmodStore's Terms of Service.

## 🔗 Links

- [GmodStore Job Market](https://www.gmodstore.com/jobmarket)
- [Documentation](https://github.com/Sycatle/gmodstore-py#readme)
- [PyPI Package](https://pypi.org/project/gmodstore-py/) (Coming soon)
- [Issue Tracker](https://github.com/Sycatle/gmodstore-py/issues)

---

Made with ❤️ for the Garry's Mod community