Cara Saya Scrape Hacker News dengan Python (2 Metode, Kode Lengkap)

Terakhir diperbarui pada April 16, 2026

Beberapa bulan lalu, saya ingin bikin ringkasan harian berisi cerita-cerita teratas di Hacker News untuk tim kami di Thunderbit. Awalnya saya pikir cukup bookmark situsnya, lalu tiap pagi buka dan baca satu per satu. Ide itu cuma tahan sekitar tiga hari, sebelum saya sadar kalau saya habiskan 20 menit setiap hari hanya buat baca headline dan copy-paste tautan ke spreadsheet.

Hacker News adalah salah satu sumber intelijen teknologi paling kaya dan paling padat di internet — sekitar , kurang lebih 1.300 cerita baru masuk tiap hari, dan sekitar 13.000 komentar dibuat setiap hari. Entah Anda lagi memantau tren teknologi baru, mengawasi brand Anda, membangun pipeline rekrutmen dari thread "Who's Hiring", atau sekadar mau tetap paham apa yang sedang jadi perhatian dunia developer, mengikuti semuanya secara manual jelas bukan strategi yang efisien.

Kabar baiknya: scraping Hacker News dengan Python ternyata cukup gampang. Di panduan ini, saya akan tunjukkan dua metode lengkap — scraping HTML dengan BeautifulSoup dan HN Firebase API resmi — lengkap dengan pagination, ekspor data, pola siap produksi, plus jalan pintas tanpa kode kalau Python terasa terlalu ribet.

Kenapa Scrape Hacker News dengan Python?

Hacker News bukan sekadar pengumpul tautan biasa. Ini feed kurasi dari komunitas, tempat cerita teknologi paling menarik naik ke atas lewat upvote dan diskusi aktif. Audiensnya sangat didominasi profesional teknologi (), dan tingkat traffic langsung sebesar 66% menunjukkan bahwa pembacanya loyal dan rutin, bukan sekadar lewat doang.

Inilah alasan orang mengekstrak data HN:

Use CaseHasil yang Didapat
Ringkasan harian teknologiCerita teratas, skor, dan tautan dikirim ke email atau Slack
Pemantauan brand/kompetitorNotifikasi saat perusahaan atau produk Anda disebut
Analisis trenMelacak teknologi, bahasa, atau topik yang makin populer dari waktu ke waktu
RekrutmenMengurai thread "Who's Hiring" untuk lowongan, stack teknologi, dan sinyal gaji
Riset kontenMenemukan topik yang performanya tinggi untuk dijadikan bahan tulisan atau dibagikan
Analisis sentimenMengukur opini komunitas terhadap produk, peluncuran, atau perubahan industri

Perusahaan bernilai gabungan lebih dari $400 miliar — Stripe, Dropbox, Airbnb — menganggap Hacker News sebagai sumber feedback awal dan pengguna yang sangat penting. Drew Houston mem-post demo Dropbox di HN pada April 2007, dan demo itu langsung naik ke posisi #1; daftar tunggu beta melonjak dari 5.000 ke 75.000 pengguna hanya dalam satu hari. Artinya, data HN bukan cuma menarik — tapi juga punya nilai komersial.

Datanya memang terbuka untuk umum, tapi struktur situsnya bikin pengumpulan manual jadi capek. Automasi dengan Python adalah solusi yang paling masuk akal.

Dua Cara Scrape Hacker News dengan Python: Gambaran Umum

Panduan ini mencakup dua pendekatan lengkap yang bisa langsung dijalankan:

  1. Scraping HTML dengan requests + BeautifulSoup — mengambil HTML mentah dari news.ycombinator.com lalu mem-parse-nya untuk mengekstrak data cerita. Cocok untuk belajar dasar web scraping dan mengambil persis data yang tampil di halaman.
  2. Hacker News Firebase API resmi — memanggil endpoint JSON secara langsung, jadi tidak perlu parsing HTML. Lebih cocok untuk pipeline data yang andal, akses komentar, dan data historis.

Berikut perbandingan berdampingan supaya Anda bisa pilih metode yang paling pas:

KriteriaScraping HTML (requests + BS4)HN Firebase APIThunderbit (Tanpa Kode)
Kompleksitas setupSedang (parse selector HTML)Rendah (endpoint JSON)Tidak ada (ekstensi Chrome 2 klik)
Keterkinian dataReal-time halaman depanReal-time (item apa pun berdasarkan ID)Real-time
Risiko rate limitSedang (robots.txt meminta jeda crawl 30 detik)Rendah (resmi, cukup longgar)Dikelola oleh Thunderbit
Akses komentarSulit (HTML bertingkat)Mudah (ID item rekursif)Fitur scraping subpage
Data historisTerbatasLewat Algolia Search APITidak tersedia
Paling cocok untukBelajar dasar scrapingPipeline data yang andalNon-developer, ekspor cepat

Kedua metode ini dilengkapi kode Python lengkap yang bisa langsung Anda jalankan. Dan kalau Anda cuma mau datanya tanpa nulis kode sama sekali, saya juga akan bahas opsi itu.

Sebelum Mulai

  • Tingkat kesulitan: Pemula hingga menengah
  • Waktu yang dibutuhkan: ~15–20 menit per metode
  • Yang Anda perlukan:
    • Python 3.11+ terpasang
    • Terminal atau code editor
    • Browser Chrome (kalau ingin cek HTML HN atau coba opsi tanpa kode)
    • (opsional, untuk metode tanpa kode)

scrape-hacker-news-methods.webp

Menyiapkan Environment Python Anda

Sebelum menyentuh data HN, mari siapkan environment-nya dulu. Saya sarankan bikin virtual environment supaya dependensi proyek tetap rapi.

1# Buat dan aktifkan virtual environment
2python3 -m venv hn-scraper
3# macOS/Linux:
4source hn-scraper/bin/activate
5# Windows:
6hn-scraper\Scripts\activate
7# Instal paket yang dibutuhkan untuk kedua metode
8pip install requests==2.33.1 beautifulsoup4==4.14.3 pandas==3.0.2 openpyxl==3.1.5

Untuk pola produksi nanti (cache, retry), Anda juga akan butuh:

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

Tidak perlu API key khusus, tidak perlu token autentikasi. Data HN terbuka.

Metode 1: Scrape Hacker News dengan Python Menggunakan BeautifulSoup

Ini pendekatan klasik — ambil HTML, parse, lalu tarik data yang Anda butuhkan. Begini cara kebanyakan orang belajar web scraping, dan layout HN yang sederhana berbasis tabel bikin ini jadi tempat latihan yang ideal.

Langkah 1: Ambil Halaman Depan Hacker News

Buka editor Anda dan buat file bernama scrape_hn_bs4.py. Berikut kode awalnya:

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")

Jalankan. Anda seharusnya melihat Status: 200 dan panjang halaman sekitar 40.000–50.000 karakter. Itu berarti HTML mentah halaman depan HN sudah ada di memori dan siap diparse.

Langkah 2: Pahami Struktur HTML-nya

HN memakai layout berbasis tabel — bukan CSS grid atau flex modern. Setiap cerita di halaman terdiri dari dua baris <tr> utama:

  • Baris cerita (<tr class="athing submission">): berisi peringkat, judul, dan tautan
  • Baris metadata (<tr> berikutnya): berisi poin, penulis, waktu, dan jumlah komentar

Selector pentingnya:

  • span.titleline > a — judul cerita dan URL
  • span.score — jumlah vote (misalnya "118 points")
  • a.hnuser — username penulis
  • span.age — waktu posting
  • <a> terakhir di .subtext dengan teks yang berisi "comment" — jumlah komentar

Kalau Anda klik kanan pada judul cerita di Chrome lalu pilih "Inspect", Anda akan melihat sesuatu seperti ini:

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

Dan baris metadata di bawahnya:

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>

Memahami selector ini penting — kalau suatu saat markup HN berubah, Anda harus update selector-nya. (Spoiler: metode API menghindari masalah ini sepenuhnya.)

Langkah 3: Ekstrak Judul, Tautan, dan Skor

Sekarang masuk ke inti. Kita akan looping semua baris cerita, ambil judul dan tautannya dari baris cerita, lalu ambil skor dari baris metadata tepat di bawahnya.

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    # Judul dan URL dari baris cerita
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 dari baris sibling berikutnya
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# Filter cerita dengan 50+ poin, urutkan berdasarkan skor
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])

Beberapa catatan dari kode ini:

  • Operator walrus (:=) tersedia di Python 3.8+. Ini memudahkan kita meng-assign dan mengecek sekaligus — berguna untuk elemen opsional seperti span.score yang tidak selalu ada di setiap baris (misalnya job post tidak punya score).
  • HN memakai \xa0 (non-breaking space) antara angka dan kata "comments", jadi kita perlu split berdasarkan karakter itu.
  • Cerita yang mengarah ke halaman HN lain (seperti post "Ask HN") akan punya URL relatif yang dimulai dengan item?id=. Anda mungkin ingin menambahkan https://news.ycombinator.com/ untuk kasus seperti itu.

Langkah 4: Jalankan dan Lihat Hasilnya

Simpan lalu jalankan:

1python scrape_hn_bs4.py

Anda akan melihat output seperti ini:

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 ...]

Itu 30 cerita dari halaman 1. Tapi HN punya ratusan cerita aktif pada saat tertentu. Kita akan bahas pagination di bagian berikutnya.

Metode 2: Scrape Hacker News dengan Python Menggunakan API Resmi

HN Firebase API adalah cara resmi yang disediakan untuk mengakses data Hacker News. Tidak perlu autentikasi, tidak perlu API key, dan tidak perlu parsing HTML. Anda akan dapat respons JSON yang bersih. Saya pakai metode ini untuk semua kebutuhan yang harus jalan andal di production.

Endpoint API Utama yang Perlu Anda Tahu

Base URL-nya adalah https://hacker-news.firebaseio.com/v0/. Berikut endpoint yang relevan:

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

Contoh item cerita terlihat seperti ini:

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}

Field kids berisi ID komentar anak langsung. Setiap komentar juga merupakan item yang bisa punya kids sendiri — itulah struktur pohon komentar HN.

Langkah 1: Ambil ID Cerita Teratas

Buat file bernama scrape_hn_api.py:

1import requests
2import time
3from pprint import pprint
4API_BASE = "https://hacker-news.firebaseio.com/v0"
5# Ambil ID cerita teratas
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 cerita dalam satu request — tanpa parsing, tanpa selector, cuma array JSON.

Langkah 2: Ambil Detail Cerita Berdasarkan ID

Sekarang kita butuh data cerita yang sebenarnya. Di sinilah masalah fan-out muncul: 500 cerita berarti 500 panggilan API terpisah. Berdasarkan pengujian saya, setiap request item memakan waktu sekitar 1,2 detik kalau dijalankan berurutan. Untuk 500 cerita, itu kira-kira 10 menit.

Untuk sebagian besar use case, Anda tidak butuh semua 500. Berikut kode untuk ambil 30 teratas:

1def fetch_story(story_id):
2    """Ambil detail satu cerita dari 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# Urutkan berdasarkan skor, tampilkan 10 teratas
7top = sorted(stories, key=lambda x: x["score"], reverse=True)[:10]
8pprint(top)

time.sleep(0.1) menambahkan jeda kecil sebagai bentuk sopan santun. Firebase API memang tidak menyebut rate limit secara eksplisit, tapi membombardir API apa pun tanpa jeda bukan praktik yang bagus.

Langkah 3: Scrape Komentar (Tree Walk Rekursif)

Di sinilah API benar-benar unggul dibanding scraping HTML. Komentar di HN bisa bertingkat sangat dalam — balasan ke balasan ke balasan. Kalau pakai HTML, Anda harus mem-parse struktur tabel bersarang yang rumit. Dengan API, setiap komentar punya field kids berisi ID anak-anaknya, lalu kita tinggal menelusuri pohonnya secara rekursif.

1def fetch_comments(item_id, depth=0, max_depth=3):
2    """Ambil komentar secara rekursif hingga 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# Contoh: ambil komentar untuk cerita teratas
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"\nKomentar untuk: {top_story['title']}")
18        all_comments = []
19        for kid_id in top_story_full["kids"][:5]:  # 5 komentar level atas pertama
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 "[no text]"
25            print(f"{indent}[{c['author']}] {preview}...")

Pendekatan rekursif ini jauh lebih mudah dibanding mencoba mem-parse thread komentar HTML yang bertingkat. Kalau Anda butuh tree komentar penuh, API adalah pilihan terbaik.

Langkah 4: Jalankan dan Lihat Hasilnya

1python scrape_hn_api.py

Anda akan melihat data cerita yang terstruktur, lalu pratinjau komentar bertingkat. Datanya lebih bersih, akses komentarnya mudah, dan tidak ada risiko scraper Anda rusak cuma karena HN mengganti nama class CSS.

Melangkah Lebih Jauh dari Halaman 1: Pagination dan Data Historis

Kebanyakan tutorial scraping HN berhenti di halaman 1 — 30 cerita. Itu cukup untuk demo cepat, tapi use case nyata sering butuh cakupan yang lebih dalam.

Scraping Banyak Halaman dengan BeautifulSoup

Pagination HN memakai pola URL sederhana: ?p=2, ?p=3, dan seterusnya. Setiap halaman memuat 30 cerita, dan situs ini menyediakan sampai sekitar halaman 20 (kurang lebih 600 cerita total). Setelah itu, Anda akan dapat halaman kosong.

1import time
2def scrape_hn_pages(num_pages=5):
3    """Scrape beberapa halaman cerita front page 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        # Hormati crawl-delay 30 detik di robots.txt
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) itu penting. HN secara eksplisit minta jeda crawl 30 detik. Abaikan itu dan Anda bisa kena rate limit (HTTP 429) atau diblokir sementara. Lima halaman dengan interval 30 detik butuh sekitar 2,5 menit — tidak instan, tapi tetap sopan.

Buat pengguna yang tidak mau mengelola kode pagination, menangani pagination berbasis klik dan infinite scroll secara otomatis. Ia mengklik tombol "More" di bagian bawah halaman HN tanpa konfigurasi apa pun.

Mengakses Data Historis Hacker News dengan Algolia API

Firebase API memberi Anda data saat ini. Untuk analisis historis — "Apa cerita Python paling populer di 2023?" atau "Bagaimana cakupan AI berubah selama 5 tahun terakhir?" — Anda perlu .

1import requests
2ALGOLIA_BASE = "https://hn.algolia.com/api/v1"
3> This paragraph contains content that cannot be parsed and has been skipped.
4# Contoh: temukan cerita scraping Python dengan 10+ poin sejak Jan 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']}")

Untuk kueri dengan filter tanggal, pakai numericFilters:

1import calendar, datetime
2# Cerita sejak 1 Januari 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 cepat (waktu proses server 5–9 ms), tidak butuh API key, dan mendukung pagination sampai 500 halaman. Untuk analisis historis skala besar, ini opsi terbaik yang tersedia.
7## Mengekspor Data Hacker News ke CSV, Excel, dan Google Sheets
8Setiap tutorial scraping HN yang pernah saya lihat biasanya berakhir dengan output `pprint()` di terminal. Itu oke buat debugging, tapi kalau Anda sedang bikin digest harian atau analisis tren, Anda butuh datanya dalam file. Berikut cara melakukannya.
9### Ekspor ke CSV dengan Python
10```python
11import csv
12def export_to_csv(stories, filename="hn_stories.csv"):
13    """Simpan cerita hasil scrape ke file CSV."""
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)

Ekspor ke Excel dengan Python

1import pandas as pd
2def export_to_excel(stories, filename="hn_stories.xlsx"):
3    """Simpan cerita hasil scrape ke file Excel."""
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)

Pastikan openpyxl sudah terpasang — pandas memakainya sebagai engine Excel. Kalau belum ada, Anda akan dapat ImportError.

Kirim ke Google Sheets (Opsional)

Untuk workflow otomatis, Anda mungkin mau kirim data langsung ke Google Sheets pakai library gspread. Ini butuh setup Google Cloud service account sekali saja:

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

Alternatif Ekspor Tanpa Kode

Kalau menyiapkan service account dan nulis kode ekspor terasa lebih ribet daripada scraping-nya sendiri, saya paham. Di Thunderbit, kami bikin ekspor data gratis yang memungkinkan Anda kirim hasil scrape langsung ke Excel, Google Sheets, Airtable, atau Notion — tanpa kode, tanpa kredensial, tanpa pipeline yang harus dirawat. Untuk pengambilan data sekali jalan, cara ini memang jauh lebih cepat. Saya bahas lebih lanjut di bawah.

Membuat Scraper Siap Produksi: Error Handling, Caching, dan Penjadwalan

Kalau Anda menjalankan scraper sekali buat iseng, kode di atas sudah cukup. Tapi kalau Anda menjalankannya setiap hari sebagai bagian dari workflow, Anda butuh beberapa komponen tambahan.

Error Handling dan Retry Logic

Jaringan bisa gagal. Server bisa membatasi akses. Satu request buruk seharusnya tidak bikin seluruh proses scrape berhenti. Berikut fungsi retry dengan exponential backoff:

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    """Ambil URL dengan retry otomatis dan exponential backoff."""
6    response = requests.get(url, timeout=10)
7    response.raise_for_status()
8    return response
9# Penggunaan:
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}")

Library tenacity menangani logika retry dengan rapi. Ia akan coba lagi sampai 5 kali dengan exponential backoff yang diberi jitter — mulai dari 1 detik sampai maksimal 60 detik. Ini cukup bagus untuk HTTP 429 (rate limited), 503 (service unavailable), dan error jaringan sementara.

Cache Respons untuk Menghindari Crawl Ulang

Selama pengembangan, Anda mungkin akan menjalankan scraper berkali-kali sambil menyempurnakan logika parsing. Tanpa cache, tiap run akan kembali membebani server HN dengan data yang sama. Library requests-cache bisa memperbaikinya hanya dalam dua baris:

1import requests_cache
2requests_cache.install_cache("hn_cache", expire_after=3600)  # Cache selama 1 jam

Setelah baris itu ditaruh di bagian atas skrip, semua panggilan requests.get() otomatis disimpan dalam database SQLite lokal. Jalankan skrip 10 kali dalam satu jam, dan cuma run pertama yang benar-benar menyentuh jaringan. Ini tool yang , dan alasannya jelas.

Memisahkan Proses Crawling dari Parsing

Pola yang sangat disukai scraper berpengalaman: unduh data mentah dulu, parse belakangan. Jadi kalau logika parsing Anda salah, Anda tinggal perbaiki dan parse ulang tanpa harus ambil data lagi.

1import os, json
2def crawl_and_save(story_ids, output_dir="raw_data"):
3    """Ambil data cerita dan simpan JSON mentah ke 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  # Lewati item yang sudah pernah diambil
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.
13Pendekatan dua tahap ini sangat berguna saat Anda memproses ratusan item dan ingin cepat eksperimen dengan cara pengolahan datanya.
14### Mengotomatisasi Scraper dengan Jadwal
15Untuk daily digest HN, scraper Anda harus jalan otomatis. Ada dua opsi umum:
16**Opsi 1: cron (Linux/Mac)**
17```bash
18# Jalankan setiap hari pukul 8:30 UTC
1930 8 * * * /usr/bin/python3 /home/user/scrape_hn.py >> /home/user/scrape.log 2>&1

Opsi 2: GitHub Actions (gratis, tanpa server)

1name: Scrape Hacker News
2on:
3  schedule:
4    - cron: '30 8 * * *'  # Setiap hari pukul 8:30 UTC
5  workflow_dispatch:        # Tombol trigger manual
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

Ada beberapa hal yang perlu diperhatikan saat pakai jadwal GitHub Actions: semua waktu cron memakai UTC, delay 15–60 menit cukup umum terjadi (pakai waktu seperti :30 alih-alih :00), dan GitHub bisa menonaktifkan workflow terjadwal pada repo yang tidak aktif selama 60 hari. Selalu sertakan workflow_dispatch supaya Anda bisa menjalankannya manual saat testing.

Kalau Anda mau opsi yang lebih simpel, fitur Scheduled Scraper di Thunderbit memungkinkan Anda mendeskripsikan jadwal dengan bahasa biasa — misalnya "scrape setiap pagi jam 8" — tanpa perlu server atau setup cron.

Saat Python Terlalu Berlebihan: Cara Tanpa Kode untuk Scrape Hacker News

Saya jujur saja, meskipun saya suka Python dan tim saya membangun tools untuk developer. Kalau Anda cuma butuh 100 cerita teratas HN hari ini dalam spreadsheet — sekarang juga, sekali saja — menulis, debugging, dan menjalankan skrip Python itu sebenarnya kebangetan. Setup-nya saja (virtual environment, instal paket, menentukan selector) sering makan waktu lebih lama daripada proses ambil datanya sendiri.

Di sinilah sangat berguna. Alurnya seperti ini:

  1. Buka news.ycombinator.com di Chrome
  2. Klik ikon ekstensi Thunderbit, lalu pilih "AI Suggest Fields"
  3. AI membaca halaman dan mengusulkan kolom: Title, URL, Score, Author, Comment Count, Time Posted
  4. Sesuaikan field kalau perlu (ganti nama, hapus, atau tambah field kustom — Anda bahkan bisa menambah prompt AI seperti "Categorize as AI/DevTools/Web/Other")
  5. Klik "Scrape" — data muncul dalam tabel terstruktur
  6. Ekspor ke Excel, Google Sheets, Airtable, atau Notion

Dua klik untuk dapat data terstruktur. Tanpa selector, tanpa kode, tanpa maintenance.

Salah satu keunggulan besar di sini: AI Thunderbit beradaptasi otomatis terhadap perubahan layout. Scraper tradisional berbasis selector CSS sering rusak saat situs mengubah markup — dan meskipun HTML HN cukup stabil, situs ini memang pernah berubah (class="athing submission" diperbarui, span.titleline menggantikan a.storylink yang lama). Scraper berbasis AI membaca halaman dari awal setiap kali, jadi tidak peduli kalau nama class berubah.

python-vs-thunderbit-comparison.webp

Thunderbit juga menangani pagination secara otomatis (mengklik tombol "More" HN) dan scraping subpage (mengunjungi halaman komentar tiap cerita untuk ambil data diskusi). Untuk use case , itu setara dengan kode API rekursif pada Metode 2 — tapi tanpa nulis satu baris pun.

Trade-off-nya cukup jelas: Python adalah pilihan tepat saat Anda butuh logika kustom, transformasi data yang kompleks, pipeline automasi terjadwal, atau sedang belajar coding. Thunderbit lebih cocok saat Anda butuh data cepat, tidak ingin merawat kode, atau bukan developer. Pilih alat yang paling sesuai dengan kebutuhan Anda.

Python vs. API vs. Tanpa Kode: Metode Mana yang Sebaiknya Dipilih?

Berikut kerangka keputusan lengkapnya:

KriteriaBeautifulSoup (HTML)Firebase APIAlgolia APIThunderbit (Tanpa Kode)
Skill teknis yang dibutuhkanPython menengahPython pemulaPython pemulaTidak ada
Waktu setup10–15 menit5–10 menit5–10 menit2 menit
Beban maintenanceSedang (selector bisa rusak)Rendah (JSON stabil)Rendah (JSON stabil)Tidak ada
Kedalaman dataHanya halaman depanItem apa pun, userPencarian + historisHalaman depan + subpage
KomentarSulitMudah (rekursif)Mudah (tree bertingkat)Scraping subpage
Data historisTidakTidakYa (arsip lengkap)Tidak
Opsi eksporBuat sendiri dengan kodeBuat sendiri dengan kodeBuat sendiri dengan kodeBawaan (Excel, Sheets, dll.)
Penjadwalancron / GitHub Actionscron / GitHub Actionscron / GitHub ActionsScheduler bawaan
Paling cocok untukBelajar scrapingPipeline andalRiset & analisisPengambilan data cepat

Kalau Anda lagi belajar Python atau membangun sesuatu yang kustom, pilih Metode 1 atau 2. Kalau Anda butuh analisis historis, tambahkan Algolia API. Kalau Anda cuma mau datanya tanpa kode, .

Kesimpulan dan Poin Penting

Sekarang Anda punya beberapa alat di kotak perkakas Anda:

  • Dua metode Python lengkap untuk scrape Hacker News — BeautifulSoup untuk parsing HTML dan Firebase API untuk data JSON yang bersih
  • Teknik pagination untuk scraping di luar halaman 1, termasuk Algolia API untuk data historis sampai 2007
  • Kode ekspor ke CSV, Excel, dan Google Sheets — karena data di terminal tidak berguna buat orang lain di tim Anda
  • Pola siap produksi — retry logic, caching, pemisahan crawl/parse, dan automasi terjadwal via cron atau GitHub Actions
  • Alternatif tanpa kode saat Python terasa lebih besar daripada kebutuhan Anda

Rekomendasi saya: mulai dari Firebase API (Metode 2) untuk sebagian besar use case. Lebih bersih, lebih andal, dan memberi akses komentar tanpa repot parsing HTML bertingkat. Tambahkan Algolia API saat Anda butuh data historis. Dan simpan di bookmark untuk saat Anda cuma perlu spreadsheet cepat tanpa ingin bikin proyek Python penuh.

Kalau mau lebih dalam, coba scrape komentar HN untuk , bangun pipeline ringkasan harian dengan GitHub Actions, atau jelajahi Algolia API untuk melacak bagaimana tren teknologi berubah selama satu dekade terakhir.

Coba Thunderbit untuk Scraping Hacker News yang Cepat

FAQ

Data HN tersedia untuk umum, dan Y Combinator menyediakan API resmi khusus untuk akses programatik. situs ini mengizinkan scraping konten baca-saja (halaman depan, halaman item, halaman user), tetapi meminta jeda crawl 30 detik. Patuhi jedanya, jangan scrape endpoint interaktif (voting, login), dan Anda berada di jalur yang aman. Untuk pembahasan lebih lanjut tentang etika scraping, lihat panduan kami.

Apakah Hacker News punya API resmi?

Ya. di hacker-news.firebaseio.com/v0/ gratis, tidak memerlukan autentikasi, dan menyediakan akses ke cerita, komentar, profil pengguna, serta semua tipe feed (top, new, best, ask, show, jobs). API ini mengembalikan JSON yang bersih dan tidak punya rate limit yang dinyatakan secara eksplisit, meski tetap disarankan untuk menjaga frekuensi request agar sopan.

Bagaimana cara scrape komentar Hacker News dengan Python?

Dengan Firebase API, ambil item cerita untuk mendapatkan field kids (array ID komentar level atas). Setiap komentar juga merupakan item yang punya field kids sendiri untuk balasan. Telusuri pohonnya secara rekursif dengan fungsi yang mengambil setiap komentar beserta anak-anaknya. Lihat bagian "Scrape Komentar (Tree Walk Rekursif)" di atas untuk kode lengkap. Sebagai alternatif, endpoint mengembalikan seluruh tree komentar bertingkat dalam satu request — jauh lebih cepat untuk cerita dengan komentar banyak.

Bisakah saya scrape Hacker News tanpa menulis kode?

Bisa. bekerja sebagai ekstensi Chrome — buka HN, klik "AI Suggest Fields," dan sistem akan otomatis mengenali kolom seperti title, URL, score, dan author. Klik "Scrape" lalu ekspor langsung ke Excel, Google Sheets, Airtable, atau Notion. Tool ini menangani pagination dan bahkan bisa mengunjungi subpage untuk mengambil data komentar. Tanpa Python, tanpa selector, tanpa maintenance.

Bagaimana cara mendapatkan data historis Hacker News?

adalah tool terbaik untuk ini. Gunakan endpoint search_by_date dengan numericFilters=created_at_i>TIMESTAMP untuk memfilter berdasarkan rentang tanggal. Anda bisa mencari berdasarkan keyword, memfilter berdasarkan tipe cerita, dan melakukan pagination hingga 500 halaman hasil. Untuk analisis historis skala besar, dataset publik juga tersedia di (arsip lengkap), (28 juta record), dan (4 juta cerita).

Pelajari Lebih Lanjut

Daftar Isi

Coba Thunderbit

Ambil leads & data lainnya hanya dalam 2 klik. Didukung AI.

Dapatkan Thunderbit Gratis
Ekstrak Data dengan AI
Dengan mudah transfer data ke Google Sheets, Airtable, atau Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week