<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Browserflare | Blog</title><description/><link>https://browserflare.xyz/</link><language>en</language><item><title>Web Scraping Without Headless Browsers: A Practical Guide</title><link>https://browserflare.xyz/blog/web-scraping-network-tab-guide/</link><guid isPermaLink="true">https://browserflare.xyz/blog/web-scraping-network-tab-guide/</guid><pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Core principle&lt;/strong&gt;: Before writing a single line of scraping code, spend 1 minute in the Network tab. Most modern sites fetch data from clean JSON APIs in the background — hitting those directly is faster, simpler, and harder to block.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;aside aria-label=&quot;Skip the code?&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Skip the code?&lt;/p&gt;&lt;div&gt;&lt;p&gt;If you’d rather point-and-click than write Python scripts, &lt;a href=&quot;https://browserflare.xyz/&quot;&gt;Browserflare&lt;/a&gt; lets you scrape, crawl, and extract structured data through a desktop GUI — no coding required. Just enter a URL, configure your selectors, and export the results. &lt;a href=&quot;https://browserflare.xyz/#download&quot;&gt;Download it here&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;step-1-find-the-real-data-source&quot;&gt;Step 1: Find the Real Data Source&lt;/h2&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Open your browser and navigate to the target page&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;F12&lt;/strong&gt; to open DevTools&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Network&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Filter by &lt;strong&gt;Fetch/XHR&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Refresh the page, scroll, or click buttons that trigger data loading&lt;/li&gt;
&lt;li&gt;Look for requests returning JSON — these are your targets&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Responses with &lt;code dir=&quot;auto&quot;&gt;Content-Type: application/json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Endpoints with patterns like &lt;code dir=&quot;auto&quot;&gt;/api/&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;/graphql&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;/v1/&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;/data/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Requests that fire when you paginate, search, or filter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Click a request and check the &lt;strong&gt;Preview&lt;/strong&gt; tab. If you can see your data structured there, you’ve found your endpoint.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;step-2-test-it-directly--the-curl-test&quot;&gt;Step 2: Test It Directly — The curl Test&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Right-click the request → &lt;strong&gt;Copy&lt;/strong&gt; → &lt;strong&gt;Copy as cURL&lt;/strong&gt;, then paste it in your terminal.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Example of what gets copied&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;https://example.com/api/products?page=1&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-H&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;accept: application/json&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-H&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;user-agent: Mozilla/5.0 ...&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-H&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;cookie: session=abc123; cf_clearance=xyz&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;did-it-work&quot;&gt;Did it work?&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Yes&lt;/strong&gt; → The site has no TLS fingerprinting. Move to Step 3.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No&lt;/strong&gt; → The site may be fingerprinting your TLS handshake. Move to Step 4.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;step-3-whittle-down-the-request&quot;&gt;Step 3: Whittle Down the Request&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;If the raw curl worked, start removing headers one by one to find the &lt;strong&gt;minimum viable request&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Removal order (start with the safest to remove):&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generic browser headers (&lt;code dir=&quot;auto&quot;&gt;sec-ch-ua&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;sec-fetch-*&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;upgrade-insecure-requests&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;referer&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;origin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;x-*&lt;/code&gt; custom headers (test each carefully — some are required)&lt;/li&gt;
&lt;li&gt;Cookies (remove one at a time — identify which are essential)&lt;/li&gt;
&lt;li&gt;Auth headers (&lt;code dir=&quot;auto&quot;&gt;authorization&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;x-api-key&lt;/code&gt;) — keep these if required&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; The leanest possible request that still returns data.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; requests&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/api/products&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;page&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;accept&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;application/json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; response.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Also check:&lt;/strong&gt; Does the endpoint require a Bearer token fetched at page load? Look for an earlier request to &lt;code dir=&quot;auto&quot;&gt;/auth&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;/token&lt;/code&gt;, or &lt;code dir=&quot;auto&quot;&gt;/session&lt;/code&gt; — you may need to grab that first.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;step-4-handle-tls-fingerprinting-with-curl_cffi&quot;&gt;Step 4: Handle TLS Fingerprinting with curl_cffi&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;If the raw curl didn’t work, the server is likely inspecting your TLS handshake to detect non-browser clients. Use &lt;code dir=&quot;auto&quot;&gt;curl_cffi&lt;/code&gt; to impersonate a real browser’s networking stack.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;pip&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;curl_cffi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; curl_cffi &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; requests&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/api/products&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;impersonate&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;chrome120&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;# mimics Chrome&apos;s TLS fingerprint&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;page&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; response.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Available impersonation targets:&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;chrome110&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;chrome120&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;safari17&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;firefox120&lt;/code&gt;, and more.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;did-it-work-1&quot;&gt;Did it work?&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Yes&lt;/strong&gt; → You have TLS fingerprinting confirmed. Use &lt;code dir=&quot;auto&quot;&gt;curl_cffi&lt;/code&gt; for all requests. Then go back to Step 3 and minimize your headers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No&lt;/strong&gt; → There’s session-based logic at play. Move to Step 5.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;step-5-emulate-sessions-and-cookies&quot;&gt;Step 5: Emulate Sessions and Cookies&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Some sites issue challenge cookies that must be obtained via a valid browser-like session. Strategies in order of complexity:&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;5a-respect-set-cookie-headers&quot;&gt;5a. Respect Set-Cookie headers&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Some sites set a cookie on the first request that must be echoed back. Use a session object:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; curl_cffi &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; requests&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;session &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;Session&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;session.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)          &lt;/span&gt;&lt;span&gt;# Triggers Set-Cookie&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; session.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/api/products&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;5b-rotating-cookies&quot;&gt;5b. Rotating cookies&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Some sites invalidate cookies after each use and issue a new one in the response. You need to update your cookie jar between requests:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;session &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;Session&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; page &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;r &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; session.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;https://example.com/api/products?page=&lt;/span&gt;&lt;span&gt;{page}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;impersonate&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;chrome120&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# session automatically handles the updated cookies&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; r.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;5c-javascript-challenge-cookies-eg-cloudflare&quot;&gt;5c. JavaScript challenge cookies (e.g., Cloudflare)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;If the site issues a &lt;code dir=&quot;auto&quot;&gt;cf_clearance&lt;/code&gt; or similar JS-challenge cookie, it requires actual JavaScript execution to solve. This is where you finally need a headless browser — but only to obtain the cookie, not to scrape data:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; playwright.sync_api &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; sync_playwright&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sync_playwright&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; p:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;browser &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p.chromium.&lt;/span&gt;&lt;span&gt;launch&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;page &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; browser.&lt;/span&gt;&lt;span&gt;new_page&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;page.&lt;/span&gt;&lt;span&gt;goto&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;page.&lt;/span&gt;&lt;span&gt;wait_for_timeout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3000&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;# Let the challenge resolve&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;cookies &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; page.context.&lt;/span&gt;&lt;span&gt;cookies&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;cf_clearance &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; c &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; cookies &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;cf_clearance&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;browser.&lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Now use the cookie in curl_cffi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/api/products&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;impersonate&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;chrome120&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;cookies&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;cf_clearance&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: cf_clearance}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;step-6-when-theres-no-api-server-side-rendered-pages&quot;&gt;Step 6: When There’s No API (Server-Side Rendered Pages)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;If the Network tab shows no useful XHR/Fetch requests, the HTML &lt;em&gt;is&lt;/em&gt; the data (server-rendered pages). In this case, parse the HTML directly:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; requests&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; bs4 &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; BeautifulSoup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;r &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://example.com/products&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;User-Agent&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Mozilla/5.0&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;soup &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BeautifulSoup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;r.text&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;lxml&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;items &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; soup.&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;.product-card .title&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;decision-flowchart&quot;&gt;Decision Flowchart&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Start&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;▼&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Find XHR/Fetch request in Network tab&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├─ No useful request found ──────────────────────► Parse HTML with BeautifulSoup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;▼&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Copy as cURL → paste in terminal&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├─ Works ──► Whittle down headers ──► Use requests or httpx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├─ Fails ──► Try curl_cffi with impersonate=&quot;chrome120&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│               │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│               ├─ Works ──► TLS fingerprinting confirmed. Use curl_cffi + minimize headers&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│               │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│               └─ Fails ──► Session logic required&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│                               │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│                               ├─ Set-Cookie emulation ──► requests.Session()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│                               ├─ Rotating cookies ──────► Update jar each request&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│                               └─ JS challenge cookie ───► Playwright to get cookie, then curl_cffi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└─ All else fails ──────────────────────────────► Full headless browser (Playwright/Selenium)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;practical-reminders&quot;&gt;Practical Reminders&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt;: Always add delays between requests (&lt;code dir=&quot;auto&quot;&gt;time.sleep(1–3)&lt;/code&gt;). Even open APIs will ban aggressive scrapers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Endpoint instability&lt;/strong&gt;: Internal APIs have no stability guarantees — your scraper can break without warning. Add error handling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auth tokens&lt;/strong&gt;: Look for an early request to &lt;code dir=&quot;auto&quot;&gt;/auth&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;/session&lt;/code&gt; that returns a Bearer token used in subsequent calls.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Respect &lt;code dir=&quot;auto&quot;&gt;robots.txt&lt;/code&gt;&lt;/strong&gt;: Check &lt;code dir=&quot;auto&quot;&gt;https://example.com/robots.txt&lt;/code&gt; before scraping. Honor it where appropriate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Legal&lt;/strong&gt;: Scraping terms of service vary. Always check the site’s ToS and applicable laws before scraping at scale.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;quick-reference-tools-by-use-case&quot;&gt;Quick Reference: Tools by Use Case&lt;/h2&gt;&lt;/div&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Situation&lt;/th&gt;&lt;th&gt;Tool&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Simple API, no auth&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;requests&lt;/code&gt; / &lt;code dir=&quot;auto&quot;&gt;httpx&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TLS fingerprinting detected&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;curl_cffi&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Session/cookie handling&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;requests.Session()&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;curl_cffi&lt;/code&gt; Session&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;JS challenge (Cloudflare, etc.)&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;playwright&lt;/code&gt; (for cookie only) + &lt;code dir=&quot;auto&quot;&gt;curl_cffi&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Server-rendered HTML&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;requests&lt;/code&gt; + &lt;code dir=&quot;auto&quot;&gt;BeautifulSoup&lt;/code&gt; / &lt;code dir=&quot;auto&quot;&gt;lxml&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Full JS rendering required&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;playwright&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;selenium&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</content:encoded></item><item><title>Scraping AliExpress Ecommerce Data With Cloudflare Browser Rendering</title><link>https://browserflare.xyz/blog/scraping-aliexpress-ecommerce-data-with-cloudflare-browser-rendering/</link><guid isPermaLink="true">https://browserflare.xyz/blog/scraping-aliexpress-ecommerce-data-with-cloudflare-browser-rendering/</guid><pubDate>Sat, 11 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h1 id=&quot;scraping-aliexpress-search-results-with-cloudflare-browser-rendering&quot;&gt;Scraping AliExpress Search Results With Cloudflare Browser Rendering&lt;/h1&gt;&lt;/div&gt;
&lt;p&gt;AliExpress is one of those sites that looks simple on the surface but fights you at every turn when you try to scrape it. It’s a fully client-rendered SPA — a plain HTTP request gives you a loading skeleton with zero product data. On top of that, AliExpress geo-localizes aggressively, so your results might come back in Japanese or Russian depending on which data center handles the request.&lt;/p&gt;
&lt;p&gt;Here’s how to get clean, structured product data from AliExpress search results using Cloudflare Browser Rendering — no local browser needed.&lt;/p&gt;
&lt;aside aria-label=&quot;Skip the code?&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Skip the code?&lt;/p&gt;&lt;div&gt;&lt;p&gt;If you’d rather point-and-click than write Python scripts, &lt;a href=&quot;https://browserflare.xyz/&quot;&gt;Browserflare&lt;/a&gt; lets you scrape, crawl, and extract structured data from sites like AliExpress through a desktop GUI — no coding required. Just enter a URL, configure your selectors, and export the results. &lt;a href=&quot;https://browserflare.xyz/#download&quot;&gt;Download it here&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;div&gt;&lt;h2 id=&quot;the-approach&quot;&gt;The Approach&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Same two-step pattern as any browser-rendering scraping workflow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fetch&lt;/strong&gt; the fully rendered HTML via Cloudflare’s &lt;code dir=&quot;auto&quot;&gt;/content&lt;/code&gt; API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parse&lt;/strong&gt; the embedded JSON data locally&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The interesting part with AliExpress is that it doesn’t use Next.js like Walmart does. There’s no convenient &lt;code dir=&quot;auto&quot;&gt;__NEXT_DATA__&lt;/code&gt; tag. Instead, AliExpress embeds its page data inside a &lt;code dir=&quot;auto&quot;&gt;window._dida_config_._init_data_&lt;/code&gt; JavaScript variable — a massive JSON blob buried in a script tag. Once you know where to look, it’s just as clean to parse.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;step-1-fetching-the-html&quot;&gt;Step 1: Fetching the HTML&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Start with the usual Cloudflare Browser Rendering setup:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; requests&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; dotenv &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; load_dotenv&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;load_dotenv&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;ACCOUNT_ID&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os.environ.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;CF_ACCOUNT_ID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;API_TOKEN&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os.environ.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;CF_API_TOKEN&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;endpoint &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;https://api.cloudflare.com/client/v4/accounts/&lt;/span&gt;&lt;span&gt;{ACCOUNT_ID}&lt;/span&gt;&lt;span&gt;/browser-rendering/content&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Build the payload. AliExpress search URLs follow the pattern &lt;code dir=&quot;auto&quot;&gt;/w/wholesale-{query}.html&lt;/code&gt;. The &lt;code dir=&quot;auto&quot;&gt;waitForSelector&lt;/code&gt; targets &lt;code dir=&quot;auto&quot;&gt;.search-item-card-wrapper-gallery&lt;/code&gt;, which is the container for the product grid:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;SEARCH_QUERY&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;sunglasses&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;payload &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;https://www.aliexpress.com/w/wholesale-&lt;/span&gt;&lt;span&gt;{SEARCH_QUERY}&lt;/span&gt;&lt;span&gt;.html?g=y&amp;#x26;SearchText=&lt;/span&gt;&lt;span&gt;{SEARCH_QUERY}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;gotoOptions&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;waitUntil&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;domcontentloaded&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;60000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;waitForSelector&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;selector&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;.search-item-card-wrapper-gallery&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;30000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;viewport&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;width&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1280&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;height&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;720&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;the-locale-problem&quot;&gt;The Locale Problem&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Here’s a gotcha that’ll waste your time if you’re not ready for it. Cloudflare’s browser instances run on their edge network, and AliExpress geo-localizes based on the requesting IP. If the edge node is in Tokyo, you’ll get Japanese product titles and yen prices. In São Paulo? Portuguese and reais.&lt;/p&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;Accept-Language&lt;/code&gt; header alone doesn’t fix this — AliExpress mostly ignores it. What works is setting locale cookies &lt;em&gt;before&lt;/em&gt; the page loads. Cloudflare’s API supports a &lt;code dir=&quot;auto&quot;&gt;cookies&lt;/code&gt; parameter for exactly this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;payload &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# ... url, gotoOptions, etc.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;setExtraHTTPHeaders&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Accept-Language&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;en-US,en;q=0.9&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;cookies&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;aep_usuc_f&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;site=glo&amp;#x26;c_tp=USD&amp;#x26;region=US&amp;#x26;b_locale=en_US&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;domain&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;.aliexpress.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;intl_locale&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;en_US&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;domain&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;.aliexpress.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;aep_usuc_f&lt;/code&gt; cookie is the important one — it tells AliExpress which regional site to serve (&lt;code dir=&quot;auto&quot;&gt;glo&lt;/code&gt; for global), what currency to use (&lt;code dir=&quot;auto&quot;&gt;USD&lt;/code&gt;), and what locale to render (&lt;code dir=&quot;auto&quot;&gt;en_US&lt;/code&gt;). Without it, you’re at the mercy of IP geolocation.&lt;/p&gt;
&lt;p&gt;Fire it off and save:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;headers &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Content-Type&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;application/json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Authorization&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;Bearer &lt;/span&gt;&lt;span&gt;{API_TOKEN}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;endpoint&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;payload&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; resp.status_code &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;aliexpress_search_raw.html&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;w&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;utf-8&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; f:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;f.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resp.text&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;Saved &lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resp.text&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:,&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; chars of rendered HTML&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;Error &lt;/span&gt;&lt;span&gt;{resp.status_code}&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;{resp.text&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;500&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;step-2-parsing-the-data&quot;&gt;Step 2: Parsing the Data&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;AliExpress doesn’t use Next.js, so there’s no &lt;code dir=&quot;auto&quot;&gt;__NEXT_DATA__&lt;/code&gt; to grab. Instead, it uses a custom framework (internally called “dida”) that injects page data into a JavaScript variable: &lt;code dir=&quot;auto&quot;&gt;window._dida_config_._init_data_&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The tricky part is extracting it. The data is assigned as a JavaScript object literal inside a &lt;code dir=&quot;auto&quot;&gt;&amp;#x3C;script&gt;&lt;/code&gt; tag — not a standalone JSON string. You can’t just grab it with a regex because the JSON is hundreds of thousands of characters long and nested deeply. Bracket counting works reliably:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; bs4 &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; BeautifulSoup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;soup &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BeautifulSoup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;html&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;html.parser&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;init_data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; script &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; soup.&lt;/span&gt;&lt;span&gt;find_all&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; script.string &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;marker &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;_init_data_= { data: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;idx &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; text.&lt;/span&gt;&lt;span&gt;find&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; idx &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;continue&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;idx &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# Find matching closing brace&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;depth &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; j &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;idx&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;)):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; text[j] &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;depth &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;elif&lt;/span&gt;&lt;span&gt; text[j] &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;depth &lt;/span&gt;&lt;span&gt;-=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; depth &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;init_data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; json.&lt;/span&gt;&lt;span&gt;loads&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;idx:j &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;break&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;break&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You scan every script tag looking for the &lt;code dir=&quot;auto&quot;&gt;_init_data_&lt;/code&gt; marker, then count curly braces to find where the JSON object ends. Once you’ve got the boundaries, &lt;code dir=&quot;auto&quot;&gt;json.loads&lt;/code&gt; handles the rest.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;the-data-structure&quot;&gt;The Data Structure&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The init data has a clear hierarchy. Product listings live at &lt;code dir=&quot;auto&quot;&gt;data.root.fields.mods.itemList.content&lt;/code&gt; — an array of 60 items per page:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;root_fields &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; init_data[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;fields&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;page_info &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; root_fields.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;pageInfo&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;item_list &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; root_fields[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;mods&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;itemList&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;pageInfo&lt;/code&gt; object gives you pagination metadata — total results, current page, page size. Useful if you want to paginate through all results.&lt;/p&gt;
&lt;p&gt;Each item in the list has a consistent shape. Here’s how to extract the useful fields:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;products &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; item &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; item_list:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prices &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;prices&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;sale_price &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; prices.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;salePrice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;original_price &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; prices.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;originalPrice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;evaluation &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;evaluation&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;trade &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;trade&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;image &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;title &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;img_url &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; image.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;imgUrl&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; img_url &lt;/span&gt;&lt;span&gt;and&lt;/span&gt;&lt;span&gt; img_url.&lt;/span&gt;&lt;span&gt;startswith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;img_url &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https:&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; img_url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;product &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;product_id&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;productId&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: title.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;displayTitle&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;https://www.aliexpress.com/item/&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;productId&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;.html&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: img_url &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;price&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: sale_price.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;formattedPrice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;price_original&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: original_price.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;formattedPrice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;discount_pct&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: sale_price.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;discount&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;currency&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: sale_price.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;currencyCode&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;rating&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: evaluation.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;starRating&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;sold&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: trade.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;tradeDesc&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;is_ad&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;productType&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;ad&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;products.&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;product&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;A few things worth noting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Image URLs are protocol-relative&lt;/strong&gt; — they start with &lt;code dir=&quot;auto&quot;&gt;//&lt;/code&gt; instead of &lt;code dir=&quot;auto&quot;&gt;https://&lt;/code&gt;, so you need to prepend the scheme yourself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prices come in two flavors&lt;/strong&gt; — &lt;code dir=&quot;auto&quot;&gt;salePrice&lt;/code&gt; is the discounted price, &lt;code dir=&quot;auto&quot;&gt;originalPrice&lt;/code&gt; is the pre-discount price. Not every item has both.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ads are identified by &lt;code dir=&quot;auto&quot;&gt;productType&lt;/code&gt;&lt;/strong&gt; — sponsored listings have &lt;code dir=&quot;auto&quot;&gt;&quot;productType&quot;: &quot;ad&quot;&lt;/code&gt; while organic results are &lt;code dir=&quot;auto&quot;&gt;&quot;natural&quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code dir=&quot;auto&quot;&gt;tradeDesc&lt;/code&gt; field is a human-readable sold count&lt;/strong&gt; — strings like &lt;code dir=&quot;auto&quot;&gt;&quot;10,000+ sold&quot;&lt;/code&gt; rather than raw numbers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deduplicate and save:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;seen &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;unique &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; p &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; products:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;pid &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;product_id&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; pid &lt;/span&gt;&lt;span&gt;and&lt;/span&gt;&lt;span&gt; pid &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; seen:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;seen.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pid&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;unique.&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;aliexpress_products.json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;w&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;utf-8&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; f:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;json.&lt;/span&gt;&lt;span&gt;dump&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unique&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;indent&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensure_ascii&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;False&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;the-output&quot;&gt;The Output&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;After running both scripts, you get a clean JSON file with 60 products per page:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;product_id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;1005007595844944&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;title&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Men Classical Square Polarized Sports Sunglasses Lightweight PC Frame UV400&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;url&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://www.aliexpress.com/item/1005007595844944.html&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;image&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://ae-pic-a1.aliexpress-media.com/kf/S0af78966b3614be2b75b067b0c7c51e1z.jpg&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;US $0.99&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;price_original&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;US $6.32&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;discount_pct&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;84&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;currency&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;USD&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;rating&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;4.7&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;sold&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;5,000+ sold&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;is_ad&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;things-to-watch-out-for&quot;&gt;Things to Watch Out For&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The locale cookie is essential.&lt;/strong&gt; Without &lt;code dir=&quot;auto&quot;&gt;aep_usuc_f&lt;/code&gt;, you’ll get results in whatever language matches the Cloudflare edge node’s geography. The &lt;code dir=&quot;auto&quot;&gt;intl_locale&lt;/code&gt; cookie reinforces it but &lt;code dir=&quot;auto&quot;&gt;aep_usuc_f&lt;/code&gt; does the heavy lifting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The &lt;code dir=&quot;auto&quot;&gt;cookies&lt;/code&gt; API parameter — not &lt;code dir=&quot;auto&quot;&gt;setCookies&lt;/code&gt;.&lt;/strong&gt; Cloudflare’s Browser Rendering API uses &lt;code dir=&quot;auto&quot;&gt;cookies&lt;/code&gt; as the parameter name. Using &lt;code dir=&quot;auto&quot;&gt;setCookies&lt;/code&gt; (which is the Puppeteer method name) will give you a 400 error with an “unrecognized keys” message.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The response might be JSON-wrapped.&lt;/strong&gt; Depending on the endpoint configuration, Cloudflare may return the HTML wrapped in a JSON object like &lt;code dir=&quot;auto&quot;&gt;{&quot;success&quot;: true, &quot;result&quot;: &quot;&amp;#x3C;html&gt;...&quot;}&lt;/code&gt;. Handle both formats:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;wrapper &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; json.&lt;/span&gt;&lt;span&gt;load&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;html &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; wrapper[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;except&lt;/span&gt;&lt;span&gt; (json.JSONDecodeError, &lt;/span&gt;&lt;span&gt;KeyError&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;html &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; f.&lt;/span&gt;&lt;span&gt;read&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bracket counting beats regex for extraction.&lt;/strong&gt; The &lt;code dir=&quot;auto&quot;&gt;_init_data_&lt;/code&gt; blob can be 400KB+ of deeply nested JSON. Regex will choke on it. Counting &lt;code dir=&quot;auto&quot;&gt;{&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;}&lt;/code&gt; to find the matching brace is simple and bulletproof.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;60 items per page is the default.&lt;/strong&gt; AliExpress returns 60 products per search page. To get more, you’d need to paginate by adding &lt;code dir=&quot;auto&quot;&gt;&amp;#x26;page=2&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;&amp;#x26;page=3&lt;/code&gt;, etc. to the URL and making additional requests.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;aliexpress-vs-walmart-different-frameworks-same-idea&quot;&gt;AliExpress vs Walmart: Different Frameworks, Same Idea&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The core technique is identical — find the embedded data blob, parse it, skip DOM scraping entirely. The difference is just where the data lives:&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Walmart&lt;/th&gt;&lt;th&gt;AliExpress&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Framework&lt;/td&gt;&lt;td&gt;Next.js&lt;/td&gt;&lt;td&gt;Custom (“dida”)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Data location&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;&amp;#x3C;script id=&quot;__NEXT_DATA__&quot;&gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;window._dida_config_._init_data_&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Extraction method&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;soup.find(&quot;script&quot;, id=...)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Bracket counting in script tags&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Items per page&lt;/td&gt;&lt;td&gt;~40&lt;/td&gt;&lt;td&gt;60&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Locale handling&lt;/td&gt;&lt;td&gt;Automatic (US site)&lt;/td&gt;&lt;td&gt;Requires cookies&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Both give you structured JSON with prices, ratings, images, and seller info. Both are far more reliable than parsing HTML elements. And both run entirely on Cloudflare’s infrastructure — no local browser needed.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;AliExpress is a trickier target than Walmart — the data is harder to find, the locale problem adds a step, and the extraction requires bracket counting instead of a simple ID lookup. But once you know the pattern, it’s just as clean. You get structured product data from a single API call, with no browser dependencies on your machine.&lt;/p&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;_init_data_&lt;/code&gt; blob contains everything the page renders — products, filters, pagination, related searches, SEO metadata. If AliExpress shows it on the page, it’s in that JSON.&lt;/p&gt;</content:encoded></item><item><title>Scraping Walmart Ecommerce Data With Cloudflare Browser Rendering</title><link>https://browserflare.xyz/blog/scraping-walmart-ecommerce-data-with-cloudflare-browser-rendering/</link><guid isPermaLink="true">https://browserflare.xyz/blog/scraping-walmart-ecommerce-data-with-cloudflare-browser-rendering/</guid><pubDate>Tue, 07 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you’ve ever tried to scrape ecommerce apps like walmart, you know the pain. It’s a React app. The HTML you get from a plain &lt;code dir=&quot;auto&quot;&gt;requests.get()&lt;/code&gt; is basically an empty shell — no products, no prices, nothing useful. The actual data only shows up after JavaScript runs, hydrates the page, and renders everything client-side.&lt;/p&gt;
&lt;p&gt;So you need a real browser. But spinning up Puppeteer or Playwright locally is slow, fragile, and annoying to deploy. That’s where Cloudflare Browser Rendering comes in.&lt;/p&gt;
&lt;aside aria-label=&quot;Skip the code?&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Skip the code?&lt;/p&gt;&lt;div&gt;&lt;p&gt;If you’d rather point-and-click than write Python scripts, &lt;a href=&quot;https://browserflare.xyz/&quot;&gt;Browserflare&lt;/a&gt; lets you scrape, crawl, and extract structured data from sites like Walmart through a desktop GUI — no coding required. Just enter a URL, configure your selectors, and export the results. &lt;a href=&quot;https://browserflare.xyz/#download&quot;&gt;Download it here&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;div&gt;&lt;h2 id=&quot;the-idea&quot;&gt;The Idea&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Instead of managing headless browsers yourself, you make an API call to Cloudflare. They spin up a browser instance on their edge network, navigate to the URL, wait for the page to fully render, and hand you back the HTML. It’s like having a browser-as-a-service.&lt;/p&gt;
&lt;p&gt;The approach here is dead simple — two steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fetch&lt;/strong&gt; the fully rendered HTML via Cloudflare’s API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parse&lt;/strong&gt; the structured data out of it locally&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;No browser dependencies on your machine. No Selenium. No Docker containers running Chrome. Just HTTP requests and JSON parsing.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;step-1-getting-the-html&quot;&gt;Step 1: Getting the HTML&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The first script hits Cloudflare’s &lt;code dir=&quot;auto&quot;&gt;/content&lt;/code&gt; endpoint. You give it a URL and some options, and it gives you back rendered HTML.&lt;/p&gt;
&lt;p&gt;First, grab your Cloudflare credentials from environment variables (or a &lt;code dir=&quot;auto&quot;&gt;.env&lt;/code&gt; file):&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; requests&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; dotenv &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; load_dotenv&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;load_dotenv&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;ACCOUNT_ID&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os.environ.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;CF_ACCOUNT_ID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;API_TOKEN&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os.environ.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;CF_API_TOKEN&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;endpoint &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;https://api.cloudflare.com/client/v4/accounts/&lt;/span&gt;&lt;span&gt;{ACCOUNT_ID}&lt;/span&gt;&lt;span&gt;/browser-rendering/content&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now build the payload. The key detail is the &lt;code dir=&quot;auto&quot;&gt;waitForSelector&lt;/code&gt; option. Walmart’s product grid doesn’t appear instantly — React needs a moment to mount and render the components. By telling Cloudflare to wait for &lt;code dir=&quot;auto&quot;&gt;[data-testid=&apos;item-stack&apos;]&lt;/code&gt; to appear in the DOM, we make sure the products have actually loaded before the HTML gets captured.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;SEARCH_QUERY&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;sunglasses&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;payload &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;https://www.walmart.com/search?q=&lt;/span&gt;&lt;span&gt;{SEARCH_QUERY}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;gotoOptions&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;waitUntil&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;domcontentloaded&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;60000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;waitForSelector&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;selector&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;[data-testid=&apos;item-stack&apos;]&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;30000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;viewport&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;width&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1280&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;height&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;720&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Then fire it off and save the result:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;headers &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Content-Type&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;application/json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Authorization&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;Bearer &lt;/span&gt;&lt;span&gt;{API_TOKEN}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; requests.&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;endpoint&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;payload&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; resp.status_code &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;walmart_search_raw.html&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;w&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;utf-8&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; f:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;f.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resp.text&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;Saved &lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resp.text&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:,&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; chars of rendered HTML&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;Error &lt;/span&gt;&lt;span&gt;{resp.status_code}&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;{resp.text&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;500&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;That’s the entire fetch step. One POST request, and you get back the full page HTML as if you’d opened it in Chrome and hit “View Source” after everything loaded.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;step-2-parsing-the-data&quot;&gt;Step 2: Parsing the Data&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Here’s where it gets interesting. You &lt;em&gt;could&lt;/em&gt; parse the HTML with BeautifulSoup, find all the product cards, and extract text from each element. But there’s a much better way.&lt;/p&gt;
&lt;p&gt;Walmart is built with Next.js, and Next.js apps embed all their page data in a &lt;code dir=&quot;auto&quot;&gt;&amp;#x3C;script id=&quot;__NEXT_DATA__&quot;&gt;&lt;/code&gt; tag. It’s a giant JSON blob containing everything the page needs to render — including all the product data in a clean, structured format.&lt;/p&gt;
&lt;p&gt;So instead of wrestling with CSS selectors and fragile DOM traversal, you just grab that JSON blob directly:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; bs4 &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; BeautifulSoup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;soup &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BeautifulSoup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;html&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;html.parser&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;script &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; soup.&lt;/span&gt;&lt;span&gt;find&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;__NEXT_DATA__&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;next_data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; json.&lt;/span&gt;&lt;span&gt;loads&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;script.string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;From there, the product data lives at a predictable path:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;search_result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; next_data[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;props&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;pageProps&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;initialData&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;searchResult&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;item_stacks &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; search_result.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;itemStacks&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now loop through the stacks and pull out what you need. One thing to watch for — not every item in a stack is an actual product. Walmart mixes in ads, placeholders, and other junk, so you need to filter:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;products &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; stack &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; item_stacks:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; item &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; stack.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;items&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# Skip non-product entries&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;__typename&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;SearchProduct&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;usItemId&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;continue&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;price_info &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;priceInfo&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;image_info &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;imageInfo&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;product &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;brand&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;brand&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;usItemId&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;usItemId&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://www.walmart.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; item[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;canonicalUrl&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                   &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;canonicalUrl&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: image_info.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;thumbnailUrl&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;price_current&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: price_info.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;linePrice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;price_was&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: price_info.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;wasPrice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;rating&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;averageRating&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;review_count&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;numberOfReviews&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;seller&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;sellerName&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;in_stock&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;isOutOfStock&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;True&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;is_sponsored&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: item.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;isSponsoredFlag&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;False&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;products.&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;product&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The same product can show up in multiple stacks (once in organic results, once as a sponsored listing), so deduplicate before saving:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;seen &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;unique &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; p &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; products:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;uid &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;usItemId&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; uid &lt;/span&gt;&lt;span&gt;and&lt;/span&gt;&lt;span&gt; uid &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; seen:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;seen.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;uid&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;unique.&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;walmart_products.json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;w&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;utf-8&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; f:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;json.&lt;/span&gt;&lt;span&gt;dump&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unique&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;indent&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensure_ascii&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;False&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Names, prices, ratings, review counts, seller info, availability, images — all neatly organized. No regex. No “find the third div inside the second span” nonsense.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-this-approach-works-well&quot;&gt;Why This Approach Works Well&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;It’s resilient.&lt;/strong&gt; Walmart can redesign their entire UI and change every CSS class name, but as long as they’re using Next.js, the &lt;code dir=&quot;auto&quot;&gt;__NEXT_DATA__&lt;/code&gt; structure stays consistent. You’re reading the same data source that React itself uses to render the page.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It’s clean.&lt;/strong&gt; You get structured JSON instead of messy HTML. Prices come as actual values, not strings you need to strip dollar signs from. Ratings are numbers. URLs are relative paths you can easily make absolute.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It’s fast.&lt;/strong&gt; The Cloudflare browser call takes 10-20 seconds (it’s rendering a full page), but the parsing step is nearly instant. And since the browser runs on Cloudflare’s infrastructure, you’re not burning your own CPU.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It’s simple to deploy.&lt;/strong&gt; No browser binaries to install. No Playwright or Puppeteer dependencies. The fetch step is just an HTTP POST. The parse step only needs &lt;code dir=&quot;auto&quot;&gt;beautifulsoup4&lt;/code&gt; and the standard library.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;things-to-watch-out-for&quot;&gt;Things to Watch Out For&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;A few gotchas I ran into:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The response format can vary.&lt;/strong&gt; Sometimes Cloudflare wraps the HTML in a JSON object with a &lt;code dir=&quot;auto&quot;&gt;result&lt;/code&gt; key, sometimes it returns raw HTML. Handle both:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;walmart_search_raw.html&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;utf-8&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; f:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;wrapper &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; json.&lt;/span&gt;&lt;span&gt;load&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;html &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; wrapper[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;except&lt;/span&gt;&lt;span&gt; (json.JSONDecodeError, &lt;/span&gt;&lt;span&gt;KeyError&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;walmart_search_raw.html&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;utf-8&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; f:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;html &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; f.&lt;/span&gt;&lt;span&gt;read&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare has usage limits.&lt;/strong&gt; Browser Rendering isn’t free — you get a certain number of requests per month on the free tier. For bulk scraping, keep that in mind.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Timeouts need to be generous.&lt;/strong&gt; Walmart’s page is heavy. The 60-second &lt;code dir=&quot;auto&quot;&gt;gotoOptions&lt;/code&gt; timeout and 30-second &lt;code dir=&quot;auto&quot;&gt;waitForSelector&lt;/code&gt; timeout aren’t arbitrary — shorter values will fail intermittently.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;the-output&quot;&gt;The Output&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;After running both scripts, you end up with a clean JSON file. Each product looks something like this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Ray-Ban RB2132 New Wayfarer Sunglasses&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;brand&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Ray-Ban&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;usItemId&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;123456789&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;url&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://www.walmart.com/ip/...&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;image&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://i5.walmartimages.com/...&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;price_current&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$129.99&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;rating&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;4.6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;review_count&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;342&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;seller&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Walmart.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;in_stock&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;is_sponsored&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;From here you can do whatever you want — feed it into a price tracker, build a comparison tool, run analytics, or just browse products without the ad clutter.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The combination of Cloudflare Browser Rendering and Next.js’s &lt;code dir=&quot;auto&quot;&gt;__NEXT_DATA__&lt;/code&gt; is genuinely one of the cleanest scraping patterns I’ve come across. You offload the hard part (running a browser) to Cloudflare, and you get structured data for free because of how Next.js works.&lt;/p&gt;
&lt;p&gt;It’s not going to work for every site — only Next.js apps have that convenient data blob. But for the ones that do, it beats traditional DOM scraping by a mile.&lt;/p&gt;</content:encoded></item><item><title>Hello World</title><link>https://browserflare.xyz/blog/hello-world/</link><guid isPermaLink="true">https://browserflare.xyz/blog/hello-world/</guid><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is the first blog post on Browserflare. Stay tuned for more updates!&lt;/p&gt;</content:encoded></item></channel></rss>