# 🕷️ SYSTEM SCRAPING & AI ANALYSIS

**System do automatycznego pobierania treści ze stron WWW firm i analizy AI**

**Data utworzenia:** 2025-11-27
**Status:** Gotowy do użycia
**Autor:** Norda Biznes Development Team

---

## 📋 SPIS TREŚCI

1. [Opis Systemu](#opis-systemu)
2. [Architektura](#architektura)
3. [Instalacja](#instalacja)
4. [Użycie](#użycie)
5. [Baza Danych](#baza-danych)
6. [Przykłady](#przykłady)
7. [FAQ](#faq)

---

## 🎯 OPIS SYSTEMU

System automatycznie:
1. **Pobiera treści** ze stron WWW firm (alfabetycznie)
2. **Zapisuje do bazy** - surowy HTML, tekst, metadata
3. **Analizuje AI** (Google Gemini) - kategoryzacja, usługi, insights
4. **Aktualizuje dane** firm na podstawie analizy

### Korzyści:
- ✅ Automatyczna aktualizacja opisów firm
- ✅ AI-driven kategoryzacja
- ✅ Ekstrakcja danych kontaktowych
- ✅ Identyfikacja usług i kompetencji
- ✅ Analiza rynku docelowego

---

## 🏗️ ARCHITEKTURA

```
┌─────────────────┐
│  80 firm WWW    │
│  (alfabetycznie)│
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────────┐
│         WebsiteScraper                  │
│  • requests + BeautifulSoup             │
│  • Ekstrakcja: HTML, tekst, metadata    │
│  • Email/telefon detection              │
│  • Social media links                   │
└────────┬────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────┐
│   PostgreSQL Database                   │
│  • company_website_content (surowe)     │
│  • company_ai_insights (AI)             │
└────────┬────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────┐
│         AIAnalyzer                      │
│  • Google Gemini 2.0 Flash              │
│  • Podsumowanie biznesowe               │
│  • Klasyfikacja kategorii               │
│  • Lista usług                          │
│  • Unique Selling Points                │
└─────────────────────────────────────────┘
```

---

## 📦 INSTALACJA

### 1. Wymagania Python:

```bash
pip install requests beautifulsoup4 psycopg2-binary google-generativeai
```

### 2. Utworzenie schematu bazy danych:

```bash
# Na serwerze NORDABIZ-01
ssh root@10.22.68.249

# Wykonaj SQL schema
su - postgres -c "psql nordabiz -f /path/to/create_website_scraping_schema.sql"
```

### 3. Konfiguracja API:

```bash
# Ustaw klucz Gemini API
export GOOGLE_GEMINI_API_KEY="twoj_klucz_api"
```

### 4. Uprawnienia:

```sql
-- Już zawarte w schema, ale sprawdź:
GRANT SELECT, INSERT, UPDATE, DELETE ON company_website_content TO nordabiz_app;
GRANT SELECT, INSERT, UPDATE, DELETE ON company_ai_insights TO nordabiz_app;
```

---

## 🚀 UŻYCIE

### Uruchomienie pełnego scrapingu:

```bash
python3 scrape_websites_ai.py
```

### Co się dzieje:

1. **Połączenie z bazą** - pobiera listę firm z websites (alfabetycznie)
2. **Scraping** - każda firma:
   - GET request do strony WWW
   - Ekstrakcja HTML, tekstu, metadanych
   - Wykrywanie emaili, telefonów
   - Social media links
   - Zapis do `company_website_content`
3. **AI Analysis** - dla każdej firmy:
   - Gemini 2.0 Flash analizuje treść
   - Generuje: podsumowanie, lista usług, kategoria
   - Zapis do `company_ai_insights`
4. **Rate limiting** - 10s między requestami (szacunek: ~13 min dla 80 firm)

### Logi:

```bash
# Real-time
tail -f /tmp/website_scraping.log

# Podsumowanie
grep "✓\|✗" /tmp/website_scraping.log
```

---

## 💾 BAZA DANYCH

### Tabela: `company_website_content`

Przechowuje surowe dane ze scrapingu:

| Kolumna | Typ | Opis |
|---------|-----|------|
| `id` | SERIAL | Primary key |
| `company_id` | INTEGER | FK do companies |
| `scraped_at` | TIMESTAMP | Data scrapingu |
| `url` | VARCHAR(500) | URL strony |
| `http_status` | INTEGER | Status HTTP (200, 404, etc) |
| `raw_html` | TEXT | Pełny HTML (max 50k) |
| `raw_text` | TEXT | Tekst bez tagów (max 30k) |
| `page_title` | VARCHAR(500) | Tytuł strony |
| `meta_description` | TEXT | Meta description |
| `main_content` | TEXT | Główna treść (bez menu/stopki) |
| `email_addresses` | TEXT[] | Znalezione emaile |
| `phone_numbers` | TEXT[] | Znalezione telefony |
| `social_media` | JSONB | Linki social media |
| `word_count` | INTEGER | Liczba słów |
| `processing_status` | VARCHAR(20) | pending/completed/failed |

### Tabela: `company_ai_insights`

Wyniki analizy AI:

| Kolumna | Typ | Opis |
|---------|-----|------|
| `id` | SERIAL | Primary key |
| `company_id` | INTEGER | FK do companies |
| `content_id` | INTEGER | FK do website_content |
| `business_summary` | TEXT | Podsumowanie (2-3 zdania) |
| `services_list` | TEXT[] | Lista usług |
| `target_market` | TEXT | Rynek docelowy |
| `unique_selling_points` | TEXT[] | USP |
| `company_values` | TEXT[] | Wartości firmy |
| `certifications` | TEXT[] | Certyfikaty, nagrody |
| `suggested_category` | VARCHAR(100) | Sugerowana kategoria |
| `category_confidence` | DECIMAL(3,2) | Pewność (0.00-1.00) |
| `industry_tags` | TEXT[] | Tagi branżowe |
| `ai_confidence_score` | DECIMAL(3,2) | Ogólna pewność AI |
| `processing_time_ms` | INTEGER | Czas przetwarzania |
| `analyzed_at` | TIMESTAMP | Data analizy |

### View: `company_website_summary`

Szybki podgląd statusu:

```sql
SELECT * FROM company_website_summary
WHERE scraping_status = 'pending'
ORDER BY name;
```

---

## 📊 PRZYKŁADY

### 1. Sprawdź status scrapingu:

```sql
SELECT
    scraping_status,
    COUNT(*) as liczba_firm
FROM company_website_summary
GROUP BY scraping_status;
```

**Oczekiwany wynik:**
```
 scraping_status | liczba_firm
-----------------+-------------
 scraped         | 75
 pending         | 5
 no_website      | 0
```

### 2. Firmy z najwyższą pewnością AI:

```sql
SELECT
    c.name,
    ai.suggested_category,
    ai.category_confidence,
    ai.ai_confidence_score
FROM company_ai_insights ai
JOIN companies c ON ai.company_id = c.id
WHERE ai.ai_confidence_score > 0.9
ORDER BY ai.ai_confidence_score DESC
LIMIT 10;
```

### 3. Firmy wymagające weryfikacji (niska pewność):

```sql
SELECT
    c.name,
    cat.name as current_category,
    ai.suggested_category,
    ai.category_confidence
FROM company_ai_insights ai
JOIN companies c ON ai.company_id = c.id
LEFT JOIN categories cat ON c.category_id = cat.id
WHERE ai.category_confidence < 0.7
ORDER BY ai.category_confidence ASC;
```

### 4. Ekstrakcja danych kontaktowych:

```sql
SELECT
    c.name,
    c.email as current_email,
    wc.email_addresses as found_emails,
    c.phone as current_phone,
    wc.phone_numbers as found_phones
FROM company_website_content wc
JOIN companies c ON wc.company_id = c.id
WHERE array_length(wc.email_addresses, 1) > 0
   OR array_length(wc.phone_numbers, 1) > 0;
```

### 5. Top usługi oferowane:

```sql
SELECT
    unnest(services_list) as usluga,
    COUNT(*) as liczba_firm
FROM company_ai_insights
WHERE services_list IS NOT NULL
GROUP BY usluga
ORDER BY liczba_firm DESC
LIMIT 20;
```

---

## ⚙️ KONFIGURACJA

### Dostosowanie rate limiting:

W pliku `scrape_websites_ai.py`:

```python
SCRAPER_CONFIG = {
    'timeout': 30,              # Timeout dla requestów
    'rate_limit_delay': 10,     # Sekundy między firmami
    'user_agent': '...'         # User-Agent
}
```

### Limit tekstów:

```python
'raw_html': response.text[:50000],  # Max 50k znaków
'raw_text': raw_text[:30000],       # Max 30k znaków
'main_content': main_content[:20000] # Max 20k znaków
```

### Model AI:

```python
self.model = genai.GenerativeModel('gemini-2.0-flash-exp')
# Alternatywy:
# - 'gemini-2.5-flash' (nowszy)
# - 'gemini-2.5-pro' (dokładniejszy, droższy)
```

---

## 🛡️ BEZPIECZEŃSTWO & ETYKA

### Rate Limiting:
- ✅ 10 sekund między requestami (domyślnie)
- ✅ Szanuje przepustowość serwerów

### Robots.txt:
⚠️ **TODO:** Dodać sprawdzanie robots.txt przed scrapingiem

### User-Agent:
- Identyfikuje się jako "NordaBizBot/1.0"
- Transparentne dla administratorów stron

### Dane osobowe:
- Emaile/telefony tylko te publicznie dostępne na stronach
- RODO: dane biznesowe (nie osoby fizyczne)

---

## 📈 WYDAJNOŚĆ

### Szacowany czas (80 firm):

```
80 firm × 10s delay = 800s = ~13 minut
+ scraping time (~5s/firma) = 400s
+ AI analysis (~3s/firma) = 240s
──────────────────────────────────
TOTAL: ~25 minut dla pełnego cyklu
```

### Koszty AI (Gemini):

```
80 firm × ~2000 tokenów input = 160k tokenów
80 firm × ~500 tokenów output = 40k tokenów

Free tier: 200 req/dzień ✅
Koszt (paid): ~$0.02 dla 80 firm
```

---

## 🔄 AKTUALIZACJE

### Re-scraping:

```sql
-- Usuń stare dane (opcjonalne)
DELETE FROM company_website_content
WHERE scraped_at < NOW() - INTERVAL '30 days';

-- Uruchom ponownie scraper
python3 scrape_websites_ai.py
```

### Automatyzacja (cron):

```bash
# Co miesiąc o 2:00 w nocy
0 2 1 * * cd /var/www/nordabiznes && python3 scrape_websites_ai.py
```

---

## ❓ FAQ

### Q: Co jeśli strona zwróci 404?
A: Skrypt loguje błąd i przechodzi dalej. Status HTTP zapisywany w bazie.

### Q: Jak obsługiwane są JavaScript-heavy strony?
A: **requests+BeautifulSoup** nie renderuje JS. Dla SPA użyj Playwright:
```python
# TODO: Implementacja Playwright dla JS websites
```

### Q: Co z CAPTCHA?
A: Większość stron firm B2B nie ma CAPTCHA. Jeśli wystąpi - manual bypass.

### Q: Jak długo dane są ważne?
A: Zalecany re-scraping: co 1-3 miesiące.

### Q: Co jeśli AI się pomyli?
A: Sprawdź `category_confidence`. Niska pewność (<0.7) = manual review.

---

## 📞 WSPARCIE

**Logi:** `/tmp/website_scraping.log`

**Baza danych:** `nordabiz@10.22.68.249`

**Dokumentacja:** Ten plik + komentarze w kodzie

---

## ✅ CHECKLIST WDROŻENIA

- [ ] Utworzono schemat bazy danych
- [ ] Uprawnienia dla nordabiz_app
- [ ] Zainstalowano biblioteki Python
- [ ] Ustawiono GOOGLE_GEMINI_API_KEY
- [ ] Przetestowano na 5 firmach
- [ ] Uruchomiono pełny scraping (80 firm)
- [ ] Zweryfikowano wyniki w bazie
- [ ] Opcjonalnie: Utworzono cron job

---

**Status:** ✅ Gotowy do użycia
**Ostatnia aktualizacja:** 2025-11-27