WebSleuth - A lightweight, extensible web scraping framework.
Project description
🕵️ WebSleuth
WebSleuth is a lightweight, developer-first Python library that simplifies web scraping. It wraps around common scraping tools like requests, BeautifulSoup, and lxml — adding support for proxy rotation, retry logic, async workflows, and data export — all in a customizable and modular way.
🚀 Features
- ✅ Queue-based URL handling with duplicate prevention
- ✅ CSS & XPath parser support
- ✅ User-Agent rotation using
fake-useragent - ✅ Proxy rotation with support for list or external APIs
- ✅ Retry logic with exponential backoff
- ✅ Auto-throttling with adaptive delay
- ✅ Synchronous and asynchronous scraping support
- ✅ Export to JSON, CSV, and Excel formats
- ✅ Modular middleware stack architecture
- ✅ Comprehensive logging and error handling
- ✅ Configuration management with persistent state
📦 Installation
pip install websleuth
🧰 Quick Start
Synchronous Scraping
from websleuth import Scraper
# Initialize a scraper with CSS selectors
scraper = Scraper(parser_type='css', output_file='results.json')
# Add URLs to scrape
scraper.add_url('https://example.com')
# Scrape for data using a CSS selector
results = scraper.scrape('h1')
Asynchronous Scraping
import asyncio
from websleuth import AsyncScraper
async def main():
# Initialize an async scraper with 5 concurrent requests
scraper = AsyncScraper(parser_type='css', output_file='results.json', concurrency=5)
# Add multiple URLs to scrape
scraper.add_urls(['https://example.com', 'https://example.org'])
# Scrape data asynchronously using a CSS selector
results = await scraper.scrape('h1')
return results
# Run the async scraper
results = asyncio.run(main())
📚 Documentation
Core Components
- URLQueue: Manages URLs to be scraped with duplicate prevention
- Parsers: CSS selectors (BeautifulSoup) and XPath (lxml) support
- Middleware: Modular components for request/response handling
- Exporters: Data export to JSON, CSV, and Excel formats
Middleware Components
- UserAgentMiddleware: Rotates user agents for each request
- ProxyMiddleware: Manages proxy rotation
- LoggingMiddleware: Comprehensive request/response logging
- RetryMiddleware: Implements retry logic with backoff
- AutoThrottleMiddleware: Adaptive request throttling
- AsyncMiddlewareManager: Asynchronous middleware processing
Advanced Usage
Customizing Middleware
from websleuth import Scraper
from websleuth.middleware import (
UserAgentMiddleware,
ProxyMiddleware,
LoggingMiddleware,
RetryMiddleware,
AutoThrottleMiddleware,
MiddlewareManager
)
# Create custom middleware stack
middlewares = [
UserAgentMiddleware(),
ProxyMiddleware(proxy_list=["http://proxy1.example.com", "http://proxy2.example.com"]),
LoggingMiddleware(),
RetryMiddleware(max_retries=5, backoff_factor=2)
]
# Create middleware manager
middleware_manager = MiddlewareManager(middlewares)
# Create scraper with custom middleware manager
scraper = Scraper(parser_type='css')
scraper.middleware_manager = middleware_manager
Extract Links
from websleuth import Scraper
from websleuth.parser import CSSParser
# Initialize scraper and fetch page
scraper = Scraper()
status, html = scraper.middleware_manager.fetch('https://example.com')
# Extract all links from the page
if status == 200 and html:
parser = CSSParser(html)
all_links = parser.extract_links()
for link in all_links:
scraper.add_url(link) # Add discovered links to the queue
Async Export Example
import asyncio
from websleuth.export import AsyncDataExporter
async def export_data(results):
async with AsyncDataExporter() as exporter:
# Export to different formats
await exporter.export(results, "data.json") # JSON
await exporter.export(results, "data.csv") # CSV
await exporter.export(results, "data.xlsx") # Excel
# Export data asynchronously
asyncio.run(export_data(results))
🛠️ Configuration
WebSleuth supports persistent configuration through a ConfigManager that stores settings between sessions.
from websleuth import Scraper
from websleuth.shared_utils import ConfigManager
# Custom configuration directory
config = ConfigManager(config_dir="./my_config")
# Create auto-throttle middleware with custom config
from websleuth.middleware import AutoThrottleMiddleware
throttle = AutoThrottleMiddleware(
config=config,
base_delay=1.5, # Base delay between requests (seconds)
max_delay=15, # Maximum delay cap (seconds)
window_size=10 # Number of requests to consider for average
)
🔧 Throttling & Backoff
WebSleuth includes smart throttling to avoid server overload and respect rate limits:
from websleuth.shared_utils import ExponentialBackoffHelper
# Create a custom backoff helper
backoff = ExponentialBackoffHelper(backoff_factor=2)
# Get backoff time for each attempt
wait_time = backoff.get_backoff_time(attempt=1) # 2 seconds
wait_time = backoff.get_backoff_time(attempt=2) # 4 seconds
wait_time = backoff.get_backoff_time(attempt=3) # 8 seconds
The auto-throttling mechanism automatically adjusts request delays based on response times and success rates, ensuring respectful scraping.
📋 Dependencies
requests- HTTP requests for synchronous scrapingaiohttp- Asynchronous HTTP requestsbeautifulsoup4- HTML parsing with CSS selectorslxml- Fast HTML parsing with XPath supportfake-useragent- User agent rotationopenpyxl- Excel file exportaiofiles- Asynchronous file operations
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file websleuth-1.0.0.tar.gz.
File metadata
- Download URL: websleuth-1.0.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f654da1efaecab66c5179586d0fb29c59b8e0c16556ec6ade611fe9a97c2d870
|
|
| MD5 |
cb8f48c51badf7ce97ad288e3cbd5231
|
|
| BLAKE2b-256 |
41a60d9061d0cbf9040e5e81e2ed99b0126d83ad970834b1de86ae7a99a824f3
|
File details
Details for the file websleuth-1.0.0-py3-none-any.whl.
File metadata
- Download URL: websleuth-1.0.0-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b12274106c27a6d8c553c295564997e3c39b71e00351d7d14cc1bd2282941b23
|
|
| MD5 |
31cd8bb6112a20eb4ad8fac736146e2a
|
|
| BLAKE2b-256 |
2737596d5cbb53277f69f32ee2e3e459c2f765ac7b8f028cfcfe4e6ed1ac01a0
|