Product Hunt Launches Scraper avatar

Product Hunt Launches Scraper

Pricing

from $1.40 / 1,000 results

Go to Apify Store
Product Hunt Launches Scraper

Product Hunt Launches Scraper

Ranked Product Hunt launches by day, week, month or year, plus product detail. Flags the paid placements injected into the ranking, and refuses impossible dates that Product Hunt would silently serve as a different day.

Pricing

from $1.40 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Ranked Product Hunt launches by day, week, month or year, plus full product detail. HTTP-only, no API key, no OAuth, no login, no browser.

Modes

ModeWhat you get
leaderboardRanked launches for a period. daily walks a date range one day at a time; weekly, monthly and yearly fetch one board. Each row carries rank, votes, comments, tagline and topics.
productsThe full product document for slugs you name — description, category, makers, screenshots, overall rating and the pros/cons lists.

There is no keyword-search mode, by design. Product Hunt's robots.txt disallows /search* outright, so this actor does not offer it. Same for user profiles (/@*/*).

Six upstream quirks it corrects

1. robots.txt itself answered 403 — and that was not the policy

The first fetch of producthunt.com/robots.txt came back HTTP 403. Running the TLS ladder over the robots file itself showed why:

Profilerobots.txt
chrome131, safari17_0, safari18_0, safari17_2_ios, firefox133200
chrome124, chrome136, edge101, chrome99_android403 (Cloudflare)

The 403 was a Cloudflare challenge, not a policy statement. The real file names no AI crawler at all. A 403 on robots.txt is a transport problem until proven otherwise — reading it as a verdict would have discarded this target entirely.

2. An impossible date is silently served as a different real day, and both echoes lie

/leaderboard/daily/2026/13/99 -> HTTP 200, heading "April 9, 2027"
/leaderboard/daily/2026/2/31 -> HTTP 200, heading "March 3, 2026"

February 31st does not exist. Product Hunt rolls it forward rather than refusing. Neither available signal catches it:

  • <link rel="canonical"> echoes your bogus input back verbatim (/daily/2026/13/99), so the canonical-gating trick that works on Land.com, Immoweb and Otodom does nothing here.
  • The heading lies too. 2026/2/31 claims "March 3, 2026" while sharing only 1 of 19 products with the genuine March 3 page.

With no trustworthy server signal, the only correct defence is to refuse impossible dates before spending a request. This actor validates every date locally and fails loudly. Out-of-range month and week values are refused the same way.

3. Paid placements are injected into the ranking, and the obvious marker is useless

One daily board's vote counts, in list order:

388 302 235 214 182 160 145 140 132 [911] 120 115 113 112 109 [696] 106 96 93

The two bracketed entries break the descending order. They are ad slots. Grepping the card markup for the word "Promoted" matches all 19 cards — it lives in shared markup, so it is a false positive on every one.

The only honest discriminator is the numeric rank prefix: ranked entries read "1. HyNote for Mac", promoted ones read "Framer AI Agents" with no prefix. Promoted rows are kept and flagged (isPromoted, rank: null) — which of the two you want is your decision. Set includePromoted: false to drop them; they stay counted in the summary either way.

4. …except the yearly board numbers nothing at all

Boardcardsnumbered
daily1917
weekly1917
monthly1917
yearly190

The yearly board prints no rank numbers, and its votes descend cleanly (1,839 / 1,673 / 1,571 / 1,417 …) — all 19 are genuine. A flat "no prefix means promoted" rule labelled every one of them an ad.

So promoted detection is decided per page: if a board numbers some of its cards, the unnumbered ones are ads; if it numbers none, the prefix carries no signal and detection is reported as unavailable (promotedDetectionAvailable: false, pagesWithoutPromotedDetection) rather than guessed. On such a board rank falls back to list position and says so via rankFromListPosition: true.

5. Rank does not follow vote count

Boardinversions
daily1 — rank 16 has 96 votes, above rank 15's 92
monthly5, starting at the top — rank 1 has 838 votes, rank 2 has 945

Product Hunt's ordering is not a vote sort. Re-deriving rank from votes produces a different order than the site shows, so every row carries rankFollowsVotes: false and the actor never implies otherwise.

6. positiveNotes and negativeNotes can be byte-identical

On one product both lists were the same 22 entries — "all-in-one workspace", "team collaboration", "project management" … presented as both the pros and the cons. Publishing them as pros/cons would ship a confidently wrong cons column. Both are emitted verbatim plus notesListsAreIdentical, and the summary counts how many products collided, so you can see it rather than inherit it.

Output

One SEARCH_SUMMARY per run, one LAUNCH per leaderboard entry, one PRODUCT per product document, one ERROR per failure.

LAUNCH: productSlug, productUrl, productName, tagline, rank, listPosition, rankFromListPosition, isPromoted, promotedDetectionAvailable, rankFollowsVotes, votes, comments, topics, period, periodRequested, pageHeading.

PRODUCT: productName, description, applicationCategory, operatingSystem, datePublished, dateModified, imageUrl, screenshots, ratingValue, ratingCount, makers, positiveNotes, negativeNotes, notesListsAreIdentical.

Limits

  • No search and no user profiles — robots.txt disallows both.
  • No topic mode. /topics/{slug} is policy-clean and returns 200, but it renders zero leaderboard cards and its product links are polluted by navigation and footer entries (one probe picked up attio/reviews?ref=footer as if it were a product). Declared out of scope rather than shipped half-reliable.
  • Slugs cannot be guessed from a product's name — a wrong guess is an honest 404. Take them from this actor's own leaderboard output.
  • A board holds roughly 17 ranked entries plus any promoted slots; there is no deeper pagination on a leaderboard.