# Changelog of Malt Profiles Scraper by query (`shoya/malt-profile-scraper`) Actor

- **URL**: https://apify.com/shoya/malt-profile-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/shoya/malt-profile-scraper.md

## Changelog

### v3.2.0 (2026-01-11)

#### Bio & Meta Tags

- **`includeFullBio`** : Visite chaque page de profil pour extraire la bio complète
  - Cherche dans : `#biography`, `.profile-about`, section "Présentation"
  - Fallback sur les paragraphes longs (>100 chars)
- **`includeMetaTags`** : Extrait les meta tags SEO de chaque profil
  - `meta_title` : Titre de la page
  - `meta_description` : Meta description
  - `og_tags` : Open Graph (og:title, og:image, etc.)
  - `twitter_tags` : Twitter Cards

#### Données enrichies (quand bio/meta activés)

- TJM extrait de la page profil (si absent de la recherche)
- Skills complets depuis la page profil
- `reviews_count` : Nombre d'avis
- `completed_projects` : Missions réalisées

#### Note

Activer ces options augmente le temps de scraping (~1-2s par profil) car chaque page est visitée individuellement.

***

### v3.1.1 (2026-01-11)

#### Retry & Resilience

- **Session init avec retry** : 3 tentatives avec délais progressifs (2-6s) en cas d'échec de connexion proxy
- **Retry sur 403** : 2 tentatives automatiques avec délai de 3-6s si anti-bot détecté
- **Retry sur 429** : 2 tentatives avec délai plus long (10-20s) si rate-limited

***

### v3.1.0 (2026-01-11)

#### Approche Hybride Multi-Méthodes

Remplacement de l'approche API-only (qui retournait 404) par une extraction multi-méthodes :

| Méthode | Description |
|---------|-------------|
| **1. HTML DOM** | Sélecteurs CSS : `a[href*="/profile/"]`, `.profile-card`, etc. |
| **2. Nuxt Data** | Extraction du script `__NUXT_DATA__` (Nuxt 3 format) |
| **3. Script JSON** | Regex pour trouver des arrays JSON dans les scripts |
| **4. URL Regex** | Fallback : extraction des slugs `/profile/xxx` dans le HTML |

#### Logs améliorés

- Affichage de la méthode d'extraction utilisée
- Diagnostic détaillé en cas d'échec (body snippet, détection immersion/Cloudflare)

***

### v3.0.0 (2026-01-11)

#### Tentative API directe (abandonnée)

- Utilisation de l'endpoint `/search/api/profiles/v2`
- **Problème** : Endpoint retourne 404 - n'existe plus ou a changé

***

### v2.0.0 (version initiale)

#### Problèmes identifiés

- **Mode Immersion** : Le proxy résidentiel déclenchait un mode "immersion" de Malt
- **Pas de profils dans le HTML** : Les données étaient chargées dynamiquement via JS
- **Sélecteur obsolète** : `a.profile-card` ne matchait plus

#### Stack technique

- `curl_cffi` avec impersonation Chrome 124
- `BeautifulSoup` pour le parsing HTML
- Proxy résidentiel français recommandé

***

### Configuration requise

```json
{
  "queries": ["n8n", "WordPress"],
  "maxPages": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "FR"
  }
}
```

### Notes techniques

#### Pourquoi curl\_cffi ?

- Émule le fingerprint TLS de Chrome 124
- Plus léger que Playwright/Puppeteer
- Évite la détection anti-bot basée sur le fingerprint

#### Ordre des méthodes d'extraction

1. On essaie d'abord le DOM (plus fiable si disponible)
2. Puis Nuxt Data (données structurées)
3. Puis extraction JSON des scripts
4. Enfin regex sur les URLs (fallback)

#### Gestion des erreurs proxy

- Erreur 595 = tunnel proxy failed
- Solution : retry avec délai pour laisser le proxy se stabiliser
