Jak scrapuji Hacker News pomocí Pythonu (2 metody, kompletní kód)

Naposledy aktualizováno April 16, 2026

Před pár měsíci jsem chtěl pro náš tým v Thunderbitu připravit denní přehled nejzajímavějších článků z Hacker News. První nápad byl úplně jednoduchý: web si jen uložit do záložek a každé ráno ho projít ručně. Vydrželo to asi tři dny, než mi došlo, že denně strávím 20 minut jen čtením nadpisů a kopírováním odkazů do tabulky.

Hacker News patří mezi nejbohatší a nejkoncentrovanější zdroje technologických informací na internetu — zhruba , asi 1 300 nových příspěvků denně a přibližně 13 000 komentářů každý den. Ať už sledujete nové technologické trendy, hlídáte svou značku, stavíte náborový kanál z vláken „Who’s Hiring“, nebo prostě chcete mít přehled o tom, co hýbe vývojářským světem, ruční sledování je předem prohraný boj.

Dobrá zpráva je, že scrapování Hacker News pomocí Pythonu je překvapivě snadné. V tomhle průvodci vám ukážu dva kompletní postupy — HTML scrapování s BeautifulSoup a oficiální HN Firebase API — a přidám i stránkování, export dat, produkční postupy a no-code zkratku pro chvíle, kdy je Python zbytečně moc.

Proč scrapovat Hacker News pomocí Pythonu?

Hacker News není jen další agregátor odkazů. Je to pečlivě kurátorovaný feed řízený komunitou, kde se ty nejzajímavější technologické příběhy dostávají nahoru díky hlasům a živé diskusi. Publikum je výrazně orientované na technologické profesionály (přibližně ), a 66% podíl přímé návštěvnosti naznačuje, že jde o loajální publikum, ne o náhodné návštěvníky.

Proto lidé HN data scrapují:

Případ použitíCo získáte
Denní technologický digestTop příběhy, skóre a odkazy doručené do e-mailu nebo do Slacku
Monitoring značky/konkurenceUpozornění, když se zmíní vaše firma nebo produkt
Analýza trendůSledování technologií, jazyků nebo témat, která získávají na popularitě
NáborParsování vláken „Who’s Hiring“ pro nabídky práce, technologické stacky a signály o mzdách
Průzkum obsahuHledání témat, která mají výkon a stojí za to o nich psát nebo je sdílet
Sentiment analýzaZjišťování, jak komunita vnímá produkty, launch nebo změny v odvětví

Firmy s dohromady hodnotou přes 400 miliard dolarů — Stripe, Dropbox, Airbnb — připisují Hacker News zásadní ranou zpětnou vazbu i první uživatele. Drew Houston zveřejnil demo Dropboxu na HN v dubnu 2007, dostalo se na první místo a čekací listina na beta verzi vyletěla z 5 000 na 75 000 uživatelů během jediného dne. Data z HN tedy nejsou jen zajímavá — mají i přímou obchodní hodnotu.

Data jsou veřejně dostupná, ale struktura webu dělá ruční sběr zdlouhavým. Automatizace pomocí Pythonu je praktické řešení.

Dva způsoby, jak scrapovat Hacker News pomocí Pythonu: přehled

Tento průvodce pokrývá dva kompletní a spustitelné přístupy:

  1. HTML scrapování s requests + BeautifulSoup — stáhne surové HTML z news.ycombinator.com a rozparsuje ho, aby vytáhlo data o příspěvcích. Skvělé pro pochopení základů scrapování a získání přesně toho, co je na stránce.
  2. Oficiální Hacker News Firebase API — jde přímo na JSON endpointy, bez potřeby parsování HTML. Lepší pro spolehlivé datové pipeline, přístup ke komentářům a historická data.

Tady je srovnání vedle sebe, které vám pomůže vybrat správný postup:

KritériumHTML scrapování (requests + BS4)HN Firebase APIThunderbit (no-code)
Náročnost nastaveníStřední (parsování HTML selektorů)Nízká (JSON endpointy)Žádná (2 kliknutí v Chrome rozšíření)
Čerstvost datAktuální hlavní stránkaAktuální (libovolná položka podle ID)Aktuální
Riziko rate limituStřední (robots.txt uvádí 30s prodlevu)Nízké (oficiální, velkorysé)Řízeno Thunderbitem
Přístup ke komentářůmNáročný (vnořené HTML)Snadný (rekurzivní ID položek)Funkce scrapování podstránek
Historická dataOmezenáPřes Algolia Search APIN/A
Nejlepší proUčení základů scrapováníSpolehlivé datové pipelineNecodery, rychlé exporty

Obě metody obsahují kompletní, spustitelný Python kód. A pokud chcete data bez psaní jediného řádku kódu, ukážu vám i to.

Než začnete

  • Obtížnost: Začátečník až středně pokročilý
  • Čas potřebný: přibližně 15–20 minut pro každou metodu
  • Co budete potřebovat:
    • Nainstalovaný Python 3.11+
    • Terminál nebo editor kódu
    • Prohlížeč Chrome (pokud chcete prozkoumat HTML HN nebo vyzkoušet no-code variantu)
    • (volitelné, pro no-code metodu)

scrape-hacker-news-methods.webp

Nastavení Python prostředí

Než sáhneme na jakákoli HN data, připravme si prostředí. Doporučuji vytvořit virtuální prostředí, aby byly závislosti projektu pěkně oddělené.

1# Vytvoření a aktivace virtuálního prostředí
2python3 -m venv hn-scraper
3# macOS/Linux:
4source hn-scraper/bin/activate
5# Windows:
6hn-scraper\Scripts\activate
7# Instalace balíčků pro obě metody
8pip install requests==2.33.1 beautifulsoup4==4.14.3 pandas==3.0.2 openpyxl==3.1.5

Pro produkční postupy později (kešování, retry) se vám budou hodit také:

1pip install requests-cache==1.3.1 tenacity==9.1.4

Žádné speciální API klíče, žádné autentizační tokeny. Data z HN jsou otevřená.

Metoda 1: Scrapování Hacker News pomocí BeautifulSoup

Tohle je klasický přístup — stáhnout HTML, rozparsovat ho a vytáhnout potřebná data. Tímto způsobem se většina lidí učí web scraping a jednoduché tabulkové rozložení HN je ideální tréninkové hřiště.

Krok 1: Stažení hlavní stránky Hacker News

Otevřete editor a vytvořte soubor scrape_hn_bs4.py. Tady je výchozí kód:

1import requests
2from bs4 import BeautifulSoup
3> This paragraph contains content that cannot be parsed and has been skipped.
4print(f"Status: {response.status_code}, Page length: {len(response.text)} chars")

Spusťte ho. Měli byste vidět Status: 200 a délku stránky kolem 40 000–50 000 znaků. To je surové HTML hlavní stránky HN uložené v paměti, připravené k parsování.

Krok 2: Pochopení struktury HTML

HN používá tabulkové rozvržení — žádný moderní CSS grid nebo flexbox. Každý příspěvek na stránce se skládá ze dvou klíčových řádků <tr>:

  • Řádek příspěvku (<tr class="athing submission">): obsahuje pořadí, název a odkaz
  • Metadatový řádek (následující <tr>): obsahuje body, autora, čas a počet komentářů

Důležité selektory:

  • span.titleline > a — název příspěvku a URL
  • span.score — počet hlasů (např. „118 points“)
  • a.hnuser — uživatelské jméno autora
  • span.age — čas publikace
  • Poslední <a> v .subtext s textem obsahujícím „comment“ — počet komentářů

Když v Chrome kliknete pravým tlačítkem na libovolný název příspěvku a zvolíte „Inspect“, uvidíte něco jako toto:

1<span class="titleline">
2  <a href="https://darkbloom.dev">DarkbloomPrivate inference on idle Macs</a>
3</span>

A pod tím metadatový řádek:

1<span class="score" id="score_47788542">118 points</span>
2by <a href="user?id=twapi" class="hnuser">twapi</a>
3<span class="age" title="2026-04-16T04:06:39 1776312399">
4  <a href="item?id=47788542">2 hours ago</a>
5</span>
6| <a href="item?id=47788542">65&nbsp;comments</a>

Pochopení těchto selektorů je zásadní — pokud HN někdy změní markup, budete muset selektory upravit. (Spoiler: metoda přes API tenhle problém obchází úplně.)

Krok 3: Extrakce názvů, odkazů a skóre

Teď to hlavní. Projdeme všechny řádky s příběhy, z řádku příspěvku vezmeme název a odkaz a z řádku pod ním pak skóre.

1import requests
2from bs4 import BeautifulSoup
3from pprint import pprint
4> This paragraph contains content that cannot be parsed and has been skipped.
5stories = []
6story_rows = soup.select("tr.athing")
7for row in story_rows:
8    # Název a URL z řádku příspěvku
9    title_tag = row.select_one("span.titleline > a")
10    if not title_tag:
11        continue
12    title = title_tag.get_text()
13    link = title_tag.get("href", "")
14    # Metadata z následujícího řádku
15    meta_row = row.find_next_sibling("tr")
16    score = 0
17    author = ""
18    comments = 0
19> This paragraph contains content that cannot be parsed and has been skipped.
20> This paragraph contains content that cannot be parsed and has been skipped.
21# Filtrovat příběhy s 50+ body a seřadit podle skóre
22top_stories = sorted(
23    [s for s in stories if s["score"] >= 50],
24    key=lambda x: x["score"],
25    reverse=True,
26)
27pprint(top_stories[:10])

Pár poznámek ke kódu:

  • Walrus operátor (:=) funguje v Pythonu 3.8+. Umožňuje přiřadit a zároveň otestovat hodnotu v jednom řádku — hodí se pro volitelné prvky jako span.score, které nemusí existovat u každého řádku (např. job posty nemají skóre).
  • HN používá \xa0 (nezlomitelnou mezeru) mezi číslem a slovem „comments“, proto dělíme podle ní.
  • Příspěvky, které odkazují na jiné stránky HN (např. „Ask HN“), budou mít relativní URL začínající item?id=. Možná budete chtít doplnit https://news.ycombinator.com/.

Krok 4: Spuštění a kontrola výsledků

Uložte a spusťte:

1python scrape_hn_bs4.py

Měli byste vidět výstup podobný tomuto:

1[{'author': 'twapi',
2  'comments': 65,
3  'score': 118,
4  'title': 'Darkbloom – Private inference on idle Macs',
5  'url': 'https://darkbloom.dev'},
6 {'author': 'sebg',
7  'comments': 203,
8  'score': 247,
9  'title': 'Show HN: I built an open-source Perplexity alternative',
10  'url': 'https://github.com/...'},
11 ...]

To je 30 příběhů z první stránky. HN ale má v daný moment stovky aktivních příspěvků. Stránkování probereme v další části.

Metoda 2: Scrapování Hacker News pomocí oficiálního API

HN Firebase API je oficiálně schválený způsob, jak přistupovat k datům Hacker News. Žádná autentizace, žádné API klíče, žádné parsování HTML. Dostanete čisté JSON odpovědi. Tuhle metodu používám pro všechno, co má běžet spolehlivě v produkci.

Klíčové API endpointy, které potřebujete znát

Základní URL je https://hacker-news.firebaseio.com/v0/. Tady jsou důležité endpointy:

This paragraph contains content that cannot be parsed and has been skipped.

Položka příběhu vypadá takto:

1{
2  "by": "twapi",
3  "descendants": 65,
4  "id": 47788542,
5  "kids": [47789171, 47788769, 47788762],
6  "score": 118,
7  "time": 1776312399,
8  "title": "Darkbloom – Private inference on idle Macs",
9  "type": "story",
10  "url": "https://darkbloom.dev"
11}

Pole kids obsahuje ID přímých podkomentářů. Každý komentář je sám o sobě položka, která může mít vlastní kids — tak je postavený strom komentářů.

Krok 1: Stažení ID top příběhů

Vytvořte soubor scrape_hn_api.py:

1import requests
2import time
3from pprint import pprint
4API_BASE = "https://hacker-news.firebaseio.com/v0"
5# Stažení ID top příběhů
6response = requests.get(f"{API_BASE}/topstories.json")
7story_ids = response.json()
8print(f"Got {len(story_ids)} top story IDs")
9# Output: Got 500 top story IDs

500 ID příběhů v jediném requestu — žádné parsování, žádné selektory, jen JSON pole.

Krok 2: Stažení detailů příběhu podle ID

Teď potřebujeme samotná data. Tady se ukáže problém fan-out: 500 příběhů znamená 500 samostatných API volání. V mém měření trvá jeden request na položku sekvenčně asi 1,2 sekundy. Pro 500 příběhů je to zhruba 10 minut.

Pro většinu použití ale 500 nepotřebujete. Tady je kód pro stažení top 30:

1def fetch_story(story_id):
2    """Stáhne detaily jednoho příběhu z HN API."""
3    resp = requests.get(f"{API_BASE}/item/{story_id}.json")
4    return resp.json()
5> This paragraph contains content that cannot be parsed and has been skipped.
6# Seřadit podle skóre, zobrazit top 10
7top = sorted(stories, key=lambda x: x["score"], reverse=True)[:10]
8pprint(top)

time.sleep(0.1) přidává malou zdvořilostní prodlevu. Firebase API nemá uvedený rate limit, ale bombardovat jakékoli API bez pauz je prostě špatná praxe.

Krok 3: Scrapování komentářů (rekurzivní průchod stromem)

Tady API opravdu září oproti HTML scrapování. Komentáře na HN jsou hluboce zanořené — odpovědi na odpovědi na odpovědi. V HTML to znamená parsovat složitou vnořenou tabulkovou strukturu. S API má každý komentář ve svém poli kids ID potomků, takže strom projdete rekurzivně.

1def fetch_comments(item_id, depth=0, max_depth=3):
2    """Rekurzivně stáhne komentáře až do max_depth."""
3    item = requests.get(f"{API_BASE}/item/{item_id}.json").json()
4    if not item or item.get("type") != "comment":
5        return []
6> This paragraph contains content that cannot be parsed and has been skipped.
7    if depth < max_depth and item.get("kids"):
8        for kid_id in item["kids"]:
9            comments.extend(fetch_comments(kid_id, depth + 1, max_depth))
10            time.sleep(0.05)
11    return comments
12# Ukázka: komentáře k nejvýše postavenému příběhu
13if stories:
14    top_story = stories[0]
15    top_story_full = requests.get(f"{API_BASE}/item/{top_story['id']}.json").json()
16    if top_story_full.get("kids"):
17        print(f"\nKomentáře pro: {top_story['title']}")
18        all_comments = []
19        for kid_id in top_story_full["kids"][:5]:  # Prvních 5 komentářů na nejvyšší úrovni
20            all_comments.extend(fetch_comments(kid_id, depth=0, max_depth=2))
21            time.sleep(0.1)
22        for c in all_comments[:15]:
23            indent = "  " * c["depth"]
24            preview = c["text"][:80].replace("\n", " ") if c["text"] else "[bez textu]"
25            print(f"{indent}[{c['author']}] {preview}...")

Tento rekurzivní přístup je výrazně jednodušší než parsování vnořených HTML vláken komentářů. Pokud potřebujete celý strom komentářů, API je správná cesta.

Krok 4: Spuštění a zobrazení výsledků

1python scrape_hn_api.py

Uvidíte strukturovaná data příběhů a pak i náhled zanořených komentářů. Data jsou čistší, přístup ke komentářům je triviální a nehrozí, že se vám scraper rozbije jen proto, že HN změnil název CSS třídy.

Nad rámec první stránky: stránkování a historická data

Většina tutoriálů na HN scraping končí na první stránce — tedy 30 příbězích. Na rychlou ukázku to stačí, ale reálné scénáře často vyžadují víc.

Scrapování více stránek pomocí BeautifulSoup

Stránkování HN používá jednoduchý vzor URL: ?p=2, ?p=3 atd. Každá stránka vrací 30 příběhů a web servíruje zhruba do 20. stránky (asi 600 příběhů celkem). Pak už jsou stránky prázdné.

1import time
2def scrape_hn_pages(num_pages=5):
3    """Scrapuje více stránek hlavního feedu HN."""
4    all_stories = []
5    for page in range(1, num_pages + 1):
6        url = f"https://news.ycombinator.com/news?p={page}"
7        response = requests.get(url, headers=headers)
8        soup = BeautifulSoup(response.text, "html.parser")
9        story_rows = soup.select("tr.athing")
10        if not story_rows:
11            print(f"Page {page}: no stories found, stopping.")
12            break
13        for row in story_rows:
14            title_tag = row.select_one("span.titleline > a")
15            if not title_tag:
16                continue
17            meta_row = row.find_next_sibling("tr")
18            score = 0
19            if meta_row and (score_tag := meta_row.select_one("span.score")):
20                score = int(score_tag.get_text().replace(" points", ""))
21> This paragraph contains content that cannot be parsed and has been skipped.
22        print(f"Page {page}: scraped {len(story_rows)} stories")
23        # Respektovat robots.txt a 30sekundovou prodlevu
24        if page < num_pages:
25            time.sleep(30)
26    return all_stories
27stories = scrape_hn_pages(5)
28print(f"\nTotal stories scraped: {len(stories)}")

time.sleep(30) je důležité. HN výslovně žádá 30sekundovou prodlevu mezi crawl requests. Ignorujte to a můžete skončit s rate limitingem (HTTP 429) nebo dočasným blokem. Pět stránek s 30sekundovými intervaly zabere asi 2,5 minuty — ne okamžitě, ale ohleduplně.

Pro uživatele, kteří nechtějí řešit stránkování v kódu, Thunderbit zvládá stránkování přes klikání i infinite scroll automaticky. Klikne na tlačítko „More“ dole na stránkách HN bez jakéhokoli nastavování.

Přístup k historickým datům Hacker News přes Algolia API

Firebase API vám dá aktuální data. Pro historickou analýzu — „Jaké byly nejlepší Python příběhy v roce 2023?“ nebo „Jak se za posledních 5 let změnilo pokrytí AI?“ — potřebujete .

1import requests
2ALGOLIA_BASE = "https://hn.algolia.com/api/v1"
3> This paragraph contains content that cannot be parsed and has been skipped.
4# Příklad: najít příběhy o Python scrapingu s 10+ body od ledna 2024
5results = search_hn(
6    query="python scraping",
7    tags="story",
8)
9print(f"Found {results['nbHits']} total results")
10for hit in results["hits"][:5]:
11    print(f"  [{hit.get('points', 0)} pts] {hit['title']}")

Pro dotazy filtrované podle data použijte numericFilters:

1import calendar, datetime
2# Příběhy od 1. ledna 2024
3start_date = datetime.datetime(2024, 1, 1)
4start_ts = int(calendar.timegm(start_date.timetuple()))
5> This paragraph contains content that cannot be parsed and has been skipped.
6Algolia API je rychlé (serverové zpracování za 59 ms), nevyžaduje API klíč a podporuje stránkování až do 500 stran. Pro hromadnou historickou analýzu je to nejlepší dostupná možnost.
7## Export scraped dat z Hacker News do CSV, Excelu a Google Sheets
8Každý HN scraping tutorial, který jsem viděl, končí výpisem z `pprint()` v terminálu. To je fajn pro ladění, ale pokud tvoříte denní digest nebo děláte analýzu trendů, potřebujete data v souboru. Tady je, jak je tam dostat.
9### Export do CSV pomocí Pythonu
10```python
11import csv
12def export_to_csv(stories, filename="hn_stories.csv"):
13    """Uloží scrapované příběhy do CSV souboru."""
14    fieldnames = ["title", "url", "score", "author", "comments"]
15    with open(filename, "w", newline="", encoding="utf-8") as f:
16        writer = csv.DictWriter(f, fieldnames=fieldnames)
17        writer.writeheader()
18        writer.writerows(stories)
19    print(f"Saved {len(stories)} stories to {filename}")
20export_to_csv(stories)

Export do Excelu pomocí Pythonu

1import pandas as pd
2def export_to_excel(stories, filename="hn_stories.xlsx"):
3    """Uloží scrapované příběhy do Excel souboru."""
4    df = pd.DataFrame(stories)
5    df.to_excel(filename, index=False, engine="openpyxl")
6    print(f"Saved {len(stories)} stories to {filename}")
7export_to_excel(stories)

Ujistěte se, že máte nainstalovaný openpyxl — pandas ho používá jako Excel engine. Pokud chybí, dostanete ImportError.

Odeslání do Google Sheets (volitelné)

Pro automatizované workflow můžete data posílat přímo do Google Sheets pomocí knihovny gspread. To vyžaduje nastavení Google Cloud service accountu (jednorázový proces):

1import gspread
2gc = gspread.service_account(filename="service_account.json")
3sh = gc.open("HN Daily Digest")
4worksheet = sh.sheet1
5# Převod stories na řádky
6header = list(stories[0].keys())
7rows = [list(s.values()) for s in stories]
8worksheet.clear()
9worksheet.update([header] + rows)
10print("Pushed to Google Sheets")

No-code alternativa exportu

Jestli nastavení service accountů a psaní exportního kódu zní jako víc práce než samotné scrapování, rozumím tomu. V Thunderbitu jsme vytvořili bezplatný export dat, díky kterému můžete odesílat scrapovaná data přímo do Excelu, Google Sheets, Airtable nebo Notion — bez kódu, bez přihlašovacích údajů, bez pipeline na údržbu. Pro jednorázové stažení dat je to upřímně rychlejší. Níže o tom víc.

Jak udělat scraper připravený pro produkci: ošetření chyb, kešování a plánování

Když scraper spouštíte jednou jen tak pro zábavu, výše uvedený kód stačí. Když ho ale spouštíte denně jako součást workflow, potřebujete ještě pár věcí.

Ošetření chyb a retry logika

Sítě selhávají. Servery omezují provoz. Jediný chybný request by neměl shodit celý scraping. Tady je retry funkce s exponenciálním backoffem:

1from tenacity import retry, stop_after_attempt, wait_exponential_jitter
2import requests
3@retry(stop=stop_after_attempt(5), wait=wait_exponential_jitter(initial=1, max=60))
4def fetch_with_retry(url):
5    """Stáhne URL s automatickými pokusy a exponenciálním backoffem."""
6    response = requests.get(url, timeout=10)
7    response.raise_for_status()
8    return response
9# Použití:
10try:
11    resp = fetch_with_retry("https://hacker-news.firebaseio.com/v0/topstories.json")
12    story_ids = resp.json()
13except Exception as e:
14    print(f"Failed after retries: {e}")

Knihovna tenacity řeší retry logiku elegantně. Zkusí request až 5krát s jitterovaným exponenciálním backoffem — začne na 1 sekundě a maximálně dosáhne 60 sekund. Dobře tím pokryjete HTTP 429 (rate limit), 503 (service unavailable) i přechodné síťové chyby.

Kešování odpovědí, abyste neprocházeli web znovu a znovu

Při vývoji budete scraper spouštět mnohokrát, zatímco ladíte parsovací logiku. Bez keše se při každém spuštění na stejné data znovu a znovu obracíte na servery HN. Knihovna requests-cache to vyřeší dvěma řádky:

1import requests_cache
2requests_cache.install_cache("hn_cache", expire_after=3600)  # Keš na 1 hodinu

Po přidání těchto řádků na začátek skriptu budou všechny requests.get() automaticky kešované v lokální SQLite databázi. Spusťte skript během hodiny 10× a jen první běh skutečně sáhne na síť. To je nástroj, který , a má to dobrý důvod.

Oddělení crawlování od parsování

Zkušení scrapovači nedají dopustit na tenhle vzor: nejdřív stáhnout surová data, až potom je parsovat. Když se vám parser pokazí, prostě ho opravíte a data rozparsujete znovu, aniž byste je museli znovu stahovat.

1import os, json
2def crawl_and_save(story_ids, output_dir="raw_data"):
3    """Stáhne data příběhů a uloží surové JSON na disk."""
4    os.makedirs(output_dir, exist_ok=True)
5    for sid in story_ids:
6        filepath = os.path.join(output_dir, f"{sid}.json")
7        if os.path.exists(filepath):
8            continue  # Přeskočit už stažené položky
9        resp = fetch_with_retry(f"{API_BASE}/item/{sid}.json")
10        with open(filepath, "w") as f:
11            json.dump(resp.json(), f)
12> This paragraph contains content that cannot be parsed and has been skipped.
13Tenhle dvoufázový přístup je obzvlášť užitečný, když scrapujete stovky položek a chcete rychle iterovat nad tím, jak data zpracováváte.
14### Automatizace scrapingu podle plánu
15Pro denní HN digest potřebujete, aby scraper běžel automaticky. Dvě běžné možnosti:
16**Možnost 1: cron (Linux/Mac)**
17```bash
18# Spustit každý den v 8:30 UTC
1930 8 * * * /usr/bin/python3 /home/user/scrape_hn.py >> /home/user/scrape.log 2>&1

Možnost 2: GitHub Actions (zdarma, bez serveru)

1name: Scrape Hacker News
2on:
3  schedule:
4    - cron: '30 8 * * *'  # Denně v 8:30 UTC
5  workflow_dispatch:        # Tlačítko pro ruční spuštění
6jobs:
7  scrape:
8    runs-on: ubuntu-latest
9    steps:
10      - uses: actions/checkout@v4
11      - uses: actions/setup-python@v6
12        with:
13          python-version: '3.12'
14      - run: pip install requests beautifulsoup4 pandas openpyxl
15      - run: python scrape_hn.py
16      - run: |
17          git config user.name "GitHub Actions Bot"
18          git config user.email "actions@github.com"
19          git add -A
20          git diff --staged --quiet || git commit -m "Update HN data $(date -u +%Y-%m-%dT%H:%M:%SZ)"
21          git push

Pár háčků u plánování v GitHub Actions: všechny cron časy jsou v UTC, zpoždění 15–60 minut je běžné (používejte třeba :30 místo :00) a GitHub může naplánované workflow vypnout u repozitářů bez aktivity po dobu 60 dnů. Vždy přidejte workflow_dispatch, abyste mohli workflow ručně spustit při testování.

Pro jednodušší variantu Thunderbit nabízí funkci Scheduled Scraper, kde můžete plán popsat normální angličtinou — třeba „scrape every morning at 8am“ — bez serveru a bez nastavování cronu.

Kdy je Python zbytečně moc: no-code způsob, jak scrapovat Hacker News

Budu upřímný, i když jsem fanoušek Pythonu a můj tým staví vývojářské nástroje. Když potřebujete jen dnešních top 100 příběhů z HN v tabulce — hned, jednorázově — psát, ladit a spouštět Python skript je zbytečná režie. Jen samotné nastavení (virtuální prostředí, instalace balíčků, hledání selektorů) zabere víc času než samotný sběr dat.

Právě sem patří . Postup vypadá takto:

  1. Otevřete news.ycombinator.com v Chrome
  2. Klikněte na ikonu rozšíření Thunderbit a pak na „AI Suggest Fields“
  3. AI přečte stránku a navrhne sloupce: Title, URL, Score, Author, Comment Count, Time Posted
  4. Pole si upravte podle potřeby (přejmenujte, odstraňte nebo přidejte vlastní — můžete přidat i AI prompt typu „Klasifikuj jako AI/DevTools/Web/Ostatní“)
  5. Klikněte na „Scrape“ — data se zobrazí ve strukturované tabulce
  6. Exportujte do Excelu, Google Sheets, Airtable nebo Notion

Dva kliky a máte strukturovaná data. Žádné selektory, žádný kód, žádná údržba.

Velká výhoda: Thunderbit se automaticky přizpůsobuje změnám rozložení. Tradiční scrapers založené na CSS selektorech se rozbijí, když web změní markup — a i když je HTML HN poměrně stabilní, měnilo se (class="athing submission" se aktualizovalo, span.titleline nahradilo starší a.storylink). AI scraper si stránku načte znovu pokaždé, takže mu změny názvů tříd nevadí.

python-vs-thunderbit-comparison.webp

Thunderbit také zvládá stránkování (automaticky kliká na tlačítko „More“ na HN) a scrapování podstránek (navštíví stránku komentářů u každého příběhu a stáhne diskusi). Pro use case je to ekvivalent rekurzivního API kódu z Metody 2 — ale bez psaní jediného řádku.

Rozhodnutí je celkem jasné: Python je správná volba, když potřebujete vlastní logiku, složité transformace dat, automatizované plánované pipeline nebo se prostě učíte programovat. Thunderbit je správná volba, když chcete data rychle, nechcete udržovat kód, nebo nejste vývojář. Vyberte si nástroj, který odpovídá vaší situaci.

Python vs. API vs. no-code: kterou metodu zvolit?

Tady je kompletní rozhodovací rámec:

KritériumBeautifulSoup (HTML)Firebase APIAlgolia APIThunderbit (no-code)
Potřebná technická úroveňStředně pokročilý PythonZačátečnický PythonZačátečnický PythonŽádná
Čas na nastavení10–15 min5–10 min5–10 min2 min
Nároky na údržbuStřední (selektory se rozbijí)Nízké (stabilní JSON)Nízké (stabilní JSON)Žádné
Hloubka datJen hlavní stránkaLibovolná položka, uživateléVyhledávání + historieHlavní stránka + podstránky
KomentářeNáročnéSnadné (rekurzivně)Snadné (vnořený strom)Scrapování podstránek
Historická dataNeNeAno (plný archiv)Ne
Možnosti exportuNaprogramujete samiNaprogramujete samiNaprogramujete samiVestavěné (Excel, Sheets atd.)
Plánovánícron / GitHub Actionscron / GitHub Actionscron / GitHub ActionsVestavěný plánovač
Nejlepší proUčení scrapováníSpolehlivé pipelineVýzkum a analýzuRychlé získání dat

Pokud se učíte Python nebo stavíte něco na míru, zvolte Metodu 1 nebo 2. Pokud potřebujete historickou analýzu, přidejte Algolia API. Pokud chcete data bez kódu, .

Závěr a klíčová zjištění

Teď máte v nástrojové sadě:

  • Dvě kompletní Python metody pro scrapování Hacker News — BeautifulSoup pro parsování HTML a Firebase API pro čistá JSON data
  • Techniky stránkování pro scrapování za první stránku, včetně Algolia API pro historická data sahající zpět do roku 2007
  • Exportní kód pro CSV, Excel a Google Sheets — protože data v terminálu jsou ostatním v týmu k ničemu
  • Produkční postupy — retry logika, kešování, oddělení crawl/parsing a plánovaná automatizace přes cron nebo GitHub Actions
  • No-code alternativu pro chvíle, kdy je Python větší nástroj, než potřebujete

Moje doporučení: pro většinu případů začněte s Firebase API (Metoda 2). Je čistší, spolehlivější a umožňuje přístup ke komentářům bez trápení s parsováním vnořeného HTML. Když potřebujete historická data, přidejte Algolia API. A si uložte do záložek pro chvíle, kdy chcete jen rychlou tabulku a nechcete rozjíždět celý Python projekt.

Pokud chcete jít víc do hloubky, zkuste scrapovat komentáře na HN pro , postavte denní digest pipeline pomocí GitHub Actions nebo prozkoumejte Algolia API a sledujte, jak se technologické trendy změnily za poslední dekádu.

Vyzkoušejte Thunderbit pro rychlé scrapování Hacker News

Často kladené otázky

Je legální scrapovat Hacker News?

Data z HN jsou veřejně dostupná a Y Combinator poskytuje oficiální API právě pro programatický přístup. webu dovoluje scrapování jen pro čtení dostupného obsahu (hlavní stránka, stránky položek, uživatelské stránky), ale žádá 30sekundovou prodlevu mezi crawl requests. Když tu prodlevu dodržíte, nesaháte na interaktivní endpointy (hlasování, přihlášení) a držíte se rozumného tempa, jste na bezpečné půdě. Více k etice scrapování najdete v našem průvodci .

Má Hacker News oficiální API?

Ano. na adrese hacker-news.firebaseio.com/v0/ je zdarma, nevyžaduje autentizaci a poskytuje přístup k příběhům, komentářům, uživatelským profilům i všem typům feedů (top, new, best, ask, show, jobs). Vrací čistý JSON a nemá uvedený rate limit, i když je vždy dobré být ohleduplný v četnosti requestů.

Jak scrapovat komentáře z Hacker News pomocí Pythonu?

Pomocí Firebase API si stáhněte položku příběhu a získejte pole kids (pole ID top-level komentářů). Každý komentář je zase položka s vlastním polem kids pro odpovědi. Strom projděte rekurzivní funkcí, která načte každý komentář a jeho potomky. Kompletní kód najdete výše v části „Scrapování komentářů (rekurzivní průchod stromem)“. Alternativně endpoint vrací celý zanořený strom komentářů v jediném requestu — výrazně rychlejší u příběhů s velkým množstvím komentářů.

Dá se Hacker News scrapovat i bez kódu?

Ano. funguje jako Chrome rozšíření — otevřete HN, klikněte na „AI Suggest Fields“ a automaticky rozpozná sloupce jako title, URL, score a author. Klikněte na „Scrape“ a exportujte přímo do Excelu, Google Sheets, Airtable nebo Notion. Zvládá stránkování a umí dokonce navštívit podstránky, aby získal i data z komentářů. Žádný Python, žádné selektory, žádná údržba.

Jak získám historická data z Hacker News?

Nejlepší nástroj pro to je . Použijte endpoint search_by_date s numericFilters=created_at_i>TIMESTAMP pro filtrování podle časového období. Můžete vyhledávat podle klíčového slova, filtrovat podle typu příběhu a stránkovat až do 500 stran výsledků. Pro hromadnou historickou analýzu jsou veřejně dostupné také datasety na (plný archiv), (28 milionů záznamů) a (4 miliony příběhů).

Další články

Obsah

Vyzkoušej Thunderbit

Sbírej leady i další data jen na 2 kliknutí. Poháněno AI.

Získat Thunderbit Je to zdarma
Extrahuj data pomocí AI
Snadno přenes data do Google Sheets, Airtable nebo Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week