Historical competitor price intelligence from Wayback Machine
Project description
PriceWatch ๐
Historical competitor price intelligence from the Internet Archive Wayback Machine.
Overview
PriceWatch is a production-ready tool that tracks competitor pricing over time by analyzing archived snapshots of their pricing pages. It provides multiple interfaces for different use cases:
- Python Library: Programmatic access for integration
- CLI Tool: Quick terminal-based analysis
- Streamlit Web App: Interactive, self-hosted web interface
Features
Multi-Stage Price Extraction
- Regex-based: Fast pattern matching for common price formats
- DOM parsing: Heuristic analysis of HTML structure
- LLM fallback: Local LLM (Ollama) for ambiguous cases
Flexible Sampling
- Quarterly, monthly, or annual snapshots
- Intelligent nearest-snapshot selection
- Configurable tolerance for date matching
Multiple Output Formats
- Interactive time-series charts (Plotly)
- Clean tabular views
- CSV export for spreadsheets
- Excel export with formatting and charts
Installation
Prerequisites
- Python 3.10+
- uv (recommended) or pip
Using uv (Recommended)
# Clone repository
git clone https://github.com/yourcompany/pricewatch.git
cd pricewatch
# Create virtual environment and install
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -e .
# Install optional dependencies
uv pip install -e ".[streamlit,export,llm]"
Using pip
pip install -e .
pip install -e ".[streamlit,export,llm]" # Optional features
Optional: Ollama for LLM Extraction
If you want LLM-assisted extraction:
- Install Ollama
- Pull a model:
ollama pull llama3.2 - Ensure Ollama is running:
ollama serve
Quick Start
CLI
Analyze a competitor's pricing page:
pricewatch analyze https://competitor.com/pricing
With options:
pricewatch analyze https://competitor.com/pricing \
--start-date 2022-01-01 \
--end-date 2024-12-31 \
--interval quarterly \
--export-csv results.csv \
--use-llm
List available snapshots:
pricewatch snapshots https://competitor.com/pricing
Streamlit App
Launch the web interface:
streamlit run streamlit_app/app.py
Then open http://localhost:8501 in your browser.
Python Library
from datetime import datetime, timedelta
from pricewatch import WaybackClient, SnapshotSampler, PriceExtractor
from pricewatch.core.models import PriceTimeSeries
# Initialize
client = WaybackClient()
sampler = SnapshotSampler(client)
extractor = PriceExtractor(use_llm=False)
# Get quarterly snapshots
url = "https://competitor.com/pricing"
start_date = datetime.now() - timedelta(days=730)
snapshots = sampler.get_quarterly_snapshots(url, start_date)
# Extract prices
price_snapshots = []
for snapshot in snapshots:
html = client.fetch_html(snapshot)
ps = extractor.extract_from_snapshot(snapshot, html)
price_snapshots.append(ps)
# Build time series
timeseries = PriceTimeSeries(
url=url,
snapshots=price_snapshots,
start_date=start_date,
end_date=datetime.now(),
total_snapshots=len(snapshots),
successful_extractions=sum(1 for ps in price_snapshots if ps.has_prices)
)
# Convert to DataFrame for analysis
df = timeseries.to_dataframe()
print(df)
# Export
from pricewatch.export.csv_export import CSVExporter
CSVExporter.export_timeseries(timeseries, Path("output.csv"))
CLI Commands
pricewatch analyze
Analyze historical pricing for a URL.
Arguments:
URL: Product/pricing page URL
Options:
--start-date YYYY-MM-DD: Start date (default: 2 years ago)--end-date YYYY-MM-DD: End date (default: today)--interval [monthly|quarterly|annual]: Sampling interval (default: quarterly)--use-llm / --no-llm: Enable LLM extraction (default: disabled)--llm-model TEXT: Ollama model name (default: llama3.2)--export-csv PATH: Export results to CSV--export-excel PATH: Export results to Excel--show-table / --no-table: Display results table (default: yes)
Examples:
# Basic analysis
pricewatch analyze https://example.com/pricing
# Export to CSV
pricewatch analyze https://example.com/pricing --export-csv prices.csv
# Monthly intervals with LLM
pricewatch analyze https://example.com/pricing \
--interval monthly \
--use-llm \
--llm-model llama3.2
pricewatch snapshots
List available Wayback Machine snapshots for a URL.
Arguments:
URL: Target URL
Example:
pricewatch snapshots https://example.com/pricing
Architecture
PriceWatch
โโโ Core Library (pricewatch/)
โ โโโ Wayback Client: CDX API + HTML fetching
โ โโโ Sampler: Quarterly/monthly/annual sampling
โ โโโ Extractor Pipeline:
โ โ โโโ Regex (fast, good precision)
โ โ โโโ DOM (structure-aware)
โ โ โโโ LLM (fallback for ambiguous pages)
โ โโโ Data Models: Pydantic schemas
โ
โโโ CLI (pricewatch/cli/)
โ โโโ Rich terminal interface
โ
โโโ Streamlit App (streamlit_app/)
โ โโโ Interactive web UI
โ
โโโ Export (pricewatch/export/)
โโโ CSV
โโโ Excel (with charts)
Configuration
Rate Limiting
The Wayback Client includes built-in rate limiting (0.5s between requests by default):
client = WaybackClient(rate_limit=1.0) # 1 second between requests
LLM Configuration
from pricewatch.extractors.llm_extractor import LLMPriceExtractor
extractor = LLMPriceExtractor(
ollama_model="llama3.2",
ollama_host="http://localhost:11434"
)
Data Models
ExtractedPrice
class ExtractedPrice(BaseModel):
value: float
currency: Currency # USD, EUR, GBP, etc.
price_type: PriceType # monthly, annual, one_time
tier_name: Optional[str] # "Professional", "Enterprise", etc.
raw_text: str
confidence: float # 0.0 to 1.0
extraction_method: ExtractionMethod # regex, dom, llm
PriceSnapshot
class PriceSnapshot(BaseModel):
snapshot: Snapshot
prices: List[ExtractedPrice]
html_length: int
extraction_time_ms: float
errors: List[str]
PriceTimeSeries
class PriceTimeSeries(BaseModel):
url: str
snapshots: List[PriceSnapshot]
start_date: datetime
end_date: datetime
total_snapshots: int
successful_extractions: int
def to_dataframe(self) -> pd.DataFrame:
"""Convert to pandas DataFrame"""
Assumptions & Limitations
Assumptions
- Wayback Machine Coverage: Assumes the target URL has been archived
- Price Display: Prices are displayed as text on the page (not in images/videos)
- USD Default: Defaults to USD when currency is ambiguous
- Quarterly Sampling: Best balance of coverage vs. API load
Limitations
- Wayback API Rate Limits: Built-in 0.5s delay between requests
- JavaScript-Heavy Sites: May miss dynamically loaded prices
- Paywalled Content: Cannot access content behind authentication
- Currency Conversion: No automatic exchange rate conversion (yet)
- LLM Availability: LLM extraction requires local Ollama installation
Known Issues
- Very old snapshots (pre-2010) may have inconsistent formatting
- Pages with complex React/Vue rendering may need LLM extraction
- Extremely high-frequency price changes (daily) may be missed with quarterly sampling
Future Extensions
High Priority
- Automated currency conversion using historical exchange rates
- Support for headless browser (Playwright/Selenium) for JS-heavy sites
- Competitor comparison dashboard (multiple URLs side-by-side)
- Price change alerts/notifications
Medium Priority
- API endpoint (FastAPI) for team-wide deployment
- Database storage (PostgreSQL) for historical data
- Scheduled jobs for automatic monitoring
- Advanced analytics (price change velocity, seasonality detection)
Nice to Have
- OCR for prices in images
- Multi-language support
- Screenshot capture of pricing pages
- Integration with business intelligence tools (Tableau, PowerBI)
Development
Running Tests
pytest tests/
Code Quality
# Format code
black pricewatch/
# Lint
ruff pricewatch/
# Type checking
mypy pricewatch/
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License - see LICENSE file for details
Support
- Issues: https://github.com/yourcompany/pricewatch/issues
- Internal wiki: [link to internal docs]
- Slack: #pricewatch-support
Acknowledgments
- Internet Archive Wayback Machine for providing historical web data
- Ollama for local LLM capabilities
Project details
Release history Release notifications | RSS feed
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 pricewatch-0.1.0.tar.gz.
File metadata
- Download URL: pricewatch-0.1.0.tar.gz
- Upload date:
- Size: 34.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cbfeb0d6f6f9dd9976a6103aa58d486daa38fd66e7e9c11def39be16997e938
|
|
| MD5 |
17cc331dc76b759d2e91592b2a220146
|
|
| BLAKE2b-256 |
47c6e36f533964c252e0e386f4189065d894557244de63420490522a48b77ae0
|
File details
Details for the file pricewatch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pricewatch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af378a35f02b77826ec2b5b00a06ec84ab696148772233877405fe9e34d3a856
|
|
| MD5 |
5a21e24ce5e6c8c124f906045a4645fd
|
|
| BLAKE2b-256 |
fcaf17c730ab614967d1859ded44306373ba1fa97d2d680de0f5d8735267fc22
|