Affiliation Amazon et contenu dupliqué : la parade

Honnêtement, la technique n’est pas novatrice mais j’ai simplement voulu la mettre à plat suite à des commentaires que j’ai reçu sur certains de mes MFA. J’ai des sites qui fonctionnent avec Amazon. L’affiliation Amazon est simple à mettre en place, on a accès à tous via l’API. Le point négatif est la description du produit qu’on souhaite vendre. Elle est dupliquée et il faut la plupart du temps la retravailler.

Il y a 3 façons de faire pour remédier au problème :

  • soit vous rédigez simplement une nouvelle description : demande du temps, du travail, des recherches (un résumé de livre, ça ne s’invente pas). La qualité est bonne mais ce n’est pas gérable si vous avez une grosse boutique qui se met à jour quotidiennement.
  • soit vous développez un masterspin avec les différentes variables qui sont à votre disposition (titre du livre, nombre de page, édition, auteurs, …). Là, la qualité est nettement moins bonne et ce n’est pas du tout vendeur. Que vont pensez les visiteurs qui seront confronté à un texte de piètre qualité ? Vous allez les perdre.
  • la dernière façon et c’est celle que je vais approfondir ici est de créer une image transparente à partir de la description du produit. Certes il n’y a pas de contenu sur la page et donc elle rankera moins bien. Mais j’accompagne l’image de 2 choses. En premier lieu, la liste des caractéristiques du livres (nombre de pages, prix, …) ainsi qu’un petit texte spinné unique en bas d’article (donc moins visible) pour donner à manger aux robots.

Donc en fait, l’architecture de ma page ressemblerait à ça : en jaune, notre belle description scrapée

Comment faire ?

Il vous faudra un fichier PHP pour générer l’image, un dossier cache pour stocker les descriptions des produits, et une page HTML pour appeler le fichier PHP.
Nous allons partir sur une page HTML toute simple avec un petit contenu, le titre du produit et l’image de la description.

<!DOCTYPE html>
<html>
<head>
    <title>Produit Amazon</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <style type="text/css">
        body {
            background: #F9F9F9 none;
            margin: 0;
            padding: 0;
            font-family: Calibri;
            font-size: 11pt;
        }

        div {
            width: 700px;
            margin: 50px auto;
            background: white none;
            -webkit-box-shadow: 0px 0px 3px 3px #888;
            box-shadow: 0px 0px 3px 3px #888;
            -webkit-border-radius: 3px;
            border-radius: 3px;
            padding: 40px;
        }

        p {
            width: 600px;
            margin: 0 auto 20px;
        }
    </style>
</head>
<body>
    <div>
        <h1>Nom du produit</h1>
        <center><img src="image.php?i=2746635208" /></center>
        <p>Description spinné de moins bonne qualité plus bas dans la page et donc moins visible pour le visiteur...</p>
    </div>
</body>
</html>

Le fichier PHP doit s’appeler image.php et se mettre au même niveau que votre fichier (dons mon exemple bien entendu). Celui-ci va récupérer la description du produit qui lui est passé en paramètre (cf l’image du fichier HTML) puis va vérifier si la description du produit est déjà en cache. Si elle est en cache, il va utiliser celle-ci, sinon, il va la scraper sur Amazon.

Je pars du principe qu’une image sur un fond transparent passe sur tous les sites mais j’ai laissé en commentaire le code permettant d’avoir un fond de couleur ainsi qu’une bordure. Vous pouvez également modifier la police d’écriture sur l’image mais vous devez lui passer en paramètre le fichier ttf de votre police. Je suis parti sur du Calibri.

Image.php :

<?php

    if ($_GET['i']) {
        $get = htmlentities($_GET['i']);
        if (file_exists("cache/" . md5($get) . ".txt")) {
            $fh = fopen("cache/" . md5($get) . ".txt", 'r');
            $ww = fread($fh, filesize("cache/" . md5($get) . ".txt"));
            fclose($fh);
        } else {
            require_once('simple_html_dom.php');
            $url = "http://www.amazon.fr/dp/" . $get . "/";
            $html = file_get_html($url);
            foreach ($html->find('#postBodyPS') as $content) {
                $txt = substr($content->find('div', 0)->plaintext, 0, 500) . "...";
                $ww = wordwrap($txt, 100, "\n", true); // nombre de caractères après lesquels il faut sauter des lignes
                break;
            }
            $fh = fopen("cache/" . md5($get) . ".txt", 'w') or die("pb avec le fichier");
            fwrite($fh, $ww);
            fclose($fh);
        }
    }

    header('Content-Type: image/png');

    $img = imagecreatetruecolor(600, 150);
    $bg = imagecolorallocate($img, 0, 0, 0);

    imagecolortransparent($img, $bg); // image transparente

    $font = imagecolorallocate($img, 0x33, 0x33, 0x33);
    imagettftext($img, 11, 0, 0, 12, $font, './calibri.ttf', $ww); // configurez votre police d'écriture

    imagepng($img);

?>

Edit 22/10 – Voici une 2ème version plus adaptée à Amazon avec correction de quelques bugs :

<?php

    if ($_GET['i']) {
        $get = htmlentities($_GET['i']);
        if (file_exists("cache/" . md5($get) . ".txt") && false) {
            $fh = @fopen("cache/" . md5($get) . ".txt", 'r');
            $ww = @fread($fh, filesize("cache/" . md5($get) . ".txt"));
            @fclose($fh);
            if (strlen($ww) < 10) {
                $ww = getWW($get);
            }
        } else {
            $ww = getWW($get);
        }
    }

    function getWW($get)
    {
        $ww = "";
        require_once('simple_html_dom.php');
        $url = "http://www.amazon.fr/dp/" . $get . "/";
        $html = file_get_html($url);
        foreach ($html->find('#postBodyPS') as $content) {
            $ww = setWW($content->find('div', 0)->plaintext);
            break;
        }
        if (strlen($ww) < 10) {
            foreach ($html->find('#productDescription') as $content) {
                $ww = setWW($content->find('div.productDescriptionWrapper', 0)->plaintext);
                break;
            }
        }
        if (strlen($ww) < 10) {
            $ww = "Aucune description disponible.";
        }
        $fh = @fopen("cache/" . md5($get) . ".txt", 'w') or die("pb avec le fichier");
        @fwrite($fh, $ww);
        @fclose($fh);
        return $ww;
    }

    function setWW($txt)
    {
        $txt = neat_trim($txt, 500);
        return trim(str_replace('’', '\'', wordwrap($txt, 95, "\n", true)));
        // nombre de caractères après lesquels il faut sauter des lignes
    }

    function neat_trim($str, $n, $delim = '...')
    {
        $len = strlen($str);
        if ($len > $n) {
            return preg_replace(' / \s +?(\S +) ? $/', '', substr($str, 0, $n)) . $delim;
        } else {
            return $str;
        }
    }

    header('Content - Type: image / png');

    $img = imagecreatetruecolor(555, 180);
    $bg = imagecolorallocate($img, 0, 0, 0);

    imagecolortransparent($img, $bg); // image transparente

    $font = imagecolorallocate($img, 0x33, 0x33, 0x33);
    imagettftext($img, 11, 0, 0, 12, $font, ' ./calibri . ttf', $ww); // configurez votre police d'écriture

    imagepng($img);

?>

Résultat :

resultat amazon

Le script est perfectible mais il vous donne les bases pour avoir une description propre.

Et vous, quels sont vos techniques pour palier au contenu dupliqué de vos régies d’affiliation préférée ?

xSpin : un créateur de spin polymorphe
Générer du contenu grâce à Youtube et à la transcription interactive

14 Comments on “Affiliation Amazon et contenu dupliqué : la parade”

  1. Bonjour,
    Vous dites que cette technique est pas novatrice, mais pour moi elle l’est et je la trouve géniale. J’ai un petit site en affiliation avec Amazon et depuis le début je me tape tout à la main et je commençais à en avoir marre. Donc là c’est une astuce qui tombe du ciel pour moi, je vais demander un coup de main à un ami pour la partie code parce que c’est pas trop mon truc et en avant! :-)

  2. Je trouve aussi votre technique géniale !! Je me demande même pourquoi je n’y avais pas pensé avant vous, vous êtes un génie de l’affiliation !!! Cela m’ouvre de nouvelles perspectives pour créer des sites satellites sans trop d’éfforts de rédaction ( ce qui était jusqu’à présent mon plus gros frein !)

  3. Sympa comme astuce, je partirais plutôt sur un spin cloaké histoire d’avoir la description propre pour l’utilisateur et le contenu un peu plus crade uniquement pour les moteurs.

    1. Mon problème venait du fait que la boutique contient plus de 12k articles. Un spin de qualité pour générer autant de variantes de textes sans trop de contenu dupliqué est difficile. J’étais parti sur ça au début mais au final, ce n’était pas top.

  4. Merci pour l’astuce et le bout de code. Notons qu’avec les CMS majeur du type SPIP (pour ce que je connais le mieux) les filtres permettent d’une part de parser les flux amazon et aussi de générer automatiquement des images avec les textes, titres etc …

  5. Il y a aussi le !# et _escaped_fragment_, ou tout simplement chargement de content en javascript… intelligemment :p

  6. Très sympa ! mais j’ai une question, Amazon dit qu’il vaut mieux ne pas « cacher » les produits en BDD pour éviter les problèmes de prix et de dispo, mais est ce vraiment gérable avec un grand nombre d’article au niveau rapidité de chargement surtout qu’il me semble que l’API à une limite de requête par heure non ?

    1. En fait, ce script n’utilise pas l’API mais il va récupérer le contenu du produit directement sur sa page. Il est vrai que vous avez une limite de requête par heure / jour mais il ne faut pas faire l’appel à chaque fois (problème de performances, vitesse, etc.). Il vaut mettre le résultat de la requête via API en cache ou dans le contenu de la page (WordPress par exemple).
      Par ailleurs, il est vrai que Amazon ne conseille pas de mettre les produits en base de donnée mais vous pouvez avoir différentes solutions pour vous positionner sur les produits en question.

  7. Vraiment géniale ta technique, j’ai testé en direct pour avoir un rendu, car comme pour pizzatoy, l’url ne fonctionne pas pour moi …

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *