<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Fjord Labs Blog]]></title><description><![CDATA[Practical Python how-tos for Google Trends, news, app reviews and Core Web Vitals data, from the team behind the Fjord Labs Apify Actors.]]></description><link>https://fjordlabs.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6ae9bbeacbe7c92a9fdd63c0/4c45808d-b101-4fe9-b3f1-efe5de878d11.png</url><title>Fjord Labs Blog</title><link>https://fjordlabs.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 10:50:48 GMT</lastBuildDate><atom:link href="https://fjordlabs.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Audit Core Web Vitals for a whole sitemap (and stop confusing page and origin data)]]></title><description><![CDATA[PageSpeed Insights is great for one URL. For a 200-page site, it's an afternoon of copy-pasting. Here's how I audit an entire sitemap in one go,…]]></description><link>https://fjordlabs.hashnode.dev/audit-core-web-vitals-for-a-whole-sitemap-and-stop-confusing-page-and-origin-data</link><guid isPermaLink="true">https://fjordlabs.hashnode.dev/audit-core-web-vitals-for-a-whole-sitemap-and-stop-confusing-page-and-origin-data</guid><category><![CDATA[webdev]]></category><category><![CDATA[performance]]></category><category><![CDATA[SEO]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Fjord Labs]]></dc:creator><pubDate>Fri, 06 Nov 2026 17:38:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae9bbeacbe7c92a9fdd63c0/de5fb6b6-3603-4372-8916-b7c6130ae3c8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>PageSpeed Insights is great for one URL. For a 200-page site, it's an afternoon of copy-pasting. Here's how I audit an entire sitemap in one go, mobile and desktop, and get a spreadsheet of Lighthouse scores, real-user Core Web Vitals and the top fixes per page.</p>
<h2>A trap first: page vs origin field data</h2>
<p>When Google has no real-user (CrUX) data for a specific page, PageSpeed Insights quietly shows the <strong>origin's</strong> data instead. So a slow, low-traffic page can look "fast" because the homepage is fast. Keep the two apart:</p>
<ul>
<li><code>fieldDataPage</code>: real users of <em>this</em> URL (often <code>null</code> on small pages)</li>
<li><code>fieldDataOrigin</code>: real users across the whole site</li>
</ul>
<h2>The code</h2>
<p>I use a hosted Actor I maintain on Apify (<a href="https://apify.com/fjordlabs/pagespeed-audit?fpr=fjordlabs">Bulk PageSpeed &amp; Core Web Vitals Audit</a>). With the Python client (<code>pip install apify-client pandas</code>):</p>
<pre><code class="language-python">from apify_client import ApifyClient
import pandas as pd

client = ApifyClient("&lt;YOUR_APIFY_TOKEN&gt;")
run = client.actor("fjordlabs/pagespeed-audit").call(run_input={
    "sitemapUrls": ["https://www.example.com/sitemap.xml"],
    "maxUrls": 200,
    "strategies": ["mobile", "desktop"],
    "alertBelowPerformanceScore": 50,
})

rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
df = pd.json_normalize(rows)
cols = ["url", "strategy", "scores.performance", "lab.lcpMs", "lab.cls",
        "fieldDataPage.overall", "fieldDataOrigin.overall", "coreWebVitalsPassed"]
print(df[cols].sort_values("scores.performance").head(15))
</code></pre>
<p>Sitemap indexes are followed and URLs de-duplicated, so you can point it at the root sitemap.</p>
<h2>Find the fixes that matter most</h2>
<p>Each row has <code>opportunities</code> with estimated savings. Summing them across the site shows which single fix helps the most pages:</p>
<pre><code class="language-python">opps = pd.json_normalize(rows, "opportunities", ["url"])
print(opps.groupby("title")["savingsMs"].agg(["count", "sum"]).sort_values("sum", ascending=False).head())
</code></pre>
<p>Usually it's "Reduce unused JavaScript" or "Eliminate render-blocking resources" on a shared template, so one fix lifts dozens of pages.</p>
<h2>Weekly monitoring</h2>
<p>Schedule it weekly. Pages under your threshold come back with <code>alert: true</code>, which you can route to Slack or email with Apify's integrations.</p>
<p>Cost: $0.004 per page audit, and failed audits are free. A 200-page site on mobile + desktop is $1.60.</p>
<p><em>Disclosure: I built and maintain this Actor. Happy to answer questions in the comments. Links to Apify include my referral code.</em></p>
<p><em>Originally published on <a href="https://dev.to/fjordlabs/audit-core-web-vitals-for-a-whole-sitemap-and-stop-confusing-page-and-origin-data-4b31">DEV</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Track what's trending on Google in 20 countries with 15 lines of Python]]></title><description><![CDATA[Google Trends has a page called Trending Now: the searches that are spiking right now in a given country, with a rough search volume and the news…]]></description><link>https://fjordlabs.hashnode.dev/track-what-s-trending-on-google-in-20-countries-with-15-lines-of-python</link><guid isPermaLink="true">https://fjordlabs.hashnode.dev/track-what-s-trending-on-google-in-20-countries-with-15-lines-of-python</guid><category><![CDATA[Python]]></category><category><![CDATA[datascience]]></category><category><![CDATA[SEO]]></category><category><![CDATA[api]]></category><dc:creator><![CDATA[Fjord Labs]]></dc:creator><pubDate>Tue, 03 Nov 2026 13:59:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae9bbeacbe7c92a9fdd63c0/b63471b2-3b17-4854-9752-008adac8be89.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Google Trends has a page called <strong>Trending Now</strong>: the searches that are spiking right now in a given country, with a rough search volume and the news stories behind them. It's great for content ideas, newsjacking and market signals. But it's one country at a time, and there's no official API.</p>
<p>Here's how I pull it for many countries at once and get clean JSON back.</p>
<h2>The data</h2>
<p>For each trending search you get:</p>
<ul>
<li>rank and search term</li>
<li>approximate searches (<code>"10K+"</code>) plus a number you can sort on (<code>10000</code>)</li>
<li>when the trend started (UTC)</li>
<li>related news: headline, source, link</li>
<li>a ready-made Google Trends explore link</li>
</ul>
<h2>The code</h2>
<p>I use a small hosted scraper I maintain on Apify (<a href="https://apify.com/fjordlabs/google-trending-now">Google Trends Trending Now</a>). With the official Python client (<code>pip install apify-client</code>):</p>
<pre><code class="language-python">from apify_client import ApifyClient

client = ApifyClient("&lt;YOUR_APIFY_TOKEN&gt;")
run = client.actor("fjordlabs/google-trending-now").call(run_input={
    "geos": ["US", "GB", "DE", "FR", "IN", "BR", "JP"],
    "includeNews": True,
    "minTraffic": 1000,        # skip the small ones
})

for t in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f'{t["geo"]} #{t["rank"]:&gt;2} {t["title"]} ({t["approxTraffic"]})')
</code></pre>
<p>Output looks like:</p>
<pre><code class="language-plaintext">US # 1 tesla stock (10K+)
GB # 1 strictly come dancing (20K+)
...
</code></pre>
<h2>Cross-country trends in pandas</h2>
<p>The fun part is seeing what trends in several countries on the same day:</p>
<pre><code class="language-python">import pandas as pd

df = pd.DataFrame(client.dataset(run["defaultDatasetId"]).iterate_items())
spread = (df.groupby(df["title"].str.lower())["geo"]
            .agg(["nunique", lambda g: ", ".join(sorted(g))])
            .sort_values("nunique", ascending=False))
print(spread.head(10))
</code></pre>
<h2>Make it a monitor</h2>
<p>Schedule the run hourly in Apify and connect the Slack or webhook integration, and you have a "what's spiking right now" alert for every market you care about. Each trending search costs $0.001, so 10 countries every hour is about $0.10 an hour at most, and failed rows are never charged.</p>
<h2>Free history</h2>
<p>I also keep a daily snapshot for 20 countries and publish the trend facts as a free Kaggle dataset: <a href="https://www.kaggle.com/datasets/Mivah/google-trending-searches-daily">Daily Google Trending Searches, 20 Countries</a> (updated weekly). It's handy for seasonality or "how do trends spread between countries" questions.</p>
<p><em>Disclosure: I built and maintain the scraper. Questions and feature requests welcome in the comments.</em></p>
<p><em>Originally published on</em> <a href="https://dev.to/fjordlabs/track-whats-trending-on-google-in-20-countries-with-15-lines-of-python-1ba5"><em>DEV</em></a><em>.</em></p>
]]></content:encoded></item></channel></rss>