Conception et implémentation d'un collecteur de données Java pour les catalogues de boutiques Weidian

Analyse de l'écosystème de données e-commerce

Dans le secteur du commerce électronique, l'accès structuré aux données de catalogue est un levier stratégique pour l'analyse concurrentielle et le suivi des prix. Weidian, en tant que plateforme majeure de micro-commerce, héberge un volume massif de références produits. Bien que des API officielles existent, leurs contraintes d'accès et de quota poussent souvent les ingénieurs à concevoir des solutions de collecte de données (crawlers) personnalisées. Cet article détaille une approche robuste en Java pour automatiser l'extraction des informations produits d'une boutique Weidian.

Stack technique et architecture logicielle

Pour garantir une extraction efficace et maintenable, nous utilisons les composants suivants :

  • Client HTTP (Java 11+) : Utilisation de java.net.http.HttpClient pour la gestion des requêtes asynchrones et des en-têtes complexes.
  • Analyseur HTML : Jsoup, indispensable pour naviguer dans le DOM et extraire des données via des sélecteurs CSS.
  • Modélisation de données : Objets POJO pour structurer les attributs produits (nom, prix, images).

Architecture de la solution

Le processus est divisé en trois phases distinctes : la récupération de la page d'accueil de la boutique pour identifier les produits, l'itération sur les pages de détails, et enfin la persistance des données collectées.

1. Récupération du contenu source

L'utilisation de java.net.http permet de simuler un navigateur moderne pour contourner les filtrages basiques basés sur l'User-Agent.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class WeidianConnector {
    private final HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    public String fetchSource(String targetUrl) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(targetUrl))
                .header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36")
                .GET()
                .build();

        return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
    }
}

2. Extraction des liens produits

Une fois le HTML récupéré, nous isolons les identifiants uniques ou les URLs pointant vers les fiches produits.

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.util.stream.Collectors;
import java.util.List;

public class CatalogParser {
    public List<String> extractProductLinks(String html) {
        Document doc = Jsoup.parse(html);
        // Adaptation du sélecteur selon la structure DOM de Weidian
        Elements links = doc.select(".item-block a, .product-card-link");
        return links.stream()
                    .map(el -> el.attr("href"))
                    .filter(href -> !href.isEmpty())
                    .collect(Collectors.toList());
    }
}

3. Analyse des métadonnées produit

Chaque page produit est analysée pour en extraire les propriétés essentielles. Nous définissons une structure de données interne pour représenter le produit.

public class ProductInfo {
    private String title;
    private String price;
    private String thumbUrl;
    private String info;

    // Constructeur et getters
    public ProductInfo(String title, String price, String thumbUrl, String info) {
        this.title = title;
        this.price = price;
        this.thumbUrl = thumbUrl;
        this.info = info;
    }

    @Override
    public String toString() {
        return String.format("Produit: %s | Prix: %s", title, price);
    }
}

public class DetailExtractor {
    public ProductInfo processDetail(String html) {
        Document doc = Jsoup.parse(html);
        String name = doc.select(".product-title, h1").text();
        String val = doc.select(".current-price, .price-tag").text();
        String img = doc.select("img.main-image").attr("src");
        String desc = doc.select(".product-desc-content").text();
        
        return new ProductInfo(name, val, img, desc);
    }
}

Logique de contrôle principale

Le point d'entrée coordonne les différents modules pour transformer une URL de boutique en une liste d'objets exploitables.

import java.util.ArrayList;
import java.util.List;

public class ScraperEngine {
    public static void main(String[] args) {
        try {
            String shopUrl = "https://weidian.com/s/12345678";
            WeidianConnector connector = new WeidianConnector();
            CatalogParser catalogParser = new CatalogParser();
            DetailExtractor detailExtractor = new DetailExtractor();

            String shopHtml = connector.fetchSource(shopUrl);
            List<String> urls = catalogParser.extractProductLinks(shopHtml);
            List<ProductInfo> catalog = new ArrayList<>();

            for (String url : urls) {
                // Pause de sécurité pour éviter le bannissement d'IP
                Thread.sleep(1500);
                String detailHtml = connector.fetchSource(url);
                catalog.add(detailExtractor.processDetail(detailHtml));
            }

            catalog.forEach(System.out::println);
        } catch (Exception e) {
            System.err.println("Erreur lors de l'exécution : " + e.getMessage());
        }
    }
}

Considérations critiques et optimisation

Le développement d'un tel outil nécessite une attention particulière sur plusieurs points techniques :

  • Gestion du throttling : Les serveurs de Weidian peuvent limiter le trafic. L'implémentation de délais aléatoires entre les requêtes et l'utilisation de proxys tournants sont recommandées pour les volumes importants.
  • Évolution du DOM : Les sélecteurs CSS (.product-title, etc.) sont sujets à changement. Une couche d'abstraction ou un fichier de configuration pour les sélecteurs facilite la maintenance.
  • Conformité : Il est impératif de respecter le fichier robots.txt du domaine cible et de s'assurer que l'usage des données collectées est conforme aux réglementations locales sur la protection des données.
  • Performance : Pour les boutiques contenant des milliers de références, l'utilisation de CompletableFuture en Java permet d'exécuter les requêtes de manière asynchrone non bloquante, augmentant ainsi considérablement le débit.

Étiquettes: Java jsoup web-scraping e-commerce HttpClient

Publié le 16 juin à 21h10