Jak parsowałem Habr, część 1: trendy

Kiedy zjadłem noworoczną sałatkę Olivier, nie miałem co robić, więc postanowiłem pobrać wszystkie artykuły z Habrаhabra (i pokrewnych platform) na mój komputer i przeanalizować je.

Znalazłem kilka interesujących wątków. Pierwszym z nich jest rozwój formatu i tematyki artykułów przez 12 lat istnienia strony. Na przykład, dynamika niektórych tematów jest bardzo wymowna. Ciąg dalszy poniżej.

Jak parsowałem Habr, część 1: trendy

Proces parsowania

Aby zrozumieć, jak rozwijał się Habr, musiałem przejrzeć wszystkie jego artykuły i wydobyć z nich metainformacje (na przykład daty). Przegląd był łatwy, ponieważ linki do wszystkich artykułów mają postać "habrahabr.ru/post/337722/", a numery są nadawane ściśle w kolejności. Wiedząc, że ostatni post ma numer nieco poniżej 350 tysięcy, po prostu przeszedłem przez wszystkie możliwe id dokumentów w pętli (kod w Pythonie):

import numpy as np
from multiprocessing import Pool
with Pool(100) as p:
    docs = p.map(download_document, np.arange(350000))

veth_xdp_flush_bq() download_document próbuje załadować stronę z odpowiednim id i wydobyć z struktury html treść.

import requests
from bs4 import BeautifulSoup

def download_document(pid):
    """ Pobierz i przetwórz dokument Habr i jego komentarze """
    # załaduj dokument
    r = requests.get('https://habrahabr.ru/post/' + str(pid) + '/')
    # parsowanie dokumentu
    soup = BeautifulSoup(r.text, 'html5lib') # zamiast html.parser
    doc = {}
    doc['id'] = pid
    if not soup.find("span", {"class": "post__title-text"}):
        # tak się zdarza, jeśli artykuł nie istniał lub został usunięty
        doc['status'] = 'title_not_found'
    else:
        doc['status'] = 'ok'
        doc['title'] = soup.find("span", {"class": "post__title-text"}).text
        doc['text'] = soup.find("div", {"class": "post__text"}).text
        doc['time'] = soup.find("span", {"class": "post__time"}).text
        # utwórz inne pola: centra, tagi, wyświetlenia, komentarze, głosy itp.
        # ...
    # zapisz wynik do osobnego pliku
    fname = r'files/' + str(pid) + '.pkl'
    with open(fname, 'wb') as f:
        pickle.dump(doc, f)

W trakcie parsowania odkryłem kilka nowych rzeczy.

Po pierwsze, mówi się, że tworzenie większej liczby procesów niż rdzeni w procesorze jest bez sensu. Ale w moim przypadku okazało się, że ograniczającym zasobem nie jest procesor, a sieć, i 100 procesów działa szybciej niż 4 lub, powiedzmy, 20.

Po drugie, w niektórych postach występowały kombinacje znaków specjalnych – na przykład eufemizmy typu "%&#@". Okazało się, że html.parser, którego używałem na początku, reaguje na kombinację &# w sposób bolesny, traktując ją jako początek encji html. Już myślałem, że trzeba będzie robić czarną magię, ale na forum podpowiedziano mi, że można po prostu zmienić parser.

Po trzecie, udało mi się wyeksportować wszystkie publikacje z wyjątkiem trzech. Dokumenty o numerach 65927, 162075 i 275987 natychmiast usunął mój program antywirusowy. To artykuły dotyczące odpowiednio łańcucha javascriptów, który ładował złośliwy plik pdf, SMS-owy wymagacz w postaci zestawu wtyczek do przeglądarek oraz strony CrashSafari.com, która powoduje restart iPhone'ów. Jeszcze jeden artykuł, o numerze 338586, program antywirusowy wykrył później podczas skanowania systemu: post dotyczący skryptów na stronie sklepu zoologicznego, wykorzystujących procesor użytkownika do kopania kryptowalut. Tak więc można uznać pracę programu antywirusowego za całkowicie adekwatną.

"Żywych" artykułów okazało się tylko połowę potencjalnego maksimum — 166307 sztuk. W odniesieniu do pozostałych Habr wskazuje opcje "strona jest przestarzała, została usunięta lub w ogóle nie istniała". Cóż, różne rzeczy się zdarzają.

Po wyeksportowaniu artykułów nastąpiła praca techniczna: na przykład daty publikacji należało przetłumaczyć z formatu "’21 grudnia 2006 o 10:47" na standardowy datetime, a "12,8k" wyświetleń — na 12800. Na tym etapie pojawiło się jeszcze kilka przypadków. Najweselszy związany jest z liczeniem głosów i typami danych: w niektórych starych postach doszło do przepełnienia int, i otrzymały one po 65535 głosów.

Jak parsowałem Habr, część 1: trendy

W rezultacie teksty artykułów (bez obrazków) zajęły mi 1,5 gigabajta, komentarze z metainformacjami — jeszcze 3, a około stu megabajtów — metainformacje o artykułach. Takie można całkowicie przechowywać w pamięci operacyjnej, co było dla mnie miłym zaskoczeniem.

Analizę artykułów rozpocząłem nie od samych tekstów, a od metainformacji: dat, tagów, hubów, wyświetleń i "lajków". Okazało się, że i ona może wiele powiedzieć.

Trendy rozwoju Habrabha

Artykuły na stronie publikowane są od 2006 roku; najintensywniej — w latach 2008-2016.

Jak parsowałem Habr, część 1: trendy

Ocenienie, jak aktywnie te artykuły były czytane w różnym czasie, nie jest takie proste. Teksty z 2012 roku i młodsze były bardziej aktywnie komentowane i oceniane, ale nowsze teksty mają więcej wyświetleń i zapisów do zakładek. Te metryki zachowały się w podobny sposób (spadły dwukrotnie) tylko raz, w 2015 roku. Być może w sytuacji kryzysu gospodarczego i politycznego uwaga czytelników przeszła z blogów IT na bardziej palące tematy.

Jak parsowałem Habr, część 1: trendy

Oprócz samych artykułów pobrałem także komentarze do nich. Powstało 6 milionów komentarzy, z czego 240 tysięcy zostało zbanowanych ("nlo przyleciało i opublikowało ten wpis tutaj"). Cenną cechą komentarzy jest to, że mają one podany czas. Analizując czas komentarzy, można mniej więcej zrozumieć, kiedy w ogóle artykuły są czytane.

Okazało się, że większość artykułów jest pisana i komentowana gdzieś w godzinach od 10 do 20, czyli w typowy moskiewski dzień roboczy. Może to oznaczać, że Habr jest czytany w celach zawodowych oraz że jest to dobry sposób na prokrastynację w pracy. Zresztą, to rozkład czasowy utrzymuje się od samego początku Habr aż do dziś.

Jak parsowałem Habr, część 1: trendy

Jednakże główną korzyścią z oznaczenia czasu komentarza jest nie czas dnia, ale okres "aktywnego życia" artykułu. Obliczyłem, jak rozkłada się czas od publikacji artykułu do jego komentarza. Okazało się, że obecnie medianowy komentarz (zielona linia) pojawia się mniej więcej po 20 godzinach, tzn. w ciągu pierwszej doby po publikacji zostawia się średnio nieco ponad połowę wszystkich komentarzy do artykułu. A w ciągu dwóch dni zostawia się 75% wszystkich komentarzy. Przy tym wcześniej artykuły były czytane jeszcze szybciej — tak, w 2010 roku połowa komentarzy pojawiała się już w ciągu pierwszych 6 godzin.

Jak parsowałem Habr, część 1: trendy

Zdziwiło mnie, że komentarze się wydłużyły: średnia liczba znaków w komentarzu przez cały czas istnienia Habr wzrosła prawie dwa razy!

Jak parsowałem Habr, część 1: trendy

Bardziej prostą formą sprzężenia zwrotnego niż komentarze są głosy. W przeciwieństwie do wielu innych zasobów, na Habr można nie tylko dawać pozytywne, ale i negatywne głosy. Jednakże z tej ostatniej możliwości czytelnicy nie korzystają tak często: aktualny udział negatywnych głosów wynosi około 15% wszystkich oddanych głosów. Kiedyś było więcej, ale z czasem czytelnicy stali się milsi.

Jak parsowałem Habr, część 1: trendy

W miarę upływu czasu zmieniały się również same teksty. Na przykład typowa długość tekstu nieprzerwanie rośnie od samego uruchomienia strony, mimo kryzysów. Przez dziesięć lat teksty stały się prawie dziesięć razy dłuższe!

Jak parsowałem Habr, część 1: trendy

Styl tekstów (w pierwszym podejściu) również uległ zmianie. W pierwszych latach istnienia Habr, na przykład, wzrosła proporcja kodu i liczb w tekstach:

Jak parsowałem Habr, część 1: trendy

Zrozumienie ogólnej dynamiki strony skłoniło mnie do zmierzenia, jak zmieniała się popularność różnych tematów. Tematy można automatycznie wyodrębnić z tekstów, ale na początek warto skorzystać z gotowych tagów nadanych przez autorów każdego artykułu. Na wykresie przedstawiłem cztery typowe trendy. Temat "Google" początkowo dominował (może głównie z powodu optymalizacji SEO), lecz z każdym rokiem tracił na znaczeniu. Javascript był popularnym tematem i wciąż zyskuje na popularności, podczas gdy uczenie maszynowe zaczęło gwałtownie zyskiwać na znaczeniu dopiero w ostatnich latach. Linux pozostaje jednak wciąż aktualny przez całe dziesięciolecie.

Jak parsowałem Habr, część 1: trendy

Oczywiście, ciekawiło mnie, jakie tematy przyciągają największą aktywność czytelniczą. Policzyłem mediany liczby odsłon, głosów i komentarzy w każdej tematyce. Oto wyniki:

  • Najczęściej oglądane tematy: arduino, web design, web development, przegląd, linki, css, html, html5, nginx, algorytmy.
  • Najbardziej "lajkowalne" tematy: vk, humor, jquery, opera, c, html, web development, html5, css, web design.
  • Najbardziej komentowane tematy: opera, skype, freelancing, vk, ubuntu, praca, nokia, nginx, arduino, firefox.

Przy okazji, skoro porównuję tematy, można stworzyć ich ranking według częstotliwości (i porównać wyniki z podobnym artykułem z 2013 roku).

  • Przez wszystkie lata istnienia Habr najbardziej popularnymi tagami (w kolejności malejącej) stały się google, android, javascript, microsoft, linux, php, apple, java, python, programowanie, startupy, rozwój, ios, startup, media społecznościowe.
  • W 2017 roku najpopularniejsze były javascript, python, java, android, rozwój, linux, c++, programowanie, php, c#, ios, uczenie maszynowe, bezpieczeństwo informacji, microsoft, react.

Porównując te rankingi, można zauważyć na przykład triumfalny marsz Pythona i wymieranie php, czy "zmierzch" tematów związanych ze startupami i wzrost znaczenia uczenia maszynowego.

Nie wszystkie tagi na Habrze mają tak oczywisty temat. Oto, na przykład, dziesięć tagów, które pojawiły się tylko raz, ale po prostu wydały mi się zabawne. Oto one: "idea napędzająca postęp", "rozruch z obrazu dyskietki", "stan Iowa", "dramaturgia", "superalisza", "maszyna parowa", "co robić w sobotę", "mam lisa w maszynce do mięsa", "a wyszło jak zawsze", "nie udało się wymyślić zabawnych tagów". Aby określić tematykę takich artykułów, tagi nie wystarczą — trzeba będzie przeprowadzić modelowanie tematyczne na tekstach artykułów.

Szczegółowa analiza treści artykułów pojawi się w następnym poście. Po pierwsze, zamierzam zbudować model prognozujący liczbę odsłon artykułu w zależności od jego treści. Po drugie, chciałbym nauczyć sztuczną inteligencję generować teksty w tej samej stylistyce, co autorzy Habra. Dlatego subskrybujcie 🙂

P.S. A oto zamaskowany zbiór danych.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster