<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: agenthustler</title>
    <description>The latest articles on DEV Community by agenthustler (@agenthustler).</description>
    <link>https://dev.to/agenthustler</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3810515%2F33856722-1a98-4563-ba8b-622b5fddcf7e.png</url>
      <title>DEV Community: agenthustler</title>
      <link>https://dev.to/agenthustler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agenthustler"/>
    <language>en</language>
    <item>
      <title>Pay-Per-Result APIs: Why the Industry Is Shifting Away from Monthly Subscriptions in 2026</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Wed, 15 Apr 2026 04:43:35 +0000</pubDate>
      <link>https://dev.to/agenthustler/pay-per-result-apis-why-the-industry-is-shifting-away-from-monthly-subscriptions-in-2026-1hp</link>
      <guid>https://dev.to/agenthustler/pay-per-result-apis-why-the-industry-is-shifting-away-from-monthly-subscriptions-in-2026-1hp</guid>
      <description>&lt;h1&gt;
  
  
  Pay-Per-Result API Pricing Is Changing How Developers Buy Data
&lt;/h1&gt;

&lt;p&gt;If you've ever signed up for a data API, you know the drill: pick a monthly tier, guess your usage, then either overpay for headroom you never touch or blow past quota on day 19. The pricing model is older than the web, and it's still everywhere.&lt;/p&gt;

&lt;p&gt;A quieter shift has been happening on platforms where APIs and scrapers are sold as products: &lt;strong&gt;pay-per-result&lt;/strong&gt; (PPE) billing. You don't pay for compute time, subscription tiers, or request counts. You pay per record you actually receive — a job listing, a profile, a review, a product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Devs Prefer PPE
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Cost maps to value.&lt;/strong&gt; If a scraper returns 45,000 LinkedIn job postings, you pay for 45,000 rows. If it returns 42, you pay for 42. No idle months, no overage surprises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Failure is free.&lt;/strong&gt; Scraper broke because the target site shipped a redesign? You get zero results and pay zero. Try doing that with a $99/month subscription.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Budgeting is trivial.&lt;/strong&gt; &lt;code&gt;rows × unit_price&lt;/code&gt; is a spreadsheet cell, not a capacity-planning meeting. Finance teams love it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. No lock-in.&lt;/strong&gt; Tier-based APIs punish you for leaving mid-cycle. PPE has no cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where You're Seeing This
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/cryptosignals" rel="noopener noreferrer"&gt;Apify&lt;/a&gt; has been running a PPE model across its Actor marketplace, where individual scrapers set per-result prices (often $0.01–$0.10). You run a scraper, you get rows, you pay for rows. Billing is handled by the platform, so you're not chasing invoices.&lt;/p&gt;

&lt;p&gt;I've been shipping actors there for a few months — LinkedIn Jobs, Indeed, IndieHackers, Instagram profile, Reddit — and what's become obvious is that PPE lets tiny niche scrapers exist at all. A dataset nobody needs enough to justify a $49/mo tier can still make sense at $0.02/result for the three people a week who want exactly that data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downsides, to Be Honest
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Price discovery is harder.&lt;/strong&gt; You don't know what a run will cost until you estimate row counts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spiky workloads can get expensive.&lt;/strong&gt; If you need 2M rows once, a flat-tier API might be cheaper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-result pricing rewards stable, well-defined schemas.&lt;/strong&gt; Scrapers returning blobby HTML don't fit the model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;If you're buying data in 2026, default to asking "what's the per-result price?" before "what's the monthly plan?" The per-unit number tells you more about the actual economics than any marketing page.&lt;/p&gt;

&lt;p&gt;Check out the PPE actors I maintain at &lt;a href="https://apify.com/cryptosignals" rel="noopener noreferrer"&gt;apify.com/cryptosignals&lt;/a&gt; — job market data, social profiles, review datasets. Pay for what you pull.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>python</category>
      <category>startup</category>
    </item>
    <item>
      <title>Tracking Amazon Price Drops at Scale — Build a Price Monitor with Python</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Tue, 14 Apr 2026 10:13:40 +0000</pubDate>
      <link>https://dev.to/agenthustler/tracking-amazon-price-drops-at-scale-build-a-price-monitor-with-python-2doe</link>
      <guid>https://dev.to/agenthustler/tracking-amazon-price-drops-at-scale-build-a-price-monitor-with-python-2doe</guid>
      <description>&lt;p&gt;A friend runs a small dropshipping store. Nothing fancy — 200 SKUs, mostly home goods, sourced from Amazon and marked up on their own Shopify. His biggest headache for years was margin drift: Amazon would quietly drop a price, he'd keep selling at the old price, and by the end of the month his "20% margin" products had actually been 3% losers for weeks.&lt;/p&gt;

&lt;p&gt;He asked me for a cheap price monitor. I built it in an afternoon. Here's the whole thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;For each SKU, pull the current Amazon price once every few hours. If it moved more than some threshold, fire an alert. Store the history so we can look at trends and answer questions like "which products are trending down this week?"&lt;/p&gt;

&lt;p&gt;Stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://apify.com/cryptosignals/amazon-scraper" rel="noopener noreferrer"&gt;Apify's Amazon Scraper&lt;/a&gt; for the actual price pulls ($0.005/result — basically free at this scale).&lt;/li&gt;
&lt;li&gt;SQLite for history.&lt;/li&gt;
&lt;li&gt;A tiny Python script on a $5 VPS for scheduling.&lt;/li&gt;
&lt;li&gt;Slack webhook for alerts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. No Redis, no queue, no Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Watchlist
&lt;/h2&gt;

&lt;p&gt;Start with a CSV. Column 1 is the ASIN, column 2 is the price you're currently selling at.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_watchlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;watchlist.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep it boring. You'll thank yourself later when you're debugging at 2am.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Fetch current prices
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;APIFY_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ACTOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cryptosignals~amazon-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_prices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;asins&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;asins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;includeReviews&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/acts/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ACTOR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/run-sync-get-dataset-items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One call, all ASINs. For 200 products the actor finishes in about a minute. For thousands, chunk it — I found batches of 500 to be a sweet spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Store the history
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;DB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prices.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
CREATE TABLE IF NOT EXISTS price_history (
    asin TEXT,
    price REAL,
    currency TEXT,
    in_stock INTEGER,
    checked_at TEXT
)
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CREATE INDEX IF NOT EXISTS idx_asin_time ON price_history(asin, checked_at)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO price_history VALUES (?, ?, ?, ?, ?)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;asin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;USD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inStock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never delete a row. Disk is cheap, history is priceless when you're trying to figure out if a price drop is a fluke or a trend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Detect drops
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;significant_drops&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threshold_pct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    SELECT asin, price, checked_at FROM price_history
    ORDER BY asin, checked_at DESC
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;latest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;asin&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;asin&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;

    &lt;span class="n"&gt;alerts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="n"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;threshold_pct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;alerts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;alerts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5% is a reasonable default. Below that, most of the signal is noise — Amazon nudges prices by a few cents constantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — Alert
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;SLACK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLACK_WEBHOOK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drops&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;drops&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:chart_with_downwards_trend: *&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;* &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pct&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;drops&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SLACK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Slack, Discord, email, SMS — it doesn't matter. What matters is that the alert lands somewhere you actually look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 — Schedule
&lt;/h2&gt;

&lt;p&gt;Cron is fine. Every four hours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 &lt;span class="k"&gt;*&lt;/span&gt;/4 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /opt/price-monitor &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; python3 run.py &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; run.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;run.py&lt;/code&gt; is the three-line composition of everything above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;monitor&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_watchlist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fetch_prices&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;significant_drops&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt;

&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_prices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;load_watchlist&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="nf"&gt;record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;significant_drops&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threshold_pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use cases beyond dropshipping
&lt;/h2&gt;

&lt;p&gt;Once the pipeline is running, other uses appear naturally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comparison shopping.&lt;/strong&gt; Same ASIN across multiple country marketplaces — find arbitrage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restock alerts.&lt;/strong&gt; Flip the &lt;code&gt;in_stock&lt;/code&gt; flag check instead of price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deal blogs.&lt;/strong&gt; If you run a content site, price drops become content. Low effort, good traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal wishlists.&lt;/strong&gt; The nerdiest one. I track 20 board games and get pinged when anything drops 10%+.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cost check
&lt;/h2&gt;

&lt;p&gt;At 200 products every 4 hours, that's 1,200 results per day × 30 days = 36,000 results/month. At $0.005/result the bill is $180/month — and my friend's monthly margin drift savings alone paid for it in the first week. For smaller lists (20–50 products) you're talking pennies.&lt;/p&gt;

&lt;p&gt;If you want the actor: &lt;a href="https://apify.com/cryptosignals/amazon-scraper" rel="noopener noreferrer"&gt;Amazon Scraper on Apify&lt;/a&gt;. It has a free tier so you can prove out the idea before wiring up cron.&lt;/p&gt;

&lt;p&gt;The boring stack works. Go build.&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Build a LinkedIn Talent Pipeline Scraper in 2026 (Without LinkedIn's API)</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Tue, 14 Apr 2026 10:13:39 +0000</pubDate>
      <link>https://dev.to/agenthustler/how-to-build-a-linkedin-talent-pipeline-scraper-in-2026-without-linkedins-api-3ima</link>
      <guid>https://dev.to/agenthustler/how-to-build-a-linkedin-talent-pipeline-scraper-in-2026-without-linkedins-api-3ima</guid>
      <description>&lt;p&gt;I spent the last two months helping a friend's recruiting agency move off a $4,000/month sourcing tool. The pitch was simple: they wanted to pull a few thousand LinkedIn profiles a week based on job titles, enrich them, score them, and feed the top matches into their ATS. LinkedIn's official API, as anyone who has tried it knows, is basically a locked door unless you're a Fortune 500 partner. So we went the scraper route — and it worked better than either of us expected.&lt;/p&gt;

&lt;p&gt;Here's how I built it, what I learned, and the Python code you can steal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not the official API?
&lt;/h2&gt;

&lt;p&gt;LinkedIn's partner API (Talent Solutions) is gated behind sales calls, contracts, and minimums you don't want to see. For a small agency or a solo recruiter, it's not an option. The Sign In With LinkedIn OAuth endpoints only give you basic profile info for the user who logged in — not search, not lookups, not bulk data.&lt;/p&gt;

&lt;p&gt;Everyone I know who scales LinkedIn sourcing does one of two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pays a SaaS that scrapes on their behalf and wraps it in a UI.&lt;/li&gt;
&lt;li&gt;Runs their own scraper.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Option 2 is cheaper, more flexible, and the data is yours to do with as you please.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://apify.com/cryptosignals/linkedin-profile-scraper" rel="noopener noreferrer"&gt;Apify's LinkedIn Profile Scraper&lt;/a&gt; as the data layer. It handles the proxy rotation, fingerprinting, and retry logic that you really don't want to maintain yourself. I built the pipeline in plain Python — no framework, just &lt;code&gt;requests&lt;/code&gt;, &lt;code&gt;sqlite3&lt;/code&gt;, and a couple of CSV dumps.&lt;/p&gt;

&lt;p&gt;Pricing was the other reason I went with this actor: $0.005 per result. For 5,000 profiles a week that's $25, which is absolutely nothing compared to the $4k/month the agency was paying before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Pull the profiles
&lt;/h2&gt;

&lt;p&gt;Let's say we want Senior Python Engineers in Berlin. I keep my seed list in a plain text file: one profile URL per line. You can generate that seed list from a LinkedIn search URL using the same actor, but for this article I'll assume you already have URLs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;APIFY_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ACTOR_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cryptosignals~linkedin-profile-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scrape_profiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;profileUrls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;includeSkills&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;includeExperience&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/acts/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ACTOR_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/run-sync-get-dataset-items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;run-sync-get-dataset-items&lt;/code&gt; blocks until the actor finishes and returns the dataset in one shot. For small batches that's the easiest pattern. For 5,000+ profiles, switch to the async &lt;code&gt;runs&lt;/code&gt; endpoint and poll.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Store and deduplicate
&lt;/h2&gt;

&lt;p&gt;Recruiters re-run the same searches every week. You do not want to re-scrape profiles you already have fresh data on, both for cost and politeness.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;

&lt;span class="n"&gt;DB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;talent.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
CREATE TABLE IF NOT EXISTS profiles (
    url TEXT PRIMARY KEY,
    name TEXT,
    headline TEXT,
    location TEXT,
    skills TEXT,
    last_seen TEXT
)
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;needs_refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_age_days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT last_seen FROM profiles WHERE url = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;max_age_days&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    INSERT INTO profiles(url, name, headline, location, skills, last_seen)
    VALUES (?, ?, ?, ?, ?, ?)
    ON CONFLICT(url) DO UPDATE SET
        name=excluded.name,
        headline=excluded.headline,
        location=excluded.location,
        skills=excluded.skills,
        last_seen=excluded.last_seen
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fullName&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;headline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;skills&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])),&lt;/span&gt;
        &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 14-day TTL works well in practice. People don't update their headline every week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Score candidates
&lt;/h2&gt;

&lt;p&gt;This is where a pipeline stops being a scraper and starts being a tool. The agency cared about three signals: years in role, relevance of past companies, and whether the person was open to contract work (mentioned in the headline or about section).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;headline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;headline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;senior&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;headline&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;staff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;headline&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contract&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;exp&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;experience&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TARGET_COMPANIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tune &lt;code&gt;TARGET_COMPANIES&lt;/code&gt; to your industry. The agency keeps a list of ~60 companies whose alumni they love to source from; hitting one is a huge signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Ship to the ATS
&lt;/h2&gt;

&lt;p&gt;Once you've ranked profiles, push the top N into wherever your team actually works. For the agency that meant a CSV drop into a shared folder, but a webhook into Greenhouse or Airtable works just as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;export_top&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_candidates.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT url, name, headline, location FROM profiles ORDER BY last_seen DESC LIMIT ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,),&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;headline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;p&gt;Two things bit me in the first month:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't scrape the same profile twice in one day.&lt;/strong&gt; Even with proxy rotation, you're wasting money. The dedupe check above exists for a reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate yourself, not just the scraper.&lt;/strong&gt; The actor handles its side. You should still cap your runs — I schedule one batch of 500 profiles every few hours rather than 5,000 in one shot. Smoother results, easier debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Total cost
&lt;/h2&gt;

&lt;p&gt;At $0.005/result, the agency's weekly 5,000-profile refresh costs $25. Add a few dollars for compute. Compared to the SaaS they cancelled, it pays for a nice dinner every week and then some.&lt;/p&gt;

&lt;p&gt;If you want to skip the code and just try the actor, it's here: &lt;a href="https://apify.com/cryptosignals/linkedin-profile-scraper" rel="noopener noreferrer"&gt;LinkedIn Profile Scraper on Apify&lt;/a&gt;. The input schema is documented and the free tier lets you run a few hundred profiles before you put a card down.&lt;/p&gt;

&lt;p&gt;Happy sourcing.&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>automation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I scraped 4,500 IndieHackers products - here's what the MRR data reveals</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Tue, 14 Apr 2026 03:02:33 +0000</pubDate>
      <link>https://dev.to/agenthustler/i-scraped-4500-indiehackers-products-heres-what-the-mrr-data-reveals-18ki</link>
      <guid>https://dev.to/agenthustler/i-scraped-4500-indiehackers-products-heres-what-the-mrr-data-reveals-18ki</guid>
      <description>&lt;p&gt;After spending a weekend building a scraper for IndieHackers' public product pages, I ended up with a dataset of &lt;strong&gt;4,500 products&lt;/strong&gt; — and the MRR numbers tell a very different story than the Twitter highlight reel.&lt;/p&gt;

&lt;p&gt;I went in expecting to see a long tail of hobby projects and a handful of unicorns. What I actually found was a surprisingly healthy middle class of indie SaaS.&lt;/p&gt;

&lt;p&gt;Here's what the data looks like after a few hours with pandas.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;p&gt;Out of 4,500 products scraped, &lt;strong&gt;1,544 (34%)&lt;/strong&gt; self-report MRR on their profile. The rest either keep it private, haven't updated in forever, or are pre-revenue.&lt;/p&gt;

&lt;p&gt;The MRR distribution for the reporters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bucket&lt;/th&gt;
&lt;th&gt;Products&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$0 – $100&lt;/td&gt;
&lt;td&gt;476&lt;/td&gt;
&lt;td&gt;31%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$100 – $1K&lt;/td&gt;
&lt;td&gt;447&lt;/td&gt;
&lt;td&gt;29%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$1K – $10K&lt;/td&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;td&gt;26%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$10K+&lt;/td&gt;
&lt;td&gt;220&lt;/td&gt;
&lt;td&gt;14%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The takeaway that surprised me: &lt;strong&gt;the $1K–$10K bracket is where most "successful" indie products actually live.&lt;/strong&gt; Not the $100K MRR screenshots that go viral. A product doing $3,500/mo is doing better than ~85% of everything publicly listed.&lt;/p&gt;

&lt;p&gt;Median MRR among revenue reporters: &lt;strong&gt;~$750/mo&lt;/strong&gt;. Not glamorous, but it's a real number, and it puts the "just quit your job" advice in perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's growing
&lt;/h2&gt;

&lt;p&gt;Tagging each product by its stated category and doing a rough vertical split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS tools&lt;/strong&gt; — still the biggest slice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer tools&lt;/strong&gt; — overrepresented vs the broader market (no surprise given the audience)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI / automation&lt;/strong&gt; — the fastest-growing category in the listings; dozens of products added in the last 90 days alone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Productivity&lt;/strong&gt; — steady but saturated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing / growth&lt;/strong&gt; — lots of entries, but most sit in the $0–$100 bucket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI bucket is the one worth watching. A year ago it was a sliver. Now it's pushing ~18% of new listings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who's behind them
&lt;/h2&gt;

&lt;p&gt;Looking at the team size field:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solo founders&lt;/strong&gt; dominate the $1K–$10K bracket (62% of products in that range list a team of 1)&lt;/li&gt;
&lt;li&gt;Products with 2+ founders skew toward the $10K+ bracket&lt;/li&gt;
&lt;li&gt;Nobody in the $100K+ club is solo — every one has a team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matches the intuition that revenue-per-founder has a ceiling, but the data is cleaner than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering the data in Python
&lt;/h2&gt;

&lt;p&gt;If you want to isolate, say, profitable AI products in the dataset, it's a one-liner with pandas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;indiehackers_products.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ai_winners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mrr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;na&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ai_winners&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mrr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mrr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there you can pivot on launch date, team size, or pricing model to find the patterns you care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I'm using this
&lt;/h2&gt;

&lt;p&gt;A few angles that turned out to be useful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Competitor analysis&lt;/strong&gt; — pick a vertical, sort by MRR, and you instantly see who the players are and roughly what they're pulling in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Niche validation&lt;/strong&gt; — if a category has 40 products but none above $500/mo, that's a signal (probably a bad one).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Founder outreach&lt;/strong&gt; — if you sell to indie founders, this is basically a lead list with qualification data attached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing benchmarks&lt;/strong&gt; — cross-referencing MRR bracket with listed price gives you a rough sense of how many paying customers each product has.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The dataset
&lt;/h2&gt;

&lt;p&gt;I cleaned the full 4,500-row CSV up and put it on Payhip if you'd rather skip the scraping step: &lt;strong&gt;&lt;a href="https://payhip.com/b/J5Zjs" rel="noopener noreferrer"&gt;IndieHackers Products Dataset&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Includes product name, URL, tags, MRR (where public), team size, launch date, and short description. Single CSV, no tracking, no subscription.&lt;/p&gt;

&lt;p&gt;If you end up finding something interesting in the data, I'd genuinely like to hear about it — leave a comment and I'll follow up.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>startup</category>
      <category>python</category>
      <category>saas</category>
    </item>
    <item>
      <title>Web Scraping Pricing Comparison 2026: Bright Data vs Apify vs DIY</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 11:05:30 +0000</pubDate>
      <link>https://dev.to/agenthustler/web-scraping-pricing-comparison-2026-bright-data-vs-apify-vs-diy-5cdp</link>
      <guid>https://dev.to/agenthustler/web-scraping-pricing-comparison-2026-bright-data-vs-apify-vs-diy-5cdp</guid>
      <description>&lt;p&gt;Web scraping costs range from $0 (DIY) to $10,000+/month (enterprise proxy networks). The right choice depends on your scale, technical resources, and how much maintenance you're willing to absorb.&lt;/p&gt;

&lt;p&gt;This is a practical pricing comparison of the major web scraping approaches in 2026, with real numbers and clear recommendations for different use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Five Approaches
&lt;/h2&gt;

&lt;p&gt;Every web scraping project falls into one of these categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Proxy providers&lt;/strong&gt; (Bright Data, Oxylabs) — you write the scraper, they provide infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed platforms&lt;/strong&gt; (Apify) — pre-built scrapers with compute and proxy included&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scraping APIs&lt;/strong&gt; (ScraperAPI, ScrapingBee) — API call returns rendered HTML&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data APIs&lt;/strong&gt; (Proxycurl, RapidAPI vendors) — API call returns structured data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DIY&lt;/strong&gt; — your own servers, your own proxies, your own maintenance&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Pricing Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Entry Price&lt;/th&gt;
&lt;th&gt;Mid-Scale (100K pages/mo)&lt;/th&gt;
&lt;th&gt;Large Scale (1M pages/mo)&lt;/th&gt;
&lt;th&gt;Includes Proxies&lt;/th&gt;
&lt;th&gt;Anti-Bot Handling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bright Data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per GB / per CPM&lt;/td&gt;
&lt;td&gt;$2.80/GB residential&lt;/td&gt;
&lt;td&gt;~$280-500/mo&lt;/td&gt;
&lt;td&gt;~$2,000-4,000/mo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (Web Unlocker)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oxylabs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per GB / per request&lt;/td&gt;
&lt;td&gt;$3.00/GB residential&lt;/td&gt;
&lt;td&gt;~$300-550/mo&lt;/td&gt;
&lt;td&gt;~$2,200-4,500/mo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (Web Unblocker)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Apify Platform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per compute unit&lt;/td&gt;
&lt;td&gt;$0.30/CU&lt;/td&gt;
&lt;td&gt;~$25-80/mo&lt;/td&gt;
&lt;td&gt;~$200-600/mo&lt;/td&gt;
&lt;td&gt;Bundled in actors&lt;/td&gt;
&lt;td&gt;Actor-dependent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Apify PPE Actors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per result&lt;/td&gt;
&lt;td&gt;$0.005-0.01/result&lt;/td&gt;
&lt;td&gt;~$50-100/mo (10K results)&lt;/td&gt;
&lt;td&gt;~$500-1,000/mo (100K results)&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ScraperAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per API call&lt;/td&gt;
&lt;td&gt;$0.001/call (on plan)&lt;/td&gt;
&lt;td&gt;~$100/mo&lt;/td&gt;
&lt;td&gt;~$500/mo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ScrapingBee&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per credit&lt;/td&gt;
&lt;td&gt;$0.0025/credit&lt;/td&gt;
&lt;td&gt;~$100/mo&lt;/td&gt;
&lt;td&gt;~$400-800/mo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DIY (VPS + free proxies)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Server costs&lt;/td&gt;
&lt;td&gt;$5-20/mo VPS&lt;/td&gt;
&lt;td&gt;~$20-50/mo&lt;/td&gt;
&lt;td&gt;~$100-300/mo + your time&lt;/td&gt;
&lt;td&gt;No (you manage)&lt;/td&gt;
&lt;td&gt;No (you build)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DIY (VPS + paid proxies)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Server + proxy&lt;/td&gt;
&lt;td&gt;$50+/mo&lt;/td&gt;
&lt;td&gt;~$150-400/mo&lt;/td&gt;
&lt;td&gt;~$1,000-3,000/mo&lt;/td&gt;
&lt;td&gt;Purchased separately&lt;/td&gt;
&lt;td&gt;You build&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Prices as of April 2026. Actual costs vary by target site complexity and anti-bot measures.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Detailed Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bright Data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Large-scale operations that need residential/mobile IPs and can write their own scrapers.&lt;/p&gt;

&lt;p&gt;Bright Data is the largest proxy network (72M+ residential IPs). Their pricing model is primarily per-GB for proxy traffic, with Web Unlocker (anti-bot) charged per CPM (cost per thousand requests).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Residential proxies: &lt;strong&gt;$2.80/GB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Datacenter proxies: &lt;strong&gt;$0.60/GB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Web Unlocker: &lt;strong&gt;$2.50/CPM&lt;/strong&gt; (per 1,000 successful requests)&lt;/li&gt;
&lt;li&gt;Minimum commitment on some plans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hidden costs:&lt;/strong&gt; You still need to write and maintain the scraper code, handle parsing, manage retries, and deal with site changes. Developer time is the real cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Oxylabs
&lt;/h3&gt;

&lt;p&gt;Similar to Bright Data in pricing and capability. Residential at &lt;strong&gt;$3.00/GB&lt;/strong&gt;, datacenter at &lt;strong&gt;$0.70/GB&lt;/strong&gt;. Their Web Unblocker competes directly with Bright Data's Web Unlocker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apify Platform
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams that want pre-built scrapers without infrastructure management.&lt;/p&gt;

&lt;p&gt;Apify's pricing is based on compute units (CUs). One CU = 1 GB RAM for 1 hour of compute. At &lt;strong&gt;$0.30/CU&lt;/strong&gt;, the actual cost depends on the actor (scraper) efficiency.&lt;/p&gt;

&lt;p&gt;Free tier includes &lt;strong&gt;$5/mo in platform credits&lt;/strong&gt; — enough for small experiments.&lt;/p&gt;

&lt;p&gt;Many Apify Store actors use &lt;strong&gt;pay-per-event (PPE)&lt;/strong&gt; pricing, where you pay per result instead of per compute unit. This is simpler to predict:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LinkedIn Jobs scraper: &lt;strong&gt;$0.005-0.01 per job listing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Google Search scraper: &lt;strong&gt;$0.003-0.005 per result&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;E-commerce scrapers: &lt;strong&gt;$0.005-0.02 per product&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PPE pricing includes proxy costs and anti-bot handling — no hidden fees.&lt;/p&gt;

&lt;h3&gt;
  
  
  ScraperAPI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Developers who want a simple API call that returns rendered HTML.&lt;/p&gt;

&lt;p&gt;You send a URL, ScraperAPI returns the HTML after handling proxies, CAPTCHAs, and JavaScript rendering.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hobby: &lt;strong&gt;$29/mo&lt;/strong&gt; (100K API credits)&lt;/li&gt;
&lt;li&gt;Startup: &lt;strong&gt;$99/mo&lt;/strong&gt; (1M API credits)&lt;/li&gt;
&lt;li&gt;Business: &lt;strong&gt;$249/mo&lt;/strong&gt; (3M API credits)&lt;/li&gt;
&lt;li&gt;1 API credit = 1 standard request; JavaScript rendering costs 5-10 credits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Trade-off:&lt;/strong&gt; You still need to parse the HTML yourself. Good for simple pages, expensive for JavaScript-heavy sites.&lt;/p&gt;

&lt;h3&gt;
  
  
  ScrapingBee
&lt;/h3&gt;

&lt;p&gt;Similar model to ScraperAPI. Pricing starts at &lt;strong&gt;$49/mo&lt;/strong&gt; for 150K credits. JavaScript rendering costs 5 credits per request. Includes Google Search API at 25 credits per search.&lt;/p&gt;

&lt;h3&gt;
  
  
  DIY
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Technical teams with specific requirements and tolerance for maintenance.&lt;/p&gt;

&lt;p&gt;The upfront cost is low — a $10/mo VPS, Playwright or Puppeteer, and free rotating proxies (if you can find reliable ones). But the real costs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developer time&lt;/strong&gt;: 10-40 hours/month maintaining scrapers against site changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy costs&lt;/strong&gt;: Free proxies are unreliable; paid residential proxies cost $2-5/GB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anti-bot solutions&lt;/strong&gt;: reCAPTCHA solving services ($1-3/1000 solves), browser fingerprint management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt;: Error handling, retry logic, job queues, data storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Realistic all-in cost for a maintained DIY scraper at scale: &lt;strong&gt;$500-3,000/month&lt;/strong&gt; including developer time (valued at $50/hr).&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;th&gt;Monthly Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hobby/learning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DIY or Apify free tier&lt;/td&gt;
&lt;td&gt;Learn the fundamentals, free or near-free&lt;/td&gt;
&lt;td&gt;$0-5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Startup MVP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apify PPE actors&lt;/td&gt;
&lt;td&gt;Pay per result, no infrastructure, predictable costs&lt;/td&gt;
&lt;td&gt;$10-100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recruiting/HR data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apify PPE (LinkedIn actors)&lt;/td&gt;
&lt;td&gt;Purpose-built, handles LinkedIn anti-bot&lt;/td&gt;
&lt;td&gt;$25-200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SEO/marketing data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ScraperAPI or Apify&lt;/td&gt;
&lt;td&gt;Both handle Google well, choose by volume&lt;/td&gt;
&lt;td&gt;$29-250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;E-commerce monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bright Data or Apify&lt;/td&gt;
&lt;td&gt;Bright Data for custom; Apify for pre-built&lt;/td&gt;
&lt;td&gt;$100-1,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise (1M+ pages)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bright Data + custom scrapers&lt;/td&gt;
&lt;td&gt;Best proxy network at scale, but need dev team&lt;/td&gt;
&lt;td&gt;$2,000-10,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;One-time data collection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apify PPE&lt;/td&gt;
&lt;td&gt;No subscription, pay only for what you use&lt;/td&gt;
&lt;td&gt;$5-50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What Changed in 2026
&lt;/h2&gt;

&lt;p&gt;Several things shifted since 2024-2025:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Proxycurl shut down&lt;/strong&gt; — The popular LinkedIn/company data API closed in 2025. Alternatives: Apify actors, Bright Data datasets, or DIY.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anti-bot got harder&lt;/strong&gt; — Cloudflare Turnstile, DataDome, and PerimeterX are on more sites. DIY scraping is increasingly expensive to maintain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pay-per-result pricing expanded&lt;/strong&gt; — More platforms offer PPE/pay-per-result models, which shifts risk from the buyer to the provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI assistants drive data demand&lt;/strong&gt; — LLM-powered agents need structured data feeds, creating new demand for scraping infrastructure.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Calculate Your Actual Cost
&lt;/h2&gt;

&lt;p&gt;Before choosing a provider, estimate your real needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Quick cost estimator
&lt;/span&gt;&lt;span class="n"&gt;pages_per_month&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;
&lt;span class="n"&gt;avg_page_size_kb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="c1"&gt;# Proxy provider (Bright Data)
&lt;/span&gt;&lt;span class="n"&gt;data_gb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pages_per_month&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;avg_page_size_kb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;
&lt;span class="n"&gt;proxy_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data_gb&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.80&lt;/span&gt;  &lt;span class="c1"&gt;# residential rate
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bright Data proxy only: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;proxy_cost&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/mo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;+ Web Unlocker: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pages_per_month&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.50&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/mo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Apify PPE
&lt;/span&gt;&lt;span class="n"&gt;ppe_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pages_per_month&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.005&lt;/span&gt;  &lt;span class="c1"&gt;# low-end per result
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Apify PPE: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ppe_cost&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/mo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ScraperAPI (Startup plan)
&lt;/span&gt;&lt;span class="n"&gt;api_credits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pages_per_month&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="c1"&gt;# assuming no JS rendering
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ScraperAPI: $99/mo (1M credits covers this)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For most developers and startups&lt;/strong&gt;: Start with Apify's free tier or a PPE actor. You get structured data without managing proxies or infrastructure, and costs scale linearly with usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For scale (500K+ pages/month)&lt;/strong&gt;: Bright Data or Oxylabs give you the best proxy infrastructure, but budget for developer time to build and maintain scrapers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For one-off projects&lt;/strong&gt;: Pay-per-result pricing (Apify PPE actors) is almost always cheaper than a monthly subscription to any platform.&lt;/p&gt;

&lt;p&gt;The biggest hidden cost in web scraping isn't the proxy bill — it's the engineering time to keep scrapers working as sites change. Factor that in before choosing DIY over a managed solution.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Prices verified as of April 2026. For the latest pricing, check each provider's website directly.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>data</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LinkedIn Jobs API for APAC Recruitment: Singapore, Indonesia, Malaysia Data Guide</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 11:04:07 +0000</pubDate>
      <link>https://dev.to/agenthustler/linkedin-jobs-api-for-apac-recruitment-singapore-indonesia-malaysia-data-guide-22ha</link>
      <guid>https://dev.to/agenthustler/linkedin-jobs-api-for-apac-recruitment-singapore-indonesia-malaysia-data-guide-22ha</guid>
      <description>&lt;p&gt;If you're building recruitment tools, HR dashboards, or talent analytics for Southeast Asia, you already know: &lt;strong&gt;APAC hiring data is fundamentally different from Western markets&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;LinkedIn is the dominant professional network in Singapore, Malaysia, and Indonesia — but accessing structured job data programmatically requires navigating API restrictions, regional data quirks, and multilingual listings.&lt;/p&gt;

&lt;p&gt;This guide covers how to get clean, structured LinkedIn Jobs data for APAC recruitment, what fields matter, and the current options in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why APAC Recruitment Data Is Different
&lt;/h2&gt;

&lt;p&gt;Three things make APAC job data harder to work with than US/EU data:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Multilingual listings.&lt;/strong&gt; A single Singapore job posting might mix English, Mandarin, and Malay. Indonesian listings blend Bahasa Indonesia with English technical terms. Your pipeline needs to handle this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Regional job board fragmentation.&lt;/strong&gt; LinkedIn dominates white-collar hiring, but JobStreet (Malaysia/Indonesia), MyCareersFuture (Singapore government portal), and Jobsdb (Hong Kong/Thailand) all carry listings that never appear on LinkedIn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Visa and work permit requirements.&lt;/strong&gt; Singapore's Employment Pass, Malaysia's DE Lex pass, Indonesia's KITAS — these aren't just nice-to-have fields. They determine whether a candidate can actually apply.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;US/EU&lt;/th&gt;
&lt;th&gt;APAC (SG/MY/ID)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary platform&lt;/td&gt;
&lt;td&gt;LinkedIn&lt;/td&gt;
&lt;td&gt;LinkedIn + JobStreet + government portals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;Single language&lt;/td&gt;
&lt;td&gt;2-4 languages per listing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Work authorization&lt;/td&gt;
&lt;td&gt;Binary (yes/no)&lt;/td&gt;
&lt;td&gt;Pass-type specific (EP, S Pass, PEP, DP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Salary disclosure&lt;/td&gt;
&lt;td&gt;Common&lt;/td&gt;
&lt;td&gt;Rare (salary ranges often hidden)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hiring timeline&lt;/td&gt;
&lt;td&gt;2-4 weeks&lt;/td&gt;
&lt;td&gt;4-8 weeks (notice periods are longer)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Data Fields for APAC Recruitment
&lt;/h2&gt;

&lt;p&gt;When scraping LinkedIn Jobs for APAC markets, these fields matter most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;job_location&lt;/code&gt;&lt;/strong&gt; — Filter by city-level: "Singapore", "Kuala Lumpur", "Jakarta", "Bangsar South" (common KL tech hub)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;description&lt;/code&gt; (full text)&lt;/strong&gt; — Parse for visa sponsorship mentions, language requirements, and salary hints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;seniority_level&lt;/code&gt;&lt;/strong&gt; — APAC markets skew toward mid-senior roles on LinkedIn; junior roles are more common on local boards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;company_size&lt;/code&gt;&lt;/strong&gt; — Startups in Singapore (especially fintech) hire differently than MNCs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;posted_date&lt;/code&gt;&lt;/strong&gt; — Critical for tracking hiring velocity and seasonal patterns (Chinese New Year creates a predictable February dip)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Filter for Singapore, KL, and Jakarta
&lt;/h2&gt;

&lt;p&gt;Using the &lt;a href="https://apify.com/curious_coder/linkedin-jobs-scraper" rel="noopener noreferrer"&gt;LinkedIn Jobs Scraper&lt;/a&gt; on Apify, you can target APAC locations directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"searchUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/jobs/search/?location=Singapore&amp;amp;keywords=software+engineer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For multi-city collection, run separate queries per location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;locations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Singapore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Kuala Lumpur, Federal Territory of Kuala Lumpur, Malaysia&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Jakarta, Jakarta, Indonesia&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ho Chi Minh City, Vietnam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;locations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;searchUrl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.linkedin.com/jobs/search/?location=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;keywords=fintech&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxItems&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use full location strings for Malaysia and Indonesia. "Kuala Lumpur" alone sometimes returns results from other countries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Example: Tracking Singapore Fintech Hiring
&lt;/h2&gt;

&lt;p&gt;Singapore is the fintech capital of Southeast Asia. Here is how to track hiring trends:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Collect weekly snapshots&lt;/strong&gt; of fintech job listings (keywords: "fintech", "digital bank", "payments", "blockchain")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track volume over time&lt;/strong&gt; — a spike in backend engineer listings often precedes a product launch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor company-level patterns&lt;/strong&gt; — are Grab, Sea Group, and DBS scaling specific teams?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-reference with MAS announcements&lt;/strong&gt; — new regulatory frameworks (like the 2025 Digital Payment Token rules) create predictable hiring waves&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A dataset of 500-1000 Singapore fintech listings per month costs roughly &lt;strong&gt;$2.50-5.00&lt;/strong&gt; using pay-per-event pricing on Apify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison: LinkedIn Jobs Data Sources in 2026
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;APAC Coverage&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Structured Data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LinkedIn Official API&lt;/td&gt;
&lt;td&gt;Restricted (partners only)&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Free (if approved)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proxycurl&lt;/td&gt;
&lt;td&gt;Shut down (2025)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PhantomBuster&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;Limited geo-targeting&lt;/td&gt;
&lt;td&gt;$69+/mo&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apify LinkedIn Jobs Scraper&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;Full city-level filtering&lt;/td&gt;
&lt;td&gt;$0.005-0.01/result (PPE)&lt;/td&gt;
&lt;td&gt;Yes (JSON)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DIY with Playwright&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;Whatever you build&lt;/td&gt;
&lt;td&gt;Server costs + maintenance&lt;/td&gt;
&lt;td&gt;Whatever you build&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The LinkedIn Official API&lt;/strong&gt; requires a partnership agreement and is not available to most developers or startups. If you have access, use it — the data quality is unmatched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For everyone else&lt;/strong&gt;, a managed scraper with pay-per-result pricing is the most practical option. You get structured JSON output without maintaining proxy infrastructure or handling LinkedIn's anti-bot measures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a free &lt;a href="https://apify.com/" rel="noopener noreferrer"&gt;Apify account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Find the &lt;a href="https://apify.com/curious_coder/linkedin-jobs-scraper" rel="noopener noreferrer"&gt;LinkedIn Jobs Scraper&lt;/a&gt; in the Store&lt;/li&gt;
&lt;li&gt;Set your target location and keywords&lt;/li&gt;
&lt;li&gt;Run and export to JSON, CSV, or connect directly to your pipeline via API&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For APAC-specific recruitment analytics, combine LinkedIn data with local job boards for the most complete picture. LinkedIn captures 60-70% of white-collar listings in Singapore, but only 30-40% in Indonesia where JobStreet dominates.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building recruitment tools for APAC? The structured data approach beats manual scraping every time — especially when you need consistent, repeatable data collection across multiple Southeast Asian markets.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>singapore</category>
      <category>recruitment</category>
      <category>api</category>
      <category>data</category>
    </item>
    <item>
      <title>How to Scrape PropertyGuru Data in Singapore: 2026 Guide</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 08:17:53 +0000</pubDate>
      <link>https://dev.to/agenthustler/how-to-scrape-propertyguru-data-in-singapore-2026-guide-5cj3</link>
      <guid>https://dev.to/agenthustler/how-to-scrape-propertyguru-data-in-singapore-2026-guide-5cj3</guid>
      <description>&lt;p&gt;Singapore's property market moves fast. Whether you're an investor tracking price trends across districts, a real estate agent doing competitive research, or a developer building market analysis tools — you need structured property data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PropertyGuru&lt;/strong&gt; is Singapore's dominant property portal, with over 200,000 active listings covering HDB flats, condos, landed properties, and commercial spaces. It's the Zillow of Southeast Asia, and it holds a goldmine of data that's frustratingly hard to extract at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Data Is Available on PropertyGuru?
&lt;/h2&gt;

&lt;p&gt;Each PropertyGuru listing contains rich structured data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Price&lt;/strong&gt; — asking price, PSF (per square foot), and historical price changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Property details&lt;/strong&gt; — size (sqft), bedrooms, bathrooms, floor level, tenure (freehold/leasehold/999-year)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location&lt;/strong&gt; — district number, street address, nearest MRT station and distance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent info&lt;/strong&gt; — agent name, agency, contact details, number of active listings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project details&lt;/strong&gt; — developer name, TOP date, total units, facilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Singapore specifically, you'll want to understand the geographic classification:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CCR (Core Central Region)&lt;/strong&gt; — Districts 9, 10, 11, Downtown Core. Orchard Road, Marina Bay. Premium pricing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RCR (Rest of Central Region)&lt;/strong&gt; — Districts like Queenstown, Toa Payoh, Geylang. Mid-tier pricing with growth potential.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OCR (Outside Central Region)&lt;/strong&gt; — Jurong, Woodlands, Punggol. Mass market, HDB-heavy. This is where 80% of Singaporeans live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URA Planning Areas&lt;/strong&gt; — 55 distinct zones used by the Urban Redevelopment Authority for planning. Critical for understanding development potential and future MRT lines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding these regions is essential for any meaningful property analysis in Singapore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why People Need This Data
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Property investors&lt;/strong&gt; track PSF trends across districts to identify undervalued areas before en-bloc fever hits. When a new MRT line is announced, prices in surrounding districts shift — having historical data lets you model these patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real estate agents&lt;/strong&gt; monitor competitor listings, pricing strategies, and agent market share. If a rival agency is dominating District 15 listings, you want to know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PropTech developers&lt;/strong&gt; build tools like mortgage calculators, investment dashboards, and rental yield estimators. All of these need fresh listing data as input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Researchers and analysts&lt;/strong&gt; study housing affordability, the HDB resale market, and the impact of cooling measures on transaction volumes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Options (And Why They Fall Short)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Manual export&lt;/strong&gt;: PropertyGuru lets you browse and filter, but there's no bulk export. Copy-pasting 50 listings is tedious. Doing 5,000 is impossible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Existing Apify actors&lt;/strong&gt;: As of early 2026, the PropertyGuru scrapers on Apify Store are &lt;strong&gt;deprecated and returning 0 results&lt;/strong&gt;. The site has changed its structure, and nobody has updated these actors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise solutions&lt;/strong&gt;: Services like Bright Data offer pre-built datasets, but pricing starts at enterprise levels — overkill if you just need listing data for a specific district or property type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Your Own PropertyGuru Scraper
&lt;/h2&gt;

&lt;p&gt;Here's a basic approach using Python and requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scrape_propertyguru&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;district&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;listing_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sale&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Scrape PropertyGuru listings for a specific district.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (compatible; research bot)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.propertyguru.com.sg/property-for-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;listing_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;district&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;html.parser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Extract listing cards - inspect the page for current selectors
&lt;/span&gt;        &lt;span class="n"&gt;listings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[data-listing-id]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;listing&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;listings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;listing_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;listing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data-listing-id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;listing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.listing-title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;listing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.listing-price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;size&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;listing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.listing-floorarea&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;district&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;district&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c1"&gt;# Clean text from elements
&lt;/span&gt;            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;size&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Be respectful with rate limiting
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;

&lt;span class="c1"&gt;# Example: Scrape District 15 (East Coast/Katong) sale listings
&lt;/span&gt;&lt;span class="n"&gt;listings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scrape_propertyguru&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;district&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;listing_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sale&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Found &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; listings in District 15&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always check PropertyGuru's &lt;code&gt;robots.txt&lt;/code&gt; and terms of service&lt;/li&gt;
&lt;li&gt;Use reasonable rate limiting (2+ seconds between requests)&lt;/li&gt;
&lt;li&gt;Selectors change frequently — you'll need to maintain your scraper&lt;/li&gt;
&lt;li&gt;Consider using Playwright or Selenium if the site relies heavily on JavaScript rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Apify for Custom Tasks
&lt;/h2&gt;

&lt;p&gt;If you don't want to maintain your own scraper infrastructure, you can build a custom Apify actor. Apify handles proxy rotation, scheduling, and storage — you just write the scraping logic.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;complementary location data&lt;/strong&gt;, the &lt;a href="https://apify.com/cryptosignals/google-maps-scraper" rel="noopener noreferrer"&gt;Google Maps Scraper&lt;/a&gt; on Apify can help you enrich property listings with nearby amenities — schools, MRT stations, hawker centres, malls, and clinics. Proximity to amenities is one of the biggest price drivers in Singapore real estate.&lt;/p&gt;

&lt;p&gt;For example, combine property listings with Google Maps data to answer: &lt;em&gt;"Which District 19 condos are within 500m of an MRT station AND have 3+ schools nearby?"&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Tips for Singapore Property Data
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HDB vs Private&lt;/strong&gt; — These are fundamentally different markets. HDB resale is regulated by HDB with transaction data publicly available at data.gov.sg. Private property (condos, landed) is where scraped data adds the most value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;New launches vs Resale&lt;/strong&gt; — New launch pricing comes from developers and is often only on PropertyGuru temporarily. Resale listings stay longer and have richer data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PSF is king&lt;/strong&gt; — Price per square foot is how Singaporeans compare properties. Always normalize by size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MRT proximity matters enormously&lt;/strong&gt; — Properties within 500m of an MRT station command a 10-15% premium. The Thomson-East Coast Line (TEL) completions through 2025-2026 are reshaping values in Districts 15 and 18.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check URA caveats&lt;/strong&gt; — Some listings are in areas zoned for future development or have plot ratio restrictions. Cross-reference with URA Master Plan data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The gap in the market for a reliable, maintained PropertyGuru scraper is real. The existing solutions are broken, and Singapore's property data needs are growing as more investors and PropTech startups enter the market.&lt;/p&gt;

&lt;p&gt;If you build something useful, consider publishing it on the &lt;a href="https://apify.com/store" rel="noopener noreferrer"&gt;Apify Store&lt;/a&gt; — there's clear demand from the Singapore market, and the existing actors aren't delivering.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have questions about scraping property data in Singapore? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>singapore</category>
      <category>webdev</category>
      <category>data</category>
      <category>python</category>
    </item>
    <item>
      <title>How Singapore Recruiters Use LinkedIn Job Data to Beat the Talent Shortage in 2026</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 08:03:20 +0000</pubDate>
      <link>https://dev.to/agenthustler/how-singapore-recruiters-use-linkedin-job-data-to-beat-the-talent-shortage-in-2026-3kem</link>
      <guid>https://dev.to/agenthustler/how-singapore-recruiters-use-linkedin-job-data-to-beat-the-talent-shortage-in-2026-3kem</guid>
      <description>&lt;p&gt;Singapore's job market is running hot — and recruiters are struggling to keep up.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;77,700 open vacancies&lt;/strong&gt; across the island and a talent shortage that shows no signs of easing, hiring teams are under pressure to fill roles faster, smarter, and cheaper. Meanwhile, &lt;strong&gt;79% of Singapore recruiters now use AI tools&lt;/strong&gt; in their workflow, according to recent industry surveys.&lt;/p&gt;

&lt;p&gt;But here's what most recruiters miss: the richest source of hiring intelligence is already sitting in plain sight on LinkedIn. You're just not seeing all of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What LinkedIn Shows You vs. What the Data Actually Contains
&lt;/h2&gt;

&lt;p&gt;LinkedIn's job search UI is built for job seekers, not hiring strategists. You get a search bar, some filters, and 25 results per page. That's fine if you're looking for a job. It's useless if you're trying to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which companies in Tuas are ramping up semiconductor hiring this quarter?&lt;/li&gt;
&lt;li&gt;What's the median salary range for DevOps engineers in Singapore vs. KL?&lt;/li&gt;
&lt;li&gt;How many new fintech roles appeared in the CBD in the last 30 days?&lt;/li&gt;
&lt;li&gt;Which recruitment agencies are posting the most jobs in your niche?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the questions that separate reactive recruiters from strategic ones. And the answers are all in LinkedIn's job data — you just need a way to extract it at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five Use Cases Singapore Recruiters Are Using Right Now
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Mapping Competitor Hiring Patterns
&lt;/h3&gt;

&lt;p&gt;When DBS, OCBC, or Grab suddenly posts 40 engineering roles in a week, that's a signal. It could mean a new product launch, an internal restructuring, or a team that just lost its lead. By tracking job posting velocity across target companies, you can anticipate talent movement before it happens.&lt;/p&gt;

&lt;p&gt;A recruitment agency in Raffles Place told us they reduced time-to-fill by 30% simply by monitoring when competitors ramped up hiring — and reaching out to passive candidates at those companies before the poaching began.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Salary Benchmarking Across the Region
&lt;/h3&gt;

&lt;p&gt;Singapore competes for talent with Hong Kong, Sydney, and increasingly with remote roles from US companies. Bulk job data lets you compare salary ranges across markets in real time — not from a report published six months ago.&lt;/p&gt;

&lt;p&gt;Filter by job title, seniority, and location. Export to a spreadsheet. Build a salary matrix that's updated weekly, not annually.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tracking Tech Talent Demand by Location
&lt;/h3&gt;

&lt;p&gt;Singapore's tech talent isn't evenly distributed. One-North, Changi Business Park, and the CBD each have distinct hiring profiles. By geocoding job listings, you can map demand density — which matters when you're advising candidates on relocation or negotiating hybrid work arrangements.&lt;/p&gt;

&lt;p&gt;Some agencies even track demand by MRT line to help candidates find roles with reasonable commutes. It sounds granular, but in a tight market, convenience sells.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Identifying Companies About to Hire (Before They Post)
&lt;/h3&gt;

&lt;p&gt;If a company posts three senior roles in the same function within a week, they're likely about to post ten more. Early signal detection means you can reach out with candidates before the company even engages an agency — winning the mandate before the RFP.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Building Niche Talent Market Reports
&lt;/h3&gt;

&lt;p&gt;The recruiters commanding premium fees in 2026 aren't just filling roles — they're selling intelligence. A monthly report on "AI/ML Hiring Trends in Singapore's Financial Sector" positions you as a strategic partner, not a CV-pusher.&lt;/p&gt;

&lt;p&gt;Bulk job data makes these reports trivial to produce. Set up a weekly extraction, filter by industry and title, chart the trends, and send it to your clients. Most agencies charge SGD 2,000-5,000 per report.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Get LinkedIn Job Data at Scale
&lt;/h2&gt;

&lt;p&gt;Manually copying job listings from LinkedIn is painfully slow, error-prone, and limited. That's why recruitment teams are turning to structured data extraction tools.&lt;/p&gt;

&lt;p&gt;One popular option is the &lt;strong&gt;&lt;a href="https://apify.com/cryptosignals/linkedin-jobs-scraper" rel="noopener noreferrer"&gt;LinkedIn Jobs Scraper on Apify&lt;/a&gt;&lt;/strong&gt; — a cloud-based tool that extracts job listings with all metadata: title, company, location, salary range, posting date, seniority level, and job description.&lt;/p&gt;

&lt;p&gt;You don't need to install anything. Set your search criteria (keywords, location, date posted), run it, and download structured data in JSON, CSV, or Excel. Pricing is pay-per-result — roughly &lt;strong&gt;USD $1-3 per 1,000 job listings&lt;/strong&gt; — which makes it accessible even for small agencies.&lt;/p&gt;

&lt;p&gt;No coding required. The interface is point-and-click, and results typically arrive within minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ROI Math for Singapore Agencies
&lt;/h2&gt;

&lt;p&gt;Let's keep this simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: Extracting 10,000 Singapore job listings costs roughly SGD 5-15&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time saved&lt;/strong&gt;: Manual research on the same data would take 40+ hours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revenue opportunity&lt;/strong&gt;: One successful placement from better market intelligence = SGD 10,000-30,000 in fees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ROI isn't theoretical. It's arithmetic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for Singapore's Recruitment Industry
&lt;/h2&gt;

&lt;p&gt;The talent shortage isn't going away. MOM's latest projections show demand outpacing supply through 2027 in tech, healthcare, and green economy roles. The agencies that thrive won't be the ones working harder — they'll be the ones working with better data.&lt;/p&gt;

&lt;p&gt;LinkedIn has the data. The tools to extract it are mature, affordable, and require no engineering team. The only question is whether you'll use them before your competitors do.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're a Singapore-based recruiter exploring data-driven hiring strategies, the &lt;a href="https://apify.com/cryptosignals/linkedin-jobs-scraper" rel="noopener noreferrer"&gt;LinkedIn Jobs Scraper&lt;/a&gt; is a good place to start. Pay only for results, no subscriptions required.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>singapore</category>
      <category>career</category>
      <category>recruitment</category>
      <category>data</category>
    </item>
    <item>
      <title>LinkedIn Profile Scraper API in 2026: 5 Alternatives After Proxycurl Shut Down</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 05:42:17 +0000</pubDate>
      <link>https://dev.to/agenthustler/linkedin-profile-scraper-api-in-2026-5-alternatives-after-proxycurl-shut-down-kfd</link>
      <guid>https://dev.to/agenthustler/linkedin-profile-scraper-api-in-2026-5-alternatives-after-proxycurl-shut-down-kfd</guid>
      <description>&lt;p&gt;If you built anything on Proxycurl's LinkedIn Profile API, July 2025 was a rough month. LinkedIn's lawsuit forced them to shut down, leaving ~200K customers scrambling for alternatives. Your enrichment pipeline broke, your sales team lost real-time prospect data, and your recruiting tools went dark overnight.&lt;/p&gt;

&lt;p&gt;I've spent the last few weeks testing every replacement I could find. Here's what actually works in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Needs LinkedIn Profile Data (And Why It Matters)
&lt;/h2&gt;

&lt;p&gt;LinkedIn profile scraping isn't just a developer curiosity — it powers serious business workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales teams&lt;/strong&gt; enrich CRM leads with job titles, company names, and career history to personalize outreach&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recruiters&lt;/strong&gt; pull candidate profiles at scale to build talent pipelines without manual copy-paste&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketers&lt;/strong&gt; build Ideal Customer Profiles (ICPs) by analyzing the demographics of existing customers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Researchers&lt;/strong&gt; study labor market trends, skill demand shifts, and workforce mobility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Proxycurl gave all of these teams a clean REST API: send a LinkedIn URL, get back structured JSON with &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;company&lt;/code&gt;, &lt;code&gt;education&lt;/code&gt;, &lt;code&gt;experience&lt;/code&gt;, &lt;code&gt;skills&lt;/code&gt;, and more. Simple, fast, reliable — until it wasn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5 Best Alternatives in 2026
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Apify LinkedIn Profile Scraper
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Developers who want full control and pay-per-result pricing.&lt;/p&gt;

&lt;p&gt;Apify runs actors (serverless scrapers) in the cloud. The &lt;a href="https://apify.com/cryptosignals/linkedin-profile-scraper" rel="noopener noreferrer"&gt;LinkedIn Profile Scraper&lt;/a&gt; accepts a list of profile URLs and returns structured JSON with all the fields Proxycurl offered — name, headline, current position, experience history, education, skills, and location.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Pay-per-event (~$0.035/profile on the Apify platform)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fields&lt;/strong&gt;: Full profile — name, headline, experience, education, skills, location, connections count&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt;: Controlled by your Apify plan (scales to thousands of profiles/day)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal stance&lt;/strong&gt;: Runs on Apify's infrastructure; you control usage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Scrapingdog LinkedIn Scraper API
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Teams that want a drop-in REST API with a free tier to test.&lt;/p&gt;

&lt;p&gt;Scrapingdog offers a dedicated LinkedIn endpoint that returns profile data as JSON. Their free plan includes 1,000 credits — enough to validate your pipeline before committing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Free tier (1,000 credits), then from $40/mo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fields&lt;/strong&gt;: Name, headline, experience, education, location, about section&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt;: Based on plan tier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal stance&lt;/strong&gt;: Proxy-based; they handle rotation and anti-bot&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. LinkdAPI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Event-driven architectures that need webhook delivery.&lt;/p&gt;

&lt;p&gt;LinkdAPI differentiates with async webhook support — submit a profile URL, get results POSTed to your endpoint when ready. Useful if you're enriching leads in a queue-based system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: From $49/mo for 500 profiles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fields&lt;/strong&gt;: Name, title, company, experience, education, certifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt;: 500-10,000 profiles/mo depending on plan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal stance&lt;/strong&gt;: Operates as a data provider; ToS compliance is user's responsibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Bright Data LinkedIn Dataset
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Bulk analysis where you need thousands of profiles at once.&lt;/p&gt;

&lt;p&gt;Bright Data offers pre-collected LinkedIn datasets and on-demand collection. Less "API" and more "data pipeline" — you define your target criteria, they deliver a dataset.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Custom pricing; typically $0.01-0.05/record for bulk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fields&lt;/strong&gt;: Comprehensive — full profile, company data, skills endorsements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt;: N/A (batch delivery)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal stance&lt;/strong&gt;: They position themselves as compliant under data protection frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. PhantomBuster LinkedIn Profile Scraper
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Non-technical teams that want a no-code solution.&lt;/p&gt;

&lt;p&gt;PhantomBuster provides browser-based "Phantoms" that scrape LinkedIn using your own session cookie. It's the most accessible option for sales teams without developer support.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: From $69/mo for 500 automations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fields&lt;/strong&gt;: Name, headline, experience, education, connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt;: ~80 profiles/day to avoid LinkedIn detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal stance&lt;/strong&gt;: Uses your own LinkedIn session — risk is on you&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Apify&lt;/th&gt;
&lt;th&gt;Scrapingdog&lt;/th&gt;
&lt;th&gt;LinkdAPI&lt;/th&gt;
&lt;th&gt;Bright Data&lt;/th&gt;
&lt;th&gt;PhantomBuster&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Trial credits&lt;/td&gt;
&lt;td&gt;1,000 free credits&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;14-day trial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Per-profile cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$0.035&lt;/td&gt;
&lt;td&gt;~$0.04&lt;/td&gt;
&lt;td&gt;~$0.10&lt;/td&gt;
&lt;td&gt;~$0.01-0.05&lt;/td&gt;
&lt;td&gt;~$0.14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Webhook support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Via integration&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (native)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Zapier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Full experience history&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skills &amp;amp; endorsements&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Batch processing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (built-in)&lt;/td&gt;
&lt;td&gt;Sequential&lt;/td&gt;
&lt;td&gt;Async queue&lt;/td&gt;
&lt;td&gt;Native batch&lt;/td&gt;
&lt;td&gt;Sequential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-hosted option&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (open source)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Migration Guide: Proxycurl to Apify in 10 Minutes
&lt;/h2&gt;

&lt;p&gt;If you had Proxycurl code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# Old Proxycurl code (no longer works)
&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://nubela.co/proxycurl/api/v2/linkedin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://linkedin.com/in/williamhgates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer YOUR_PROXYCURL_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;full_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;headline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the Apify equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cryptosignals/linkedin-profile-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;profileUrls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://linkedin.com/in/williamhgates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;headline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Current: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;currentCompany&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Experience: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;experience&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; positions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skills: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;skills&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key differences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Async by default&lt;/strong&gt; — Apify runs the scrape as a job, so you get richer data but wait a few seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch-native&lt;/strong&gt; — pass 100 URLs in one call instead of looping&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset storage&lt;/strong&gt; — results are stored and queryable, not just returned once&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Install the client with &lt;code&gt;pip install apify-client&lt;/code&gt; and grab your API token from &lt;a href="https://console.apify.com/account/integrations" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which One Should You Pick?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Need a quick REST API with free testing?&lt;/strong&gt; Start with &lt;strong&gt;Scrapingdog&lt;/strong&gt; — their free tier lets you validate without a credit card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building a production enrichment pipeline?&lt;/strong&gt; Go with &lt;strong&gt;Apify&lt;/strong&gt; — pay-per-result scales better than monthly subscriptions, and the actor model lets you customize extraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Processing webhooks in an event-driven system?&lt;/strong&gt; &lt;strong&gt;LinkdAPI&lt;/strong&gt; is purpose-built for this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Need 50K+ profiles for analysis?&lt;/strong&gt; &lt;strong&gt;Bright Data&lt;/strong&gt; bulk datasets are the most cost-effective at scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-technical team?&lt;/strong&gt; &lt;strong&gt;PhantomBuster&lt;/strong&gt; gets you started without writing code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Proxycurl shutdown was painful, but the ecosystem has matured. You actually have better options now than you did in 2024 — more flexible pricing, better batch support, and open-source alternatives you can self-host.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building a LinkedIn data pipeline? I maintain the &lt;a href="https://apify.com/cryptosignals/linkedin-profile-scraper" rel="noopener noreferrer"&gt;LinkedIn Profile Scraper&lt;/a&gt; on Apify — it's optimized for reliability and returns the same structured fields Proxycurl did.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linkedin</category>
      <category>python</category>
      <category>webdev</category>
      <category>singapore</category>
    </item>
    <item>
      <title>Best Proxycurl Alternative in 2026: Apify LinkedIn Scrapers vs Scrapingdog vs LinkdAPI</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 05:05:39 +0000</pubDate>
      <link>https://dev.to/agenthustler/best-proxycurl-alternative-in-2026-apify-linkedin-scrapers-vs-scrapingdog-vs-linkdapi-11n7</link>
      <guid>https://dev.to/agenthustler/best-proxycurl-alternative-in-2026-apify-linkedin-scrapers-vs-scrapingdog-vs-linkdapi-11n7</guid>
      <description>&lt;p&gt;Proxycurl was the go-to LinkedIn data API for recruiters, sales teams, and developers. At its peak, it served ~200K paying customers and pulled in $10M ARR. Then LinkedIn sued them in January 2025, and by July 2025, Proxycurl was dead.&lt;/p&gt;

&lt;p&gt;If you relied on Proxycurl, you need a replacement. I tested the top alternatives so you don't have to.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happened to Proxycurl?
&lt;/h2&gt;

&lt;p&gt;LinkedIn filed a lawsuit in January 2025 alleging unauthorized scraping and reselling of member data. Proxycurl fought it briefly, but by July 2025 they shut down completely. API endpoints went dark, documentation was pulled, and their website now shows a generic service discontinued page.&lt;/p&gt;

&lt;p&gt;This left a massive gap. Proxycurl was clean, well-documented, and cheap. Finding something comparable is not trivial.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Contenders
&lt;/h2&gt;

&lt;p&gt;I evaluated four alternatives based on what matters most: &lt;strong&gt;reliability, pricing, data quality, and ease of migration&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Scrapingdog&lt;/th&gt;
&lt;th&gt;LinkdAPI&lt;/th&gt;
&lt;th&gt;BrightData&lt;/th&gt;
&lt;th&gt;Apify LinkedIn Scrapers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Profile Data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Company Data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Job Listings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Monthly plans&lt;/td&gt;
&lt;td&gt;Monthly plans&lt;/td&gt;
&lt;td&gt;Enterprise&lt;/td&gt;
&lt;td&gt;Pay-per-event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Starting Price&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$40/mo (5K credits)&lt;/td&gt;
&lt;td&gt;$49/mo (2K lookups)&lt;/td&gt;
&lt;td&gt;Custom (~$500+/mo)&lt;/td&gt;
&lt;td&gt;~$0.005/result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free Tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1K credits&lt;/td&gt;
&lt;td&gt;100 lookups&lt;/td&gt;
&lt;td&gt;Trial only&lt;/td&gt;
&lt;td&gt;Apify free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rate Limits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10 req/s&lt;/td&gt;
&lt;td&gt;5 req/s&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Concurrent runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Format&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST JSON&lt;/td&gt;
&lt;td&gt;REST JSON&lt;/td&gt;
&lt;td&gt;REST JSON&lt;/td&gt;
&lt;td&gt;REST JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Scrapingdog ($40-$200/mo)
&lt;/h2&gt;

&lt;p&gt;Scrapingdog is a general-purpose scraping API with a LinkedIn endpoint. It works, but LinkedIn is not their focus — they cover 20+ sites. Their LinkedIn data sometimes has gaps in education history and skills sections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Established company, good uptime, multi-site coverage.&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; LinkedIn data quality is inconsistent, monthly commitment, credits expire.&lt;/p&gt;
&lt;h2&gt;
  
  
  LinkdAPI ($49-$249/mo)
&lt;/h2&gt;

&lt;p&gt;LinkdAPI is LinkedIn-focused, which means better data structure. Their profile endpoint returns clean JSON similar to Proxycurl. The downside is no job listing support, and the $49/mo minimum is steep if you are doing low-volume lookups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Clean data format, LinkedIn-focused, Proxycurl-like response structure.&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; No job data, minimum $49/mo even for occasional use, 2K lookup cap on starter plan.&lt;/p&gt;
&lt;h2&gt;
  
  
  BrightData (Enterprise, $500+/mo)
&lt;/h2&gt;

&lt;p&gt;BrightData is the enterprise option. If you are scraping millions of profiles for a sales intelligence platform, this is your pick. For everyone else, it is overkill. Pricing is opaque, onboarding involves a sales call, and the minimum commitment is high.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Scale, reliability, compliance team.&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Expensive, slow onboarding, not suitable for startups or solo developers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Apify LinkedIn Scrapers (Pay-Per-Event)
&lt;/h2&gt;

&lt;p&gt;This is what I migrated to. Apify runs actors (cloud scrapers) that you call via API. Two actors cover the Proxycurl equivalent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/cryptosignals/linkedin-jobs-scraper" rel="noopener noreferrer"&gt;LinkedIn Jobs Scraper&lt;/a&gt;&lt;/strong&gt; — public job listings with filters for title, location, and company&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/cryptosignals/linkedin-profile-scraper" rel="noopener noreferrer"&gt;LinkedIn Profile and Company Scraper&lt;/a&gt;&lt;/strong&gt; — profiles and company data for lead generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pricing model is pay-per-event (PPE): you pay per result returned, not per month. At $0.005-$0.01 per result, 10K profiles costs $50-$100 with no monthly commitment and no expiring credits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; No monthly fees, pay only for what you use, scales from 1 to 1M results, free tier available.&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Slightly higher latency than direct APIs (runs are async), Apify platform learning curve.&lt;/p&gt;
&lt;h2&gt;
  
  
  Migration Guide: Proxycurl to Apify
&lt;/h2&gt;

&lt;p&gt;Here is a working Python example that replaces a typical Proxycurl job lookup with the Apify LinkedIn Jobs Scraper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;APIFY_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_apify_token_here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# get at apify.com/account#/integrations
&lt;/span&gt;&lt;span class="n"&gt;ACTOR_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cryptosignals/linkedin-jobs-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scrape_linkedin_jobs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;United States&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Start the actor run
&lt;/span&gt;    &lt;span class="n"&gt;run_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/acts/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ACTOR_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/runs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;searchQueries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResults&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;max_results&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;run_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Poll until finished
&lt;/span&gt;    &lt;span class="n"&gt;status_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/actor-runs/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SUCCEEDED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FAILED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Fetch results
&lt;/span&gt;    &lt;span class="n"&gt;dataset_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/datasets/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dataset_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;

&lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scrape_linkedin_jobs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python developer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Remote&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;company&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern works the same way for profiles. Swap the actor ID to &lt;code&gt;cryptosignals/linkedin-profile-scraper&lt;/code&gt; and adjust the input parameters. Check each actor page on Apify for the full input schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which One Should You Pick?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose Scrapingdog&lt;/strong&gt; if you need multi-site scraping and LinkedIn is just one of many sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose LinkdAPI&lt;/strong&gt; if you only need profile data, want Proxycurl-like JSON responses, and don't mind monthly billing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose BrightData&lt;/strong&gt; if you are an enterprise doing millions of lookups and need a compliance team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose Apify LinkedIn Scrapers&lt;/strong&gt; if you want pay-per-use pricing, need jobs and profiles in one place, or you prefer controlling costs per request rather than per month.&lt;/p&gt;

&lt;p&gt;For most developers migrating from Proxycurl, Apify makes the most sense financially, especially if your usage varies month to month. You are not locked into a $49/mo plan during months when you only need 200 lookups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Proxycurl's shutdown was a wake-up call about depending on a single vendor for LinkedIn data. Whatever you choose, build your pipeline with swap-ability in mind. Abstract your data source behind an interface so the next time a provider goes down, migration is a config change, not a rewrite.&lt;/p&gt;

&lt;p&gt;The LinkedIn data market is more fragmented now than in 2024, but that also means more options and more competitive pricing. For most use cases, pay-per-event pricing will save you money over monthly plans.&lt;/p&gt;

</description>
      <category>linkedin</category>
      <category>scraping</category>
      <category>data</category>
      <category>singapore</category>
    </item>
    <item>
      <title>Indeed Job Data: 5 Real Use Cases for Recruiters, Analysts, and Developers</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 05:03:39 +0000</pubDate>
      <link>https://dev.to/agenthustler/indeed-job-data-5-real-use-cases-for-recruiters-analysts-and-developers-28o0</link>
      <guid>https://dev.to/agenthustler/indeed-job-data-5-real-use-cases-for-recruiters-analysts-and-developers-28o0</guid>
      <description>&lt;p&gt;Indeed is the world's largest job board — &lt;strong&gt;175 million monthly visitors&lt;/strong&gt;, over &lt;strong&gt;300 million job listings&lt;/strong&gt; posted since launch, and coverage across 60+ countries. That's an enormous amount of structured data about who's hiring, what they're paying, and where the market is headed.&lt;/p&gt;

&lt;p&gt;But accessing this data programmatically? That's where it gets tricky.&lt;/p&gt;

&lt;p&gt;Indeed's official API is enterprise-only, expensive, and heavily restricted. Web scraping is fragile — layouts change, CAPTCHAs block you, and maintaining scrapers costs engineering time you could spend on actual analysis.&lt;/p&gt;

&lt;p&gt;There's a better way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Indeed Job Data Matters
&lt;/h2&gt;

&lt;p&gt;Job postings are one of the most underrated data sources in business. Every listing is a &lt;strong&gt;buying signal&lt;/strong&gt; — a company willing to spend money on talent. Aggregate enough of these signals, and you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track which industries are growing or contracting&lt;/li&gt;
&lt;li&gt;Identify companies scaling specific teams (engineering, sales, ops)&lt;/li&gt;
&lt;li&gt;Benchmark salaries across roles, locations, and experience levels&lt;/li&gt;
&lt;li&gt;Monitor competitor hiring strategies in real time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem was never &lt;em&gt;why&lt;/em&gt; — it was &lt;em&gt;how&lt;/em&gt; to get the data reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 Real Use Cases for Indeed Job Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Recruitment Analytics
&lt;/h3&gt;

&lt;p&gt;Staffing agencies and HR teams can monitor job posting volume by role, location, and company to spot demand trends before competitors do. If "AI Engineer" postings in Austin spike 40% month-over-month, that's actionable intelligence.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Lead Generation for B2B Sales
&lt;/h3&gt;

&lt;p&gt;A company posting 15 new software engineering roles is likely &lt;strong&gt;buying tools, services, and infrastructure&lt;/strong&gt;. Sales teams at SaaS companies, staffing firms, and consultancies use job posting data as a lead qualification signal — it's more reliable than intent data from ad platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Salary Benchmarking
&lt;/h3&gt;

&lt;p&gt;Compensation teams need market data. By extracting salary ranges from thousands of similar postings across geographies, you can build compensation benchmarks without paying $50K/year for a Radford subscription.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Labor Market Research
&lt;/h3&gt;

&lt;p&gt;Economists, policy analysts, and investors track job posting data to understand economic health. Which sectors are hiring? Which are freezing? Indeed data provides ground-truth signals that lag less than government employment reports.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Custom Job Alert Pipelines
&lt;/h3&gt;

&lt;p&gt;Build your own job monitoring system — filter by exact criteria (remote + Python + $150K+), deduplicate across sources, and push matches to Slack, email, or a dashboard. No more relying on Indeed's limited alert system.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Extract Indeed Jobs at Scale
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://apify.com/cryptosignals/indeed-jobs-scraper?referral=cryptosignals" rel="noopener noreferrer"&gt;Indeed Jobs Scraper&lt;/a&gt; on Apify handles all the complexity — anti-bot measures, pagination, data normalization — so you get clean, structured JSON.&lt;/p&gt;

&lt;p&gt;Here's how to run it with Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;queries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python developer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New York, NY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResults&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cryptosignals/indeed-jobs-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;company&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; — &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;salary&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the client with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;apify-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sample Output
&lt;/h3&gt;

&lt;p&gt;Each result comes back as structured JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Senior Python Developer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TechCorp Inc."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New York, NY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"salary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$140,000 - $180,000 a year"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Full-time"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"We are looking for an experienced Python developer..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"postedDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3 days ago"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.indeed.com/viewjob?jk=abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"companyRating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get the title, company, location, salary (when listed), job type, full description, posting date, direct URL, and company rating — all normalized and ready for analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing: $0.01 Per Result
&lt;/h2&gt;

&lt;p&gt;Let's put this in perspective:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Indeed Official API&lt;/td&gt;
&lt;td&gt;Enterprise pricing ($$$$)&lt;/td&gt;
&lt;td&gt;Restricted access, approval required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build your own scraper&lt;/td&gt;
&lt;td&gt;Engineering time + proxies + maintenance&lt;/td&gt;
&lt;td&gt;High — breaks regularly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Indeed Jobs Scraper on Apify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.01 per result&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Zero — just call the API&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For &lt;strong&gt;$1&lt;/strong&gt;, you get &lt;strong&gt;100 fully structured job listings&lt;/strong&gt;. For $10, you get 1,000. That's less than the cost of a single proxy rotation on most scraping setups.&lt;/p&gt;

&lt;p&gt;No infrastructure to manage. No CAPTCHAs to solve. No scrapers to maintain when Indeed changes their layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://apify.com?referral=cryptosignals" rel="noopener noreferrer"&gt;&lt;strong&gt;Create a free Apify account&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/cryptosignals/indeed-jobs-scraper?referral=cryptosignals" rel="noopener noreferrer"&gt;Indeed Jobs Scraper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Enter your search queries and location&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Start&lt;/strong&gt; and download your results as JSON, CSV, or Excel&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can also integrate it into any workflow via the Apify API — schedule daily runs, pipe results to a database, or trigger it from your own application.&lt;/p&gt;




&lt;p&gt;Whether you're building a recruitment dashboard, qualifying B2B leads, or tracking the job market — Indeed data at $0.01/result removes the last excuse not to start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/cryptosignals/indeed-jobs-scraper?referral=cryptosignals" rel="noopener noreferrer"&gt;&lt;strong&gt;Try the Indeed Jobs Scraper →&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>career</category>
    </item>
    <item>
      <title>Google Maps API Too Expensive? 5 Cheaper Alternatives for Location Data in 2026</title>
      <dc:creator>agenthustler</dc:creator>
      <pubDate>Sun, 12 Apr 2026 04:07:06 +0000</pubDate>
      <link>https://dev.to/agenthustler/google-maps-api-too-expensive-5-cheaper-alternatives-for-location-data-in-2026-275p</link>
      <guid>https://dev.to/agenthustler/google-maps-api-too-expensive-5-cheaper-alternatives-for-location-data-in-2026-275p</guid>
      <description>&lt;h2&gt;
  
  
  Google Maps API Pricing Is Crushing Small Projects
&lt;/h2&gt;

&lt;p&gt;Google Maps Platform pricing has been a pain point since the 2018 overhaul. Here is what you pay today in 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API Endpoint&lt;/th&gt;
&lt;th&gt;Cost per 1,000 Requests&lt;/th&gt;
&lt;th&gt;Free Tier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Geocoding&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;40K/month ($200 credit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Places Search&lt;/td&gt;
&lt;td&gt;$32.00&lt;/td&gt;
&lt;td&gt;~6,250/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Places Details&lt;/td&gt;
&lt;td&gt;$17.00&lt;/td&gt;
&lt;td&gt;~11,764/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Directions&lt;/td&gt;
&lt;td&gt;$5.00-$10.00&lt;/td&gt;
&lt;td&gt;40K/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Street View&lt;/td&gt;
&lt;td&gt;$7.00&lt;/td&gt;
&lt;td&gt;~28,571/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The $200 monthly credit sounds generous until you actually build something. A restaurant finder app making 50 Places Detail requests per user session burns through that credit in under 250 users. A real estate platform geocoding listings hits the wall even faster.&lt;/p&gt;

&lt;p&gt;For businesses processing hundreds of thousands of requests, the bill can easily reach $2,000-$10,000/month. Here are the alternatives developers are actually switching to.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. OpenStreetMap + Nominatim (Free, Self-Hosted)
&lt;/h2&gt;

&lt;p&gt;OpenStreetMap is the Wikipedia of maps. Nominatim is its geocoding engine. Together, they replace Google's Geocoding and Places APIs for many use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you get:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forward and reverse geocoding&lt;/li&gt;
&lt;li&gt;Address search&lt;/li&gt;
&lt;li&gt;POI data (restaurants, shops, landmarks)&lt;/li&gt;
&lt;li&gt;Map tiles via services like MapTiler or Stadia Maps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing:&lt;/strong&gt; Free if self-hosted. Third-party hosted Nominatim (LocationIQ, Geocod.io) starts at $0.50/1,000 requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Completely free at source&lt;/li&gt;
&lt;li&gt;No vendor lock-in&lt;/li&gt;
&lt;li&gt;Massive global coverage&lt;/li&gt;
&lt;li&gt;Open data you can fork and customize&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-hosting requires a beefy server (64GB+ RAM for full planet import)&lt;/li&gt;
&lt;li&gt;Data quality varies by region (excellent in Europe, patchy in parts of Asia/Africa)&lt;/li&gt;
&lt;li&gt;No Street View equivalent&lt;/li&gt;
&lt;li&gt;POI data is less comprehensive than Google for business listings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Projects where geocoding and basic POI search cover 80% of needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Scraping Google Maps Directly
&lt;/h2&gt;

&lt;p&gt;If you specifically need Google Maps data (reviews, ratings, business hours, photos) but cannot afford the API pricing, web scraping is the most direct alternative.&lt;/p&gt;

&lt;p&gt;Cloud scraping platforms like Apify offer Google Maps scrapers that extract business listings, reviews, and place details. You pay per result rather than per API call — typically $1-3 per 1,000 places, which is 10-30x cheaper than the official API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you can extract:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business name, address, phone, website&lt;/li&gt;
&lt;li&gt;Reviews and ratings&lt;/li&gt;
&lt;li&gt;Opening hours&lt;/li&gt;
&lt;li&gt;Photos&lt;/li&gt;
&lt;li&gt;GPS coordinates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10-30x cheaper than official API&lt;/li&gt;
&lt;li&gt;Access to data Google does not expose via API (review text, photos)&lt;/li&gt;
&lt;li&gt;Pay only for what you use&lt;/li&gt;
&lt;li&gt;JSON/CSV output, easy to integrate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not officially sanctioned by Google&lt;/li&gt;
&lt;li&gt;Data freshness depends on when you scrape&lt;/li&gt;
&lt;li&gt;No real-time geocoding — this is for batch data collection&lt;/li&gt;
&lt;li&gt;Google updates their frontend regularly, though cloud platforms handle the maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Batch data collection of business listings, lead generation, market research.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. HERE Maps API
&lt;/h2&gt;

&lt;p&gt;HERE (formerly Nokia Maps) is the closest full-featured alternative to Google Maps Platform. They power the maps in Mercedes, BMW, and most automotive navigation systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;HERE Cost / 1K&lt;/th&gt;
&lt;th&gt;Google Cost / 1K&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Geocoding&lt;/td&gt;
&lt;td&gt;$0.90&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Places Search&lt;/td&gt;
&lt;td&gt;$3.60&lt;/td&gt;
&lt;td&gt;$32.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Routing&lt;/td&gt;
&lt;td&gt;$0.90&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Map Tiles&lt;/td&gt;
&lt;td&gt;$0.72&lt;/td&gt;
&lt;td&gt;$7.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;HERE offers a free tier of 250K transactions/month — significantly more generous than Google's $200 credit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full-featured drop-in replacement for Google Maps&lt;/li&gt;
&lt;li&gt;5-10x cheaper across the board&lt;/li&gt;
&lt;li&gt;Generous free tier&lt;/li&gt;
&lt;li&gt;Strong offline map support&lt;/li&gt;
&lt;li&gt;Excellent in automotive and logistics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Street View equivalent (HERE StreetLevel) has limited coverage&lt;/li&gt;
&lt;li&gt;Smaller developer community than Google Maps&lt;/li&gt;
&lt;li&gt;Places database not as comprehensive for small businesses&lt;/li&gt;
&lt;li&gt;Migration requires code changes (different API structure)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Production applications that need a reliable, cheaper Google Maps replacement.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Mapbox
&lt;/h2&gt;

&lt;p&gt;Mapbox powers maps for Meta, The New York Times, Instacart, and thousands of apps. Their strength is customizable, beautiful map rendering, but they also offer geocoding and routing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100K free map loads/month&lt;/li&gt;
&lt;li&gt;Geocoding: $0.75/1,000 requests (temporary) up to $0.60 at volume&lt;/li&gt;
&lt;li&gt;Directions: $0.50-$2.00/1,000 requests&lt;/li&gt;
&lt;li&gt;Custom map styles included&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best-in-class map customization and design&lt;/li&gt;
&lt;li&gt;Very competitive pricing&lt;/li&gt;
&lt;li&gt;Excellent documentation and SDKs&lt;/li&gt;
&lt;li&gt;Strong open-source tooling (Mapbox GL JS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Places/POI search is limited compared to Google&lt;/li&gt;
&lt;li&gt;Geocoding quality slightly below Google in some regions&lt;/li&gt;
&lt;li&gt;Pricing structure can be confusing with different product tiers&lt;/li&gt;
&lt;li&gt;Recently made GL JS proprietary (v2+)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Consumer-facing apps where map appearance matters, or projects needing geocoding + custom maps.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. LocationIQ + Overpass API (Budget Stack)
&lt;/h2&gt;

&lt;p&gt;This is the budget developer's stack. LocationIQ provides hosted Nominatim geocoding at scale, while the Overpass API lets you query OpenStreetMap data directly for POIs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LocationIQ: Free up to 5K requests/day, then $0.50/1,000&lt;/li&gt;
&lt;li&gt;Overpass API: Free (rate limited on public servers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cheapest option for geocoding at scale&lt;/li&gt;
&lt;li&gt;Overpass queries are incredibly flexible (find all coffee shops within 500m of a point)&lt;/li&gt;
&lt;li&gt;No credit card required to start&lt;/li&gt;
&lt;li&gt;Built on open data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two separate services to integrate&lt;/li&gt;
&lt;li&gt;Overpass has a learning curve (custom query language)&lt;/li&gt;
&lt;li&gt;No routing or directions without adding another service&lt;/li&gt;
&lt;li&gt;Business listing data is less complete than Google&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Cost-conscious developers who need geocoding + POI search and are comfortable with some extra integration work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;th&gt;Geocoding Cost/1K&lt;/th&gt;
&lt;th&gt;POI Data&lt;/th&gt;
&lt;th&gt;Map Tiles&lt;/th&gt;
&lt;th&gt;Real-Time&lt;/th&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Google Maps&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenStreetMap&lt;/td&gt;
&lt;td&gt;Free (self-host)&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Via 3rd party&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Maps Scrapers&lt;/td&gt;
&lt;td&gt;$1-3 per 1K places&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HERE Maps&lt;/td&gt;
&lt;td&gt;$0.90&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mapbox&lt;/td&gt;
&lt;td&gt;$0.75&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Yes (best)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LocationIQ + Overpass&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Via 3rd party&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Which Alternative Is Right for You?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You need a full Google Maps replacement:&lt;/strong&gt; Go with HERE Maps. It is the closest feature-for-feature alternative at 5-10x lower cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need beautiful custom maps:&lt;/strong&gt; Mapbox is unmatched for map rendering and design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need to scrape business data in bulk:&lt;/strong&gt; Cloud scraping platforms give you Google Maps data at a fraction of the API cost, without the per-request pricing model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are building a side project on a budget:&lt;/strong&gt; LocationIQ + OpenStreetMap covers geocoding and POIs for practically free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need everything for free:&lt;/strong&gt; Self-host Nominatim and use Overpass, but budget time for setup and maintenance.&lt;/p&gt;

&lt;p&gt;The $200 monthly Google Maps credit is enough for prototyping, but any app with real users will outgrow it quickly. Switching early saves both money and migration headaches later.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What are you using instead of Google Maps API? Share your stack in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>googlemaps</category>
      <category>api</category>
      <category>webscraping</category>
      <category>geodata</category>
    </item>
  </channel>
</rss>
