Hintergrund

Der Listicle Generator: Wie ich dich automatisch geärgert habe

Gestern ist ein Listicle online gegangen, das bewusst dumm war. Warum? Es zeigt auf, dass Journalismus nicht zwingend von Menschen gemacht wird und dennoch effektiv sein kann. Denn ich habe das Listicle halbautomatisch generiert.

Du hast Listicles auch schon als dumm bezeichnet? Willkommen im Club. Du hast gestern mein Kabel-Listicle als dumm bezeichnet? Gut so, dann hast du erkannt, worum es geht. Denn Listicles sind dumm. Und ich zeige dir, wie dumm sie wirklich sind. Ich kann sie mittlerweile per Web App generieren. Halbautomatisch und fixfertig durchformatiert. Zeitersparnis nach einigen Stunden Development: Etwa eine Stunde pro Listicle.

Ich zeige dir, wie ich die Web App gebaut habe, was sie macht und wo ich sie noch weiter verbessern könnte.

  • Ratgeber

    Die besten 14 Kabel. Nummer 9 wird dich erstaunen // Update: 11.12.2018 08:00

    von Dominik Bärlocher

Warum sind Listicles so erfolgreich?

Aber aus Sicht eines Webportals, das gerne Visitors hat, sind Listicles sehr interessant. Denn sie haben ein paar Hebel, die immer ziehen.

  • Eine definierte Anzahl, die eine Form von Exklusivität vorgaukelt → «Die besten 14 Kabel»
  • Ein Aufreger, der deine Neugierde weckt → «Nummer 9 wird dich erstaunen»

Damit spreche ich im Text deine Neugierde wie auch deine Emotionen an. «Ich bin mir sicher, dass Nummer 9 total unbeeindruckend ist», denkst du dir vielleicht und klickst drauf. Du willst wissen, was Nummer 9 ist und ob die Nummer 9 tatsächlich so scheisse ist, wie du erwartest. Portale wie Buzzfeed haben sich durch Titel wie «Die besten 14 Kabel. Nummer 9 wird dich erstaunen» ein Millionenpublikum aufgebaut. Wie loyal diese Millionen sind, ist eigentlich egal. Sie sind auf der Seite, haben die Bildli angeschaut und sich gedacht «So ein Käse», haben aber die Werbung angeschaut und Impressions und somit Geld generiert.

Aus journalistischer Sicht sind Listicles noch dümmer als aus Lesersicht. Denn, was viele vergessen: Irgendwer muss den Kehricht auch noch schreiben. Die Chefetage bei digitec findet das Konzept Listicle mal mehr, mal weniger interessant und im Rahmen des SEO-optimierten Wortes «Kaufratgeber» stehen auch Listicles zur Diskussion. Da diese aber immer nach demselben Schema funktionieren habe ich das automatisiert. Ich mag zwar keine Lust auf stundenlanges manuelles Formatieren haben, aber auf viel längeres stundenlanges Programmieren schon.

Analyse eines Listicles

Damit ein Projekt wie mein sogenannter «Black Magic Listicle Generator» entstehen kann, müssen wir die Komponenten eines Listicles abstrahieren.

Wichtig ist die Erkenntnis, dass Listicles nicht gelesen werden wie ein Buch. Niemand interessiert sich für die Texte jenseits der Rangnummern und einer catchy Überschrift. Daher kann dieser Text vernachlässigt werden. Er muss aber da sein, damit Googles SEO-Algorithmen die Seite nach wie vor mögen und hoch rangieren.

Ein Listicle besteht aus folgenden Elementen, jetzt spezifisch auf digitec bezogen:

  • Titel des Artikels
  • Lead: Das ist der Text der gleich unter dem Titel etwas grösser steht.
  • Intro: Plusminus zwei Sätze, die zwischen Liste und Lead stehen, damit die SEO-Indizierung uns nicht abstraft, wenn wir von Lead direkt in einen Untertitel übergehen.
  • Zwischentitel: Das Ding, das die Nummern der Listicle Items vorgibt und auch noch etwas Text hat.
  • Ein Produktlisting
  • Freier Text: SEO-relevant, kann aber ohne jeglichen Inhalt und Bedeutung auskommen. Ideal für SEO-Wörter

Der Begriff SEO ist jetzt schon öfter gefallen. Hinter ihm versteckt sich mehr Religion als Wissenschaft, denn damit macht Google gutes Geld. Es geht darum, dass die Indizierung Googles dich besser mag. Welche Kriterien reinspielen, ist nicht genau bekannt, aber einige gängige Praktiken haben sich etabliert. So darf eine Überschrift 3 nicht einer Überschrift 2 übergeordnet sein. Versionen einzelner Wörter – Smartphones, Phones, Natel, Telefon, Mobiltelefon – sollen den Suchradius verbreitern, selbst wenn Google mittlerweile selbständig abstrahiert. Und so weiter. Es gibt in jedem Medienunternehmen Kräfte, die sich von SEO umgehend eine Million oder mehr unique organic visitors versprechen und daher muss alles sofort SEO-optimiert sein, egal wie schlecht der Text sich nachher liest.

Ein Eintrag im Listicle
Ein Eintrag im Listicle

Von mir aus.

Ein Listicle ist also etwas, das Maschinen gefällt, von Menschen aber nicht gelesen wird. Warum sollte das dann auch nicht eine Maschine schreiben?

JQuery to the Rescue

Ich programmiere dann und wann wieder gerne Web Apps, die einen recht spezifischen Dienst erledigen. Die haben eine Funktion, kein Error Handling und funktionieren in einem eng definierten Rahmen. Gut, ich bin der weltschlechteste Coder, aber einen dummen Listicle Generator kriege ich hin. Du auch.

Du brauchst:

  • Einen Texteditor wie Brackets
  • Ein fixfertiges CSS wie Materialize
  • Etwas HTML-Wissen
  • Etwas Wissen über JQuery
  • Die Fähigkeit, copypaste zu bedienen

Das Projekt, das wir anpacken, sieht zwar hübsch aus, kann aber mit «Quick and Dirty» recht gut beschrieben werden. Denn hinter den Kulissen wird alles etwas hacky wirken. Soll es auch, denn für Listicles lehnen wir uns nicht aus dem Fenster. Im Gegenteil, wir wollen so wenig wie möglich selbst machen.

Leg dir irgendwo auf einem Computer eine Ordnerstruktur an, die so aussieht:

root/
 ├── css/   
 │   └── styles.css
 ├── img/   
 │   ├── logo.png
 │   └── favicon.png
 └── index.html

Kurze Erklärung:

  • css/styles.css: Sonderfälle im Aussehen der Seite. Du brauchst die Datei, für den Fall, dass du Farben oder dergleichen anpassen willst
  • img/logo.png: Jede Seite braucht ein Logo (optional)
  • img/favicon.png: Jede Seite braucht ein Favicon (optional)
  • index.html: Hier geschieht die Hauptarbeit. Da wir quick and dirty arbeiten wird die nicht besonders hübsch codiert sein

Das HTML-Grundgerüst

Für dieses Projekt brauchen wir eigentlich nur die JavaScript Library JQuery, aber ich habe mir mal vor vielen Monden ein Grundgerüst für Web Apps zusammengestellt, die so ziemlich jeden Use Case und jede Programmiersprache abdeckt, die ich für Web Apps brauchen kann. Der sieht so aus:

Experten sehen jetzt schon, wo der Teil, der hacky ist, reinkommt. Ich lade viel zu viel Zeug rein, das ich für ein kleines JQuery-Projekt nicht brauche. Aber ich habe nie behauptet ein besonders guter Coder zu sein. Zudem will ich die Zeit für ein Listicle nicht verschwenden. Ich geh lieber Bier trinken oder sowas.

Am Ende will ich einen Text, der folgendes Schema hat:

  1. Titel
  2. Lead
  3. Intro
  4. Zwischentitel
  5. Produkt
  6. Bedeutungsloser Füllsatz aus SEO-Gründen

Die Abstraktion geht weiter

Damit wir eine möglichst vielseitige Webform abfüllen können, nicht viel eingeben müssen und möglichst schnell zum Resultat kommen, können wir die oben erwähnten Elemente eines Listicles noch weiter runterbrechen.

Der Titel

Ein Titel hat immer ein ähnliches, wenn nicht sogar dasselbe Format: «Die besten $zahl $productTypePlural. Nummer $zahl2 wird dich erstaunen»

Sowohl $zahl wie $zahl2 können wir vorerst ignorieren. Sie erfordern keinen menschlichen Input, denn hier ist noch ein Geheimnis der Listicles: Die besondere Nummer 9 ist komplett irrelevant. Bis jetzt weiss ich nicht, was Nummer 9 im gestrigen Listicle eigentlich ist. Ich habe mir die Gesamtanzahl vom Computer errechnen lassen und aus dieser Zahl dann eine zufällige als besonders kennzeichnen lassen.

$productTypePlural aber ist etwas schwieriger. Denn die deutsche Sprache ist grammatikalisch heikel. Ich muss der Maschine sowohl einen Singular wie auch einen Plural des Produkttypen übergeben. Im Titel brauche ich den Plural, im Zwischentitel dann den Singular.

Daher sieht das HTML für den Titel so aus:

Dieser/Diese/Dieses

Für den Zwischentitel muss ich der Maschine etwas Grammatik beibringen. Denn dieser liest sich in der aktuellen Version immer «Dieses Kabel». Ist natürlich automatisch generiert. Die Variablen hier heissen $productTypeThis und $productType.

Lead und Intro

Diese zwei Elemente behalte ich als freien Text. Das ergibt SEO-technisch am meisten Sinn. Und zwei, drei Sätze habe ich schnell geschrieben.

Der Zwischentitel

Der Zwischentitel «Dieses Kabel» setzt sich wie folgt zusammen:

var articleZwiti = productTypeThis + " " + productType

Dazu kommt nachher noch ein automatisch generierter Rang und etwas Formatierung.

Das Produkt

Produkte betten wir in unserem Backend nach wie vor manuell ein. Dazu brauchen wir die Produktnummer, die praktischerweise in jeder URL zu einem Produkt verpackt ist.

Da wir aber eine beliebige Anzahl Produkte einbetten können, muss ich später mit einem Array arbeiten. Daher mache ich eine Text Area, die pro Zeile einen Link aus dem digitec Shop akzeptiert und damit arbeitet.

Der nutzlose Fülltext

Da den Fülltext eh keiner liest, kann ich im Fülltext SEO-kompatible Wörter einspielen. Auch hier, Text Area mit einem Satz pro Zeile. Die erste Zeile wird später dem ersten Produkt zugeordnet, die zweite dem zweiten und so weiter.

Dazu habe ich unten einen Button integriert, denn mit diesen Angaben kann mein Generator arbeiten und ein komplettes Listicle erstellen.
Das Listicle wird in einer Textbox namens #listicleOutput ausgegeben

JQuery to the Rescue

Bis jetzt macht die Webseite zwar einen hübschen Eindruck, hat aber noch keine Funktion. Da die Funktion nicht wirklich so besonders komplex ist, können wir hier mit JQuery arbeiten. Die JavaScript Library ist recht stark und versatil und daher perfekt für so Dinge, wie unseren lieblos hingesudelten Listicle Generator.

Im Script-Teil der Seite index.html können wir mit wenigen Zeilen Code recht viel bewirken. Zuerst aber müssen wir die ganzen oben festgelegten Begriffe in JQuery übernehmen. Das machen wir mit Variablen:

            var productNumbers = $('#productNumbers').val()
            var uselessSentences = $('#uselessSentences').val()
            var productType = $('#productType').val()
            var productTypePlural = $('#productTypePlural').val()
            var productTypeThis = $('#productTypeThis').val() 
            var articleLead = $('#articleLead').val()
            var articleIntro = $('#articleIntro').val()

Hier kommen zum ersten Mal auch digitec-spezifische Aspekte hinein. Wir arbeiten im Backend mit Markdown. Das heisst, wir können mit einfachen Zeichen vor einer Zeile Formatierungen schaffen, die dann von der Website übernommen werden. Das ist praktisch und im Alltag müssen die Marketing Manager und die Redaktoren nicht hundertmal mühsam Formatierungen zusammenklicken.

            var zwitiPrefix = "## ";
            var productPrefix = "[[product: ";
            var productSuffix = "]]";
            var doubleBreak = "\r\r";

Zur Erklärung: Wenn ich einen Zwischentitel mache, dann sieht der im Backend so aus:

## Zwischentitel

Ein eingebettetes Produkt so:

[product: 8287505]

Zwischen einzelnen Formatierungen müssen immer zwei Zeilenumbrüche sein, die ich mit var doubleBreak als Variable definiere. Mit diesen Formatierungen plus den Angaben aus obiger Form kann ich also mein Listicle zusammensetzen.

Zwei Arrays mit lieblosen Daten

Ich bin aber faul. Ich will nur Links in meine Form reinpacken, denn so finde ich die Produkte für mein liebloses Listicle auch. Da noch manuell konzentriert Produktnummern herauszueditieren ist zu viel verlangt. Machen wir das automatisch.

              var urls = productNumbers.split(/\s+/)
                console.log(urls)
                var mv = $.map(urls, function (val, i) {
                    if (val != "") {
                        var ju = val.split('?')[0]
                        pat = /[-|/](\d{5,8})$/
                        rv = pat.exec(ju)
                        if (rv !== null) {
                            console.log("Found id: " + rv[1])
                            return rv[1]
                        } else {
                            console.log(" Not matching html ")
                        }
                    }
                })

Hier baue ich ein Array aus den URLs. In der Regel ist die Produktnummer ganz hinten an der URL.

https://www.digitec.ch/de/s1/product/caterpillar-s61-520-64gb-dual-sim-16mp-schwarz-silber-mobiltelefon-8287505

Wenn ich aber über die Filter der Website zu meiner Auswahl gelangt bin, dann macht die Seite ein Suffix, das die Filterung reflektiert, hinten an die URL.

https://www.digitec.ch/de/s1/product/caterpillar-s61-520-64gb-dual-sim-16mp-schwarz-silber-mobiltelefon-8287505?tagIds=82

Darum der .split mit dem Fragezeichen. Alles, was nach dem Fragezeichen kommt, wird verworfen. Danach suche ich eine Zahlenfolge von 5 bis 8 Ziffern und packe sie in ein Array. StackOverflow sei Dank habe ich sogar etwas wie Error Handling eingebaut.

Das zweite Array ist dann auch schnell gemacht, denn Texte sind etwas einfacher.

                var lines = $('#uselessSentences').val().split(/\n/);
                var texts = [];
                for (var i = 0; i < lines.length; i++) {
                    // only push this line if it contains a non whitespace character.
                    if (/\S/.test(lines[i])) {
                        texts.push($.trim(lines[i]));
                    }
                }

Habe ich von StackOverflow. Im Wesentlichen mache ich hier nichts anderes, als all die SEO-Sätze in ein zweites Array zu packen.

Bauen wir einen Artikel

Damit haben wir alles, damit wir einen Aritkel bauen können. Das geht in JQuery easy mit .each:

$.each(mv, function (index, value) {
                    var articleZwiti = productTypeThis + " " + productType
                    $('#listicleOutput').append(zwitiPrefix + (index + 1) + ": " + articleZwiti + doubleBreak + productPrefix + value + productSuffix + doubleBreak + texts[index] + doubleBreak);
                })

Ich nehme die Variablen oben, definiere kurz wie ein Zwischentitel aufgebaut ist, dann geht's los:

  • Im Feld #listicleOutput
  • Hinten an den (bisher leeren) Inhalt angehängt
  • Die zwei Hashtags, damit das System einen Zwischentitel macht
  • Dann die Stelle im Array, an der die Produktnummer ist. Achtung: Arrays fangen immer bei Null an, bei Ranglisten aber fangen Menschen bei 1 an. Daher das +1 am Ende.
  • Ein Doppelpunkt
  • Der Zwischentitel
  • Zwei Leerzeilen
  • Die beiden eckigen Klammern plus das Wort «product: »
  • Die Produktnummer
  • Die beiden eckigen Klammern abschliessen
  • Zwei Leerzeilen
  • Der korrespondierende Satz aus dem Array texts
  • Zwei Leerzeilen

each macht das für jeden Eintrag in der Linkliste und sortiert den Satz aus dem zweiten Array dazu.

Beim Klick auf den Black Magic Button passiert das alles vollautomatisch und in #listicleOutput wird das fertig gebaute Listicle ausgespuckt.

Die Sache mit dem Titel und all dem

Ein Listicle aber hat einen Titel. Den können wir automatisieren. Wir brauchen nur die Anzahl Einträge im Array (+1), dann eine zufällige Zahl aus der Anzahl der Einträge im Array.

var randomIndex = Math.floor(Math.random() * texts.length)+1;

var articleTitle = "Die besten " + texts.length + " " + productTypePlural + ". Nummer " + randomIndex + " wird dich erstaunen";


Die Variable randomIndex pickt zufällig eine Zahl aus dem Array raus und macht dann «Nummer 9 wird dich erstaunen». Mit dem Attribut .length sage ich JQuery, dass nicht der Inhalt, sondern die Länge des Arrays relevant ist.

Dieses Konstrukt schieben wir an den Anfang des Listicles:

$('#listicleOutput').prepend(articleTitle + doubleBreak + articleLead + doubleBreak + articleIntro + doubleBreak)

Voilà, das Listicle steht und kann 1:1 in unser Backend kopiert werden. Ein Listicle kann so lieblos in wenigen Sekunden hingesudelt werden.

Dieses Modell kann übrigens beliebig erweitert werden. Die Wälle aus Produkten auf digitec und Galaxus? Kein Problem. Irgendwelche Styling-Listen, wo ein gesamtes Outfit irgendwie dargestellt werden muss? Keine Sache. Menschlicher Fehler ist minimiert und inhaltlich sind wir zwar SEO-optimiert, aber nicht relevant.

Was sonst noch so dazu gehört

Damit sind wir noch nicht ganz am Ende. Denn da wir so wenig Arbeit wie möglich am Listicle selbst machen können, können wir mit dem Knopfdruck einiges automatisieren.

Kopieren des Listicles

Wenn wir das Listicle nicht automatisch kopieren, dann müssen wir im Feld #listicleOutput alles markieren, rechts klicken und dann kopieren, oder CTRL/⌘+C drücken. Wieder Risiko für menschlichen Fehler. Daher:

$("#listicleOutput").select();
document.execCommand('copy');

Das kopiert den ganzen Inhalt in die Zwischenablage. Können wir uns das also sparen. Ferner können wir uns die manuelle Suche nach einem passenden Bild oben sparen. Denn wir haben den Suchbegriff, den wir bei Google eingeben würden, bereits oben in $productType übergeben.

var searchURL = "https://www.google.ch/search?q=" + productType + "&tbs=sur:fc,isz:l,imgo:1&tbm=isch"
window.open(searchURL, '_blank')

Voilà, eine Google Image Search öffnet sich per Knopfdruck. Der Suffix hinten an der URL macht nichts anderes als folgende Filterungen in Google Image Search standardmässig bereits zu machen:

  • Grösse: gross
  • Lizenz: Zur freien Verbreitung
  • Grössen der Bilder anzeigen

Denn kein Listicle ist komplett ohne belangloses Stock Photo oben.

Du bist dran: Bau weiter

Ich habe einen Narren an diesem Projekt gefressen. Denn mit wenig Effort kann der Generator viel mehr. Ich habe mir überlegt, ob ich ihm Aspekte wie «beste», «schönste» oder so übergeben kann, damit auch die nutzlosen aber SEO-optimierten Sätze entweder generiert werden oder aus einem Array ausgelesen.

So. Fertig. Ich mach mal wieder was, das etwas Recherche und Liebe erfordert. Journalismus, zum Beispiel.

Update 11.12.2018 // 10:55 Uhr: GitHub

Auf Wunsch aus der Kommentarspalte, hier ein GitHub-Repo mit dem Projekt. Lass mich wissen, wenn du was Cooles damit machst.

87 Personen gefällt dieser Artikel


User Avatar
User Avatar

Journalist. Autor. Hacker. Ich bin Geschichtenerzähler und suche Grenzen, Geheimnisse und Tabus. Ich dokumentiere die Welt, schwarz auf weiss. Nicht, weil ich kann, sondern weil ich nicht anders kann.

Diese Beiträge könnten dich auch interessieren

  • Hintergrund

    Apple NeuralHash gegen Privatsphäre: Die Büchse der Pandora wird geöffnet

    von Dominik Bärlocher

  • Hintergrund

    Eine komplexe Angelegenheit: So funktioniert eine SSD

    von Kevin Hofer

  • Hintergrund

    NeuralHash Update: Von Erklärungsversuchen, Hackern und der Backdoor, die keine sein soll

    von Dominik Bärlocher

24 Kommentare

Avatar
later