Files
wp-statpress-analyze/README.md
T
2026-09-30 21:05:53 +08:00

322 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IP Geo Visitor Analysis Toolkit
A set of three Python scripts to process large-scale web visitor logs from MySQL, enrich them with geographic data, detect bots, and generate monthly analytics reports.
---
## Overview
| Script | Purpose |
|---|---|
| `ip_geo_report.py` | Read visitor records from MySQL, resolve IPs to countries, export daily visit counts per country |
| `analyze.py` | Read the CSV output from `ip_geo_report.py` and generate monthly visit stats with MoM changes and charts |
| `bot_analyzer.py` | Select records from a date range and score each visit to classify as human, bot, or suspicious |
---
## Requirements
- Python 3.8+
- MySQL database with visitor records
- ipinfo `bundle_location_lite.mmdb` (free, download from [ipinfo.io](https://ipinfo.io/account/data-downloads))
---
## Installation
```bash
# Clone or copy scripts to your project folder
mkdir visitor-analysis && cd visitor-analysis
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # Linux / macOS
# venv\Scripts\activate # Windows
# Install dependencies
pip install mysql-connector-python maxminddb matplotlib
```
---
## Project Structure
```
visitor-analysis/
├── venv/ ← virtual environment (do not commit)
├── bundle_location_lite.mmdb ← ipinfo offline GeoIP database
├── ip_geo_report.py ← Script 1: IP → Country report
├── analyze.py ← Script 2: Monthly analytics + charts
├── bot_analyzer.py ← Script 3: Bot detection
├── requirements.txt
├── README.md
├── cache/ ← Auto-created: LRU disk cache + checkpoints
└── report/ ← Auto-created: CSV output from Script 1
```
---
## Script 1 — `ip_geo_report.py`
Reads all visitor records from MySQL in batches, resolves each IP address to a country using the ipinfo mmdb database, and produces a CSV report of daily visit counts per country.
### Features
- Batch processing with cursor-based pagination (handles 100M+ rows)
- Two-level cache: LRU memory (100k IPs) + disk shelve spillover
- Resume from checkpoint on crash or interruption
- ipinfo mmdb offline lookup → ipinfo API fallback
- Bot/attack filtering before GeoIP lookup
### Configuration
Edit the top section of `ip_geo_report.py`:
```python
DB_CONFIG = {
"host": "localhost",
"user": "your_user",
"password": "your_password",
"database": "your_database",
}
TABLE_NAME = "visitors" # your table name
IP_COLUMN = "ip" # IP address column
DATE_COLUMN = "visit_date" # DATE or DATETIME column
UA_COLUMN = "user_agent" # set None if not available
PATH_COLUMN = "path" # set None if not available
GEOIP_DB_PATH = "./bundle_location_lite.mmdb"
IPINFO_TOKEN = "" # optional API fallback token
BATCH_SIZE = 50_000
LRU_MAX_SIZE = 100_000
```
### Usage
```bash
source venv/bin/activate
python3 ip_geo_report.py
```
If interrupted, simply re-run — it resumes from the last checkpoint automatically.
### Output
```
report/
├── report_YYYY-MM-DD.csv ← Country, Date, Visit Count
└── summary_YYYY-MM-DD.csv ← Country, Total Visits (sorted)
```
---
## Script 2 — `analyze.py`
Reads the CSV output from `ip_geo_report.py` and generates monthly analytics including MoM (Month-over-Month) percentage changes and a 4-panel visualization chart.
### Features
- Auto-detects latest `report_*.csv` in `./report/`
- Handles multiple date formats (`YYYY-MM-DD`, `YYYYMMDD`, `YYYY/MM/DD`)
- Monthly visit totals with MoM % change
- Monthly unique country counts with MoM % change
- Top N countries per month
- 4-panel PNG chart (bar charts + MoM line + stacked country chart)
### Usage
```bash
# Auto-detect latest report
python3 analyze.py
# Specify input file
python3 analyze.py --input ./report/report_2026-09-27.csv
# Custom output dir and top N countries
python3 analyze.py \
--input ./report/report_2026-09-27.csv \
--output ./analysis \
--top 10
```
### Arguments
| Argument | Default | Description |
|---|---|---|
| `--input`, `-i` | latest in `./report/` | Path to input CSV |
| `--output`, `-o` | `./analysis/` | Output directory |
| `--top`, `-n` | `10` | Top N countries per month |
### Output
```
analysis/
├── monthly_summary_YYYYMMDD.csv ← Month, Visits, MoM%, Countries, MoM%
├── top_countries_YYYYMMDD.csv ← Month, Rank, Country, Visits, %
└── analysis_chart_YYYYMMDD.png ← 4-panel visualization chart
```
### Chart Panels
| Panel | Content |
|---|---|
| Top-left | Monthly total visits bar + MoM % line |
| Top-right | Monthly unique countries bar + MoM % line |
| Bottom-left | MoM % comparison line chart with +/- shading |
| Bottom-right | Stacked bar — top 5 countries (last 6 months) |
---
## Script 3 — `bot_analyzer.py`
Selects visitor records from a MySQL date range and scores each visit across multiple signals to classify it as human, bot, or suspicious.
### Features
- Two-pass processing: frequency counting then per-record scoring
- Windowed frequency detection (per day, per hour, traffic ratio)
- Pattern-based signals: user agent, request path, IP range
- Outputs three separate CSVs: human / bot / suspicious
- Detailed summary with top high-frequency IPs
### Scoring Rules
| Signal | Score | Trigger |
|---|---|---|
| Invalid / Private IP | +10 | Reserved IP ranges (RFC 1918 etc.) |
| Bot User Agent | +8 | googlebot, scrapers, crawlers |
| High Freq Per Hour | +8 | IP hits > threshold in single hour |
| Attack Path | +9 | SQLi, shells, scanner paths |
| Tool User Agent | +7 | curl, wget, python, selenium |
| No User Agent | +7 | Empty or missing UA |
| High Freq Per Day | +7 | IP hits > threshold in single day |
| Old IE Browser | +5 | IE 6/7/8 (commonly spoofed) |
| High Traffic Ratio | +5 | IP > 1% of all traffic in range |
| Suspicious Combo | +4 | Old UA + attack path together |
| Empty Path | +3 | Request path is blank or just `/` |
**Classification thresholds:**
| Score | Classification |
|---|---|
| 0 – 2 | ✅ Human |
| 3 – 4 | ⚠️ Suspicious |
| 5+ | 🤖 Bot |
### Configuration
```python
HIGH_FREQ_PER_DAY = 100 # flag if IP hits > N times in a single day
HIGH_FREQ_PER_HOUR = 30 # flag if IP hits > N times in a single hour
HIGH_FREQ_TOTAL_RATIO = 0.01 # flag if IP > 1% of total traffic in range
BOT_SCORE_THRESHOLD = 5 # score >= this = bot
SUSPICIOUS_THRESHOLD = 3 # score >= this = suspicious
```
### Usage
```bash
# Basic usage
python3 bot_analyzer.py --start 2026-01-01 --end 2026-09-30
# Custom thresholds
python3 bot_analyzer.py \
--start 2026-01-01 \
--end 2026-09-30 \
--bot-threshold 5 \
--freq-per-day 100 \
--freq-per-hour 30 \
--freq-ratio 0.01 \
--output ./bot_analysis
```
### Arguments
| Argument | Default | Description |
|---|---|---|
| `--start`, `-s` | required | Start date `YYYY-MM-DD` |
| `--end`, `-e` | required | End date `YYYY-MM-DD` |
| `--output`, `-o` | `./bot_analysis/` | Output directory |
| `--bot-threshold` | `5` | Minimum score to classify as bot |
| `--freq-per-day` | `100` | Max hits per day before flagging |
| `--freq-per-hour` | `30` | Max hits per hour before flagging |
| `--freq-ratio` | `0.01` | Max fraction of total traffic per IP |
### Output
```
bot_analysis/
├── human_DATERANGE_TIMESTAMP.csv ← Confirmed human visits
├── bot_DATERANGE_TIMESTAMP.csv ← Confirmed bot visits + score + reasons
├── suspicious_DATERANGE_TIMESTAMP.csv ← Borderline visits for manual review
└── summary_DATERANGE_TIMESTAMP.csv ← Stats, reason counts, top IPs
```
---
## Recommended Workflow
```
1. Run ip_geo_report.py
→ Processes all historical data
→ Outputs report/report_YYYY-MM-DD.csv
2. Run analyze.py
→ Reads the report CSV
→ Outputs monthly stats + chart
3. Run bot_analyzer.py --start YYYY-MM-DD --end YYYY-MM-DD
→ Focuses on a specific time window
→ Outputs human / bot / suspicious CSVs
```
---
## GeoIP Database Setup
1. Register for a free account at [https://ipinfo.io/signup](https://ipinfo.io/signup)
2. Go to [https://ipinfo.io/account/data-downloads](https://ipinfo.io/account/data-downloads)
3. Download **`bundle_location_lite.mmdb`**
4. Place it in the project root directory
The database provides: `country`, `country_code`, `continent`, `asn`, `as_name`, `as_domain`
---
## Database Table Requirements
Your MySQL visitor table should have at minimum:
| Column | Type | Required | Description |
|---|---|---|---|
| `id` | INT | ✅ Yes | Primary key for cursor pagination |
| `ip` | VARCHAR | ✅ Yes | Visitor IP address |
| `visit_date` | DATE / DATETIME | ✅ Yes | Visit timestamp |
| `user_agent` | VARCHAR | ⚠️ Optional | Browser user agent string |
| `path` | VARCHAR | ⚠️ Optional | Request path / URL |
> Set `UA_COLUMN = None` and `PATH_COLUMN = None` in scripts if those columns do not exist.
---
## requirements.txt
```
mysql-connector-python
maxminddb
matplotlib
```
Install with:
```bash
pip install -r requirements.txt
```
---
## Notes
- All scripts support resuming interrupted runs (Script 1 via checkpoint file, Script 3 via re-running with same date range)
- Cache files in `./cache/` persist between runs to avoid redundant GeoIP lookups
- Partial report data is saved every 10 batches to survive crashes
- Scripts are designed for Python 3.8+ and tested on Ubuntu 20.04