10 06.2015

Kupiłeś na Allegro bazę maili i adresy są popsute. Co robić, jak żyć?

Dzisiejszym artykułem rozpoczynamy nowy cykl porad dla email marketerów. Mamy nadzieję, że nasze porady obniżą próg wejścia w branżę email marketingu na tyle, aby wielu obecnych pracowników etatowych zaryzykowało i spełniło swoje marzenie o własnym biznesie.

Dzisiaj pokażemy na przykładach, w jaki sposób poprawić jakość taniej bazy adresów email. W kolejnych odcinkach wytłumaczymy, w jaki sposób można:

  • poprawiać jakość tanich baz adresowych
  • obsługiwać i automatycznie analizować zwrotki
  • wykrywać nieaktualne adresy (a także optymalizować zużycie zasobów potrzebnych do ich wykrywania - to ważne, jeśli korzystasz z chmury)
  • prowadzić czarne listy upierdliwych odbiorców
  • oddzielać odbiorców ze zbyt silną ochroną antyspamową od reszty
  • oddzielać adresy spełniające określone kryteria prawne, np. "oznaczonych odbiorców będących osobą fizyczną", od reszty
  • targetować mailingi po branżach, miastach i płci, mając do dyspozycji tylko i wyłącznie adresy email bez danych dodatkowych
  • zapewnić sobie pełną zgodność z prawem
  • omijać filtry antyspamowe portali typu Onet
  • umiejętnie prowadzić dialog ze swoim dostawcą hostingu, który dostaje skargi na wysyłanie spamu i grozi Ci wypowiedzeniem umowy


Wszystkie te techniki sprawdziliśmy w praktyce, prowadząc przez prawie 2 lata serwis LegalnyMailing.pl i wysyłając w tym czasie kilkaset milionów maili. Jeśli chcielibyście poczytać o innych aspektach prowadzenia takiego serwisu, niż te z powyższej listy, piszcie w komentarzach albo bezpośrednio do nas na adres pomoc@fajne.it. A więc zacznijmy.

Kupiłeś bazę za 49,99 zł i okazało się, że jest bardzo słabej jakości

Gdy to zauważyłeś, pewnie zacząłeś się zastanawiać, czy cały Twój pomysł na biznes nie opiera się na błędnych założeniach. Spokojnie! Każdy w ten sposób zaczynał. No, prawie każdy - na rynku są również gracze, którzy od samego początku działalności mieli do dyspozycji wielomilionowy kapitał, i którzy mogli sobie pozwolić na "lepsze", bardziej wyszukane metody budowania baz odbiorców. Ty jednak takim kapitałem przypuszczalnie nie dysponujesz, dlatego nie trać czasu i energii na czytanie "dobrych rad" od takich firm, gdyż z dużym prawdopodobieństwem tych rad i tak nie da się zastosować w Twoim biznesie.

Przyjrzyjmy się Twojej bazie. Część adresów jest prawidłowa, a część nie. Wygląda to zapewne mniej więcej tak:


ogonek@wp
mart..@pl.onet
prawidlowy@adres.pl
piotr@pwr.wroc
firma@firma.waw
jasiu@neos
innafirma@siem

Widzieliśmy dziesiątki tego typu baz adresów. To nic nowego. Zabierzmy się więc za naprawę tej bazy.

Zrobimy to za pomocą skryptu stworzonego w języku PHP. Wybraliśmy akurat ten język z uwagi na jego bardzo dużą elastyczność i genialną funkcjonalność tablic asocjacyjnych połączoną z dynamicznym typowaniem, dzięki którym kod na nich operujący jest znacznie krótszy i prostszy, niż w innych językach. Dodatkowo w języku PHP w mniejszym stopniu używa się operatorów (czyli dziwnych sekwencji znaków typu ~=), a w większym stopniu funkcji o nazwach w języku angielskim, dobrze rozpoznawalnych przez Google. Początkujący mogą więc łatwo zasięgnąć w Google porady, jak dana część kodu działa.

Zabierzmy się więc za analizę poszczególnych części skryptu, funkcja po funkcji:


function fix_cut_domains($address)
{
     $cuts = array(
          array( -2, ".p",   "l"     ), // @wp.p$
          array( -4, "onet", ".pl"   ), // @poczta.onet$
          array( -4, ".one", "t.pl" ),
          array( -3, ".on",  "et.pl" ), // @poczta.on$
          array( -3, "@wp",  ".pl" ),
          array( -3, ".wp",  ".pl" ),
          array( -4, "lodz", ".pl" ),
          array( -4, "wroc", ".pl" ),
          array( -4, "nysa", ".pl" ),
          array( -4, ".tor", "un.pl" ),
          array( -4, ".waw", ".pl" ),
          array( -4, ".gda", ".pl" ),
     );

     foreach ($cuts as $cut) {
          $last = substr($address, $cut[0]);
          if ($last === $cut[1]) {
               $address .= $cut[2];
               break;
          }
     }

     return $address;
}

Jak działa powyższa funkcja: trafia do niej po kolei każdy adres z pliku wejściowego i jest sprawdzany, czy kończy się jednym z podanych wyrażeń, np. "@wp" - jeśli tak, wówczas jest do niego doczepiana końcówka, więc adres po naprawie kończy się tak: "@wp.pl".

W tym momencie przerwijmy na chwilę i wyjaśnijmy jedną rzecz: powyższy fragment skryptu zawiera tabelę z 12 typami obciętych adresów. Nasz kompletny skrypt rozpoznaje prawie 130 takich końcówek, jak również ponad 100 innych anomalii.

Skrypt ten możesz kupić w naszym sklepie już za 50 zł (zobacz nasz pełny cennik lub nie trać czasu i od razu kup go, płacąc kartą lub przelewem z dowolnego banku).

Ten artykuł opisuje ok. 60% funkcjonalności tego skryptu, pozwalających wykryć i naprawić średnio nieco ponad 70% popsutych adresów, jeśli więc nie chcesz go kupować, możesz go złożyć samodzielnie z fragmentów (będzie działać!), a następnie dobrać eksperymentalnie kolejne końcówki adresów i inne brakujące dane - nie ma w tym żadnej filozofii, wystarczy po prostu podzielić bazę adresów na adresy prawidłowe i nieprawidłowe, po czym przyjrzeć się bliżej tym nieprawidłowym i dopisać kolejne regułki: dla miast, dla typowych literówek itp.

Dla porównania, pełna wersja skryptu pozwala wykryć i naprawić (niekoniecznie automatycznie!) ponad 99% popsutych adresów.


Wróćmy do opisu skryptu i zajmijmy się przypadkiem domen obciętych w taki sposób, że nie jest jasne, jakiej poczty używa odbiorca:


function dots($address)
{
     return strpos($address, "..") !== false;
}

function rewrite_dotted_domains($address)
{
     $domains_with_double_dots = array(
          "on." => "onet.pl",
          "o." => array("onet.pl", "o2.pl", "op.pl"),
     );

     list($username, $domain) = explode("@", $address);

     if (dots($domain)) {
          foreach ($domains_with_double_dots as $key => $replacement) {
               if (strpos($domain, $key) === 0) {
                    if (!is_array($replacement)) {
                         return array("$username@$replacement");
                    } else {
                         $out = array();
                         foreach ($replacement as $tmp)
                              $out[] = "$username@$tmp";
                         return $out;
                    }
               }
          }
     }

     return array($address);
}

Ta funkcja otrzymuje na wejściu pojedynczy adres, zwraca natomiast listę adresów - listę złożoną z pojedynczego adresu, jeśli udało się zrobić pełne dopasowanie, bądź z kilku adresów, jeśli na podstawie uciętego adresu nie da się jednoznacznie odtworzyć domeny. Przykładowo, z adresu "marta@o." robione są kolejno adresy: marta@onet.pl. marta@o2.pl i marta@op.pl. Powyższy skrypt zawiera tylko 2 regułki, nasz skrypt zawiera ich 17.

Kolejną ciekawą anomalią jest obcięcie końcówek ".pl" dla adresów z "podwójnymi" końcówkami, np. edu.pl. Spróbujmy wykryć takie przypadki:


function detect_global_domain($address)
{
     $globals = array(
          ".edu" => -4,
     );

     foreach ($globals as $global => $length) {
          $last = substr($address, $length);
          if ($last === $global) {
               return true;
          }
     }

     return false;
}

Przejdźmy do tzw. pętli głównej skryptu, czyli części, która będzie czytać dane z pliku, wstępnie obrabiać i kierować je do dalszego przetwarzania przez m.in. powyższe funkcje:


$strip1 = array(" ", "\t", "\"", "\\", "'", "!");
$lines = file($argv[1], FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
$out = array();
$broken = array();
$nospam = array();
foreach ($lines as $line)
{
     // na początek próbujemy naprawić typowe problemy
     // (w naszym skrypcie jest tu jeszcze kilkadziesiąt dodatkowych filtrów)
     $address = str_replace($strip1, "", $line);
     $address = strtolower($address);
     $address = str_replace("nospam.gazeta.pl", "gazeta.pl", $address);
     $address = str_replace("onet.poczta", "poczta.onet", $address);
     $address = str_replace("wp.lp", "wp.pl", $address);
     $address = fix_cut_domains($address);

     // ta funkcja wykrywa adresy, które w treści mają słowa typu usun, skasuj,
     // delete, spam itp., ale z wyjątkiem maili w domenach typu spamgourmet.com
     // (inwencja niektórych osób nie zna granic, więc nie próbujemy naprawić
     // tych adresów ręcznie, typu kierujemy je do osobnego pliku wyjściowego
     // celem naprawy manualnej)
     if (marked_nospam($address)) {
          $nospam[] = $address;
          continue;
     }

     // te adresy kierujemy do osobnego pliku celem naprawy manualnej;
     // anomalie, które wyłapujemy w tym miejscu, najczęściej występują
     // wspólnie z innymi anomaliami, więc nie próbujemy automatycznie
     // rozwiązać tylko części problemu, tylko w całości kierujemy do
     // analizy i naprawy manualnej
     // (w naszym skrypcie jest 13 takich reguł, te 2 to najprostsze przypadki)
     if (strpos($address, ".plwww") !== false
      || strpos($address, ".pltel") !== false) {
          $broken[] = $address;
          continue;
     }

     // w tym przypadku oryginalny adres zostanie zastąpiony poprawionym adresem
     if (substr($address, -4) === ".prv") {
          $address .= ".pl";
     }

     $addresses = array();

     // w tym przypadku z oryginalnego adresu powstaną 2 adresy: oryginalny
     // i poprawiony, a który z nich jest faktycznie poprawny, okaże się w
     // momencie wysyłki mailingu - na niepoprawny adres przyjdzie zwrotka
     if (detect_global_domain($address)) {
          $addresses[] = $address.".pl";
     }

     foreach ($addresses as $address) {
          if (!dots($address)) {
               $out[] = $address;
               continue;
          }

          $list = rewrite_dotted_domains($address);

          foreach ($list as $tmp) {
               if (dots($tmp)) {
                    $broken[] = $tmp;
               } else {
                    $out[] = $tmp;
               }
          }
     }
}

file_put_contents($argv[2], implode("\n", $out));
file_put_contents($argv[3], implode("\n", $broken));
file_put_contents($argv[4], implode("\n", $nospam));


To jest uproszczona wersja naszego skryptu. Pełna wersja, którą możesz u nas kupić, wykrywa i naprawia łącznie ponad 250 różnych anomalii.


Spróbujmy uruchomić ten skrypt:


php rewrite.php in.txt tmp.txt out-broken.txt out-nospam.txt

Co znajduje się w poszczególnych plikach:

  • in.txt - Twoja oryginalna baza adresów
  • tmp.txt - adresy poprawne (w tym naprawione automatycznie) do dalszego przetwarzania
  • out-broken.txt - adresy popsute do naprawy manualnej
  • out-nospam.txt - adresy "zabezpieczone antyspamowo" do naprawy manualnej

A kiedy już obrobisz pliki out-broken.txt i out-nospam.txt, uruchom to polecenie, aby je scalić:


cat tmp.txt out-broken.txt out-nospam.txt |sort |uniq >out.txt

Tyle powinno Ci wystarczyć na początek. Oczywiście nadal Twoje mailingi nie trafią do najlepszych adresów - najlepszych, czyli tych, które tylko nieliczni zdołali odtworzyć - ale dzięki powyższym technikom powinieneś odtworzyć ponad 70% popsutych adresów z bazy (średnio, dokładny wynik zależy od źródła, z którego kupiłeś bazę).

Jeśli brakuje Ci czasu lub cierpliwości na składanie gotowego skryptu z powyższych części, możesz kupić całość już za 50 zł (zobacz cennik). Poza samym skryptem PHP dostaniesz również skrypt shell uruchamiający część PHP, oraz wykrywający kolejne anomalie w adresach.

Nabywcy wersji niekodowanej skryptu otrzymają dodatkowo skrypty shell realizujące kolejne etapy filtrowania adresów (opiszemy to w kolejnych odcinkach naszego poradnika).

Całość jest przetestowana na Debianie Wheezy z PHP w domyślnej wersji 5.4.39, powinna jednak działać bez problemów w dowolnej wersji systemu Linux z zainstalowanym PHP.



Tomasz Klim
Administrator serwerów i baz danych, specjalista w zakresie bezpieczeństwa, architekt IT, przedsiębiorca. Prawie 20 lat w branży IT. Pracował dla największych i najbardziej wymagających firm, jak Grupa Allegro czy Wikia. Obecnie zajmuje się doradztwem dla klientów Fajne.IT, a w wolnych chwilach pisze artykuły. Chętnie podejmuje się ciekawych zleceń.


Wzbudziliśmy Twoje zainteresowanie?

Szukasz pomocy? formularz kontaktowy