{"id":40507,"date":"2026-08-31T14:43:04","date_gmt":"2026-08-31T14:43:04","guid":{"rendered":"https:\/\/nodemaven.com\/?p=40507"},"modified":"2026-08-31T14:43:05","modified_gmt":"2026-08-31T14:43:05","slug":"web-scraping-vs-api","status":"publish","type":"post","link":"https:\/\/nodemaven.com\/ru\/blog\/web-scraping-vs-api\/","title":{"rendered":"Web Scraping vs API: How to Extract JSON Data With Python"},"content":{"rendered":"<p>If a website already loads data through a JSON endpoint, calling that endpoint is often faster than scraping HTML or running Selenium. You get structured data directly from the source the page uses, without waiting for a browser to render every button, card, script, image, and popup.<\/p>\n\n\n\n<p>HTML scraping and browser scraping still have their place. Some websites put the data directly in the page source. Others require clicks, scrolling, forms, or a rendered browser. But on many dynamic websites, the cleanest route starts in the browser&#8217;s Network tab.<\/p>\n\n\n\n<p>The modern web gives scrapers a reason to check that path early. The <a href=\"https:\/\/almanac.httparchive.org\/en\/2024\/javascript\">HTTP Archive Web Almanac JavaScript chapter<\/a> reported that median JavaScript payloads reached <strong>558 KB on mobile<\/strong> \u0438 <strong>613 KB on desktop<\/strong> in 2024. Many pages now load the first HTML shell, then fetch the actual data through background requests.<\/p>\n\n\n\n<p>For example, imagine you are trying to scrape a hotel booking engine. The classic HTML method returns empty containers. Selenium can render the rooms, but every page is slow and errors appear during pagination. If the room prices, dates, names, and availability come from a background JSON request, you can collect that data straight from the endpoint.<\/p>\n\n\n\n<p>This guide shows how to inspect a page, find the API request, test it in Postman, convert it to Python, handle pagination, and save the results to CSV.<\/p>\n\n\n<div\n\t\t\t\n\t\t\tclass=\"so-widget-rhinocore-addons-rhino-alert-banner so-widget-rhinocore-addons-rhino-alert-banner-default-d75171398898\"\n\t\t\t\n\t\t><div class=\"rhino-widget rhino-widget--rhinocore-addons-rhino-alert-banner section-alert\"    style=\"--alert-background-color: #E6E6FF\"\n>\n            <div class=\"section-alert__icon\">\n            <img decoding=\"async\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/02\/icon-4.svg\" alt=\"\" loading=\"lazy\" width=\"64\" height=\"64\">        <\/div>\n    \n            <div class=\"section-alert__main\">\n                            <div class=\"section-alert__title\">Scale API Scraping With Clean Sessions<\/div>\n            \n                            <div class=\"section-alert__description\"><p>Use NodeMaven residential proxies, sticky sessions, geo-targeting, and Scraping Browser for tougher JavaScript-heavy pages. Start with <strong>750 \u041c\u0411 \u0434\u043b\u044f $3.50<\/strong>.<\/p>\n<\/div>\n                    <\/div>\n    \n            <a\n            class=\"section-alert__button b-btn b-btn--static-xl b-btn--secondary-black\"\n            href=\"https:\/\/dashboard.nodemaven.com\/checkout\/pag\/trial\"\n            >\n            \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441        <\/a>\n    <\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-quick-answer-should-you-use-web-scraping-or-an-api\"><strong>Quick answer: should you use web scraping or an API?<\/strong><\/h2>\n\n\n\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <strong>API-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/strong> when the page loads clean JSON through Fetch\/XHR and the endpoint can be requested safely.<\/p>\n\n\n\n<p>\u041f\u0440\u043e\u0431\u0443\u0439 <strong>HTML-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/strong> when the data is already present in the page source.<\/p>\n\n\n\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <a href=\"https:\/\/nodemaven.com\/ru\/blog\/scraping-browser-guide\/\"><strong>browser scraping<\/strong><\/a> when the workflow needs JavaScript rendering, clicks, scrolling, screenshots, form submissions, or visual debugging.<\/p>\n\n\n\n<p>A frontend endpoint visible in DevTools is not automatically grant permission to reuse it at scale. Check the website&#8217;s terms, access rules, and whether an official API exists before building a large scraper.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-web-scraping-vs-api-what-is-the-difference\"><strong>Web scraping vs API: what is the difference?<\/strong><\/h2>\n\n\n\n<p><a href=\"https:\/\/nodemaven.com\/ru\/blog\/the-best-ai-web-scraping-stack-in-2026\/\">\u0412\u0435\u0431-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/a> extracts data from the website page. API scraping sends a request to the endpoint the website uses to load structured data, usually JSON.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>\u041c\u0435\u0442\u043e\u0434<\/strong><\/td><td><strong>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/strong><\/td><td><strong>\u041b\u0443\u0447\u0448\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0441\u0442\u0430\u0440\u0442\u0430<\/strong><\/td><\/tr><tr><td>HTML-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/td><td>Downloads page HTML and parses elements<\/td><td>Static pages<\/td><\/tr><tr><td>\u0411\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0439 \u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/td><td>Opens the page with Selenium or Playwright<\/td><td>JavaScript-heavy pages, clicks, scrolling<\/td><\/tr><tr><td>API endpoint scraping<\/td><td>Calls the background JSON request directly<\/td><td>Dynamic pages with visible XHR\/fetch data<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>In a basic <a href=\"https:\/\/nodemaven.com\/ru\/blog\/web-scraping\/\">\u0432\u0435\u0431-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/a> workflow, the scraper downloads HTML and extracts text from selectors. NodeMaven&#8217;s <a href=\"https:\/\/nodemaven.com\/ru\/blog\/python-web-scraping\/\">\u0432\u0435\u0431-\u0441\u043a\u0440\u0430\u043f\u0438\u043d\u0433 \u043d\u0430 Python<\/a> guide covers that classic approach with Requests and BeautifulSoup.<\/p>\n\n\n\n<p>API endpoint scraping works differently. The browser loads a page, JavaScript asks the server for data, and the server returns JSON. Instead of scraping the rendered card or table, your Python script sends a similar request and reads the JSON response.<\/p>\n\n\n\n<p>That is why API scraping can be faster and cleaner. The data is already structured before the website turns it into visual elements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-official-apis-vs-frontend-endpoints\"><strong>Official APIs vs frontend endpoints<\/strong><\/h2>\n\n\n\n<p>An official API is documented and built for developers. It usually has authentication, rate limits, versioning, response examples, and usage rules.<\/p>\n\n\n\n<p>A frontend endpoint is the request a website&#8217;s own interface sends in the background. You can often see it in Chrome DevTools under Fetch\/XHR. It may return clean JSON, but it can change without notice and may depend on cookies, tokens, headers, or signed payloads.<\/p>\n\n\n\n<p>Use an official API when it provides the fields and limits you need. Use a frontend endpoint only when access is allowed and the request can be reproduced reliably. Use browser scraping when the endpoint is too hard to reproduce or the workflow depends on the rendered page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-api-endpoint-scraping-can-be-faster-than-selenium\"><strong>Why API endpoint scraping can be faster than Selenium<\/strong><\/h2>\n\n\n\n<p>A hotel booking engine may show room cards only after JavaScript loads prices and availability from an API. Selenium can wait for the rendered cards, but every run brings <strong>browser startup, JavaScript execution, images, CSS, popups, and wait logic<\/strong>.<\/p>\n\n\n\n<p>API endpoint scraping skips that rendered interface when the same data is already available as JSON. Instead of waiting for a browser to display the room card, your script requests <strong>the data behind it<\/strong>.<\/p>\n\n\n\n<p>This comes up often in developer discussions. In a <a href=\"https:\/\/stackoverflow.com\/questions\/78215046\/slow-scraping-using-selenium\">Stack Overflow thread about slow Selenium scraping<\/a>, the answer points to Selenium&#8217;s browser overhead and recommends inspecting the Network tab to reproduce the underlying requests with Python.<\/p>\n\n\n\n<p>That approach can reduce:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>long CSS selectors for every field<\/li>\n\n\n\n<li>waits for rendered elements<\/li>\n\n\n\n<li>browser crashes<\/li>\n\n\n\n<li>slow pagination<\/li>\n\n\n\n<li>messy HTML parsing<\/li>\n\n\n\n<li>heavy CPU and memory use<\/li>\n<\/ul>\n\n\n\n<p>But API endpoint scraping is not always the right route. Some endpoints require <strong>private authorization, CSRF values, one-time tokens, signed payloads, or strict session validation<\/strong>. Others change without warning because they are built for the website frontend, not for external developers.<\/p>\n\n\n\n<p>If the endpoint is restricted or the workflow needs <strong>clicks, screenshots, scrolling, forms, or visual debugging<\/strong>, use browser scraping instead. <a href=\"https:\/\/nodemaven.com\/ru\/blog\/playwright-scraping\/\">Playwright<\/a> \u0438 <a href=\"https:\/\/nodemaven.com\/ru\/blog\/selenium-scraping\/\">Selenium<\/a> both open the page, run JavaScript, and work with the rendered result.<\/p>\n\n\n\n<p>For browser-based scraping that needs <strong>cloud execution, proxies, CAPTCHA support, Live Browser debugging, and session recordings<\/strong>, <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/scraping-browser\/\">\u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0434\u043b\u044f \u0441\u043a\u0440\u0430\u043f\u0438\u043d\u0433\u0430 NodeMaven<\/a> gives you a managed Chrome environment instead of maintaining the browser stack yourself.<\/p>\n\n\n\n<p>If the website offers an official API with the fields and limits you need, start there. It is <strong>documented, versioned, and usually easier to maintain<\/strong> than a frontend endpoint found in DevTools.<\/p>\n\n\n<div\n\t\t\t\n\t\t\tclass=\"so-widget-rhinocore-addons-rhino-alert-banner so-widget-rhinocore-addons-rhino-alert-banner-default-d75171398898\"\n\t\t\t\n\t\t><div class=\"rhino-widget rhino-widget--rhinocore-addons-rhino-alert-banner section-alert\"    style=\"--alert-background-color: #E6E6FF\"\n>\n            <div class=\"section-alert__icon\">\n            <img decoding=\"async\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/02\/icon-4.svg\" alt=\"\" loading=\"lazy\" width=\"64\" height=\"64\">        <\/div>\n    \n            <div class=\"section-alert__main\">\n                            <div class=\"section-alert__title\">Scale API Scraping With Clean Sessions<\/div>\n            \n                            <div class=\"section-alert__description\"><p>Use NodeMaven residential proxies, sticky sessions, geo-targeting, and Scraping Browser for tougher JavaScript-heavy pages. Start with <strong>750 \u041c\u0411 \u0434\u043b\u044f $3.50<\/strong>.<\/p>\n<\/div>\n                    <\/div>\n    \n            <a\n            class=\"section-alert__button b-btn b-btn--static-xl b-btn--secondary-black\"\n            href=\"https:\/\/dashboard.nodemaven.com\/checkout\/pag\/trial\"\n            >\n            \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441        <\/a>\n    <\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-tutorial-setup-tools-and-demo-website\"><strong>Tutorial setup: tools and demo website<\/strong><\/h2>\n\n\n\n<p>You need four things for this tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u0425\u0440\u043e\u043c<\/strong><\/li>\n\n\n\n<li><strong>Postman<\/strong><\/li>\n\n\n\n<li><strong>Python 3<\/strong><\/li>\n\n\n\n<li><strong>\u0417\u0430\u043f\u0440\u043e\u0441\u044b<\/strong><\/li>\n<\/ul>\n\n\n\n<p>For the demo, use <a href=\"https:\/\/quotes.toscrape.com\/scroll\">Quotes to Scrape infinite scroll<\/a>. It is built for scraping practice, loads data dynamically, and exposes a clean JSON endpoint.<\/p>\n\n\n\n<p>You will install Requests inside a virtual environment before running the Python examples. This avoids the externally-managed-environment error that can appear on newer Homebrew Python versions.<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"python3%20-m%20venv%20scraping-env%0A%0Asource%20scraping-env%2Fbin%2Factivate%0A%0Apython3%20-m%20pip%20install%20requests\"><\/code><\/pre><\/figure>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-1-find-the-api-endpoint-in-chrome-devtools\"><strong>Step 1: find the API endpoint in Chrome DevTools<\/strong><\/h2>\n\n\n\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c <a href=\"https:\/\/quotes.toscrape.com\/scroll\">Quotes to Scrape infinite scroll<\/a> in Chrome.<\/p>\n\n\n\n<p>Right-click the page and select <strong>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c<\/strong>. Open the <strong>\u0421\u0435\u0442\u044c<\/strong> tab, then click <strong>Fetch\/XHR<\/strong>. Reload the page or scroll until new requests appear.<\/p>\n\n\n\n<p>In the request list, click <strong>quotes?page=1<\/strong>. Then open the <strong>Preview<\/strong> tab. If you see fields like has_next, page, quotes, and top_ten_tags, you have found the JSON response behind the page.<\/p>\n\n\n\n<p>For this demo, the endpoint is:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"plaintext\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-plaintext\" data-rhino-code=\"https%3A%2F%2Fquotes.toscrape.com%2Fapi%2Fquotes%3Fpage%3D1\"><\/code><\/pre><\/figure>\n\n\n<p>The page=1 part controls pagination. Later, the Python script will change that value to collect page 2, page 3, and the rest of the available results.<\/p>\n\n\n\n<p>Chrome&#8217;s <a href=\"https:\/\/developer.chrome.com\/docs\/devtools\/network\/reference\/?hl=en\">Network features reference<\/a> explains how the Network panel shows requests made by the page, including Fetch\/XHR requests and response previews.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"504\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-1024x504.png\" alt=\"API Scraping tutorial\" class=\"wp-image-40509\" srcset=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-1024x504.png 1024w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-300x148.png 300w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-768x378.png 768w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-1536x757.png 1536w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-2048x1009.png 2048w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-1-18x9.png 18w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-2-test-the-endpoint-in-postman\"><strong>Step 2: Test the Endpoint in Postman<\/strong><\/h2>\n\n\n\n<p>After you find the request in Chrome DevTools, right-click quotes?page=1 and choose:<\/p>\n\n\n\n<p><strong>Copy &gt; Copy as cURL<\/strong><\/p>\n\n\n\n<p>Open Postman and paste the copied cURL into the request URL field. For this demo, Postman extracts the endpoint and shows it as:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"plaintext\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-plaintext\" data-rhino-code=\"https%3A%2F%2Fquotes.toscrape.com%2Fapi%2Fquotes%3Fpage%3D1\"><\/code><\/pre><\/figure>\n\n\n<p>Keep the method as GET and click <strong>Send<\/strong>.<\/p>\n\n\n\n<p>If the response panel shows <strong>200 OK<\/strong> and JSON fields such as has_next, page, and quotes, the endpoint works outside the browser.<\/p>\n\n\n\n<p>Also check the <strong>Params<\/strong> tab. Postman separates page=1 into a query parameter. This is important because the Python script will later change that value to page=2, page=3, and so on.<\/p>\n\n\n\n<p>Now open Postman\u2019s <strong>Code snippet<\/strong> panel and choose <strong>Python &#8211; Requests<\/strong>. Postman will generate Python code for the same request, including the endpoint URL, method, headers, and payload structure.<\/p>\n\n\n\n<p>For real websites, keep this generated code as your starting point. Headers, cookies, tokens, and payload values can decide whether the endpoint works outside the browser.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"602\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-1024x602.png\" alt=\"API Scraping tutorial\" class=\"wp-image-40510\" srcset=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-1024x602.png 1024w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-300x176.png 300w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-768x451.png 768w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-1536x903.png 1536w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-2048x1204.png 2048w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-2-18x12.png 18w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Postman confirms that the copied endpoint returns JSON and can be converted into a Python Requests snippet.<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-what-to-check-before-moving-to-python\"><strong>What to Check Before Moving to Python<\/strong><\/h3>\n\n\n\n<p>Before writing code, review the request in Postman.<\/p>\n\n\n\n<p>\u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0441 <strong>Request URL<\/strong>. This is the endpoint address. Then check the <strong>\u041c\u0435\u0442\u043e\u0434<\/strong>, usually GET or POST.<\/p>\n\n\n\n<p>A GET request often stores values in the URL. A POST request may send a separate payload.<\/p>\n\n\n\n<p>Next, inspect the <strong>query parameters<\/strong>. In this demo, page=1 controls pagination. On real websites, parameters can control the search term, category, city, date, currency, sort order, offset, or cursor.<\/p>\n\n\n\n<p>For POST requests, open the <strong>Payload<\/strong> tab. Booking websites may send values such as destination, checkin, checkout, adults, currency, and page. E-commerce endpoints may use query, category, sort, limit, and offset.<\/p>\n\n\n\n<p>Before moving to Python, check:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Headers:<\/strong> content type, accept, user agent, and request-specific headers<\/li>\n\n\n\n<li><strong>Cookies or tokens:<\/strong> session values, CSRF tokens, or authorization values<\/li>\n\n\n\n<li><strong>Response shape:<\/strong> where the fields you need appear in the JSON<\/li>\n\n\n\n<li><strong>Pagination fields:<\/strong> values such as page, offset, cursor, has_next, or next<\/li>\n<\/ul>\n\n\n\n<p>If the Python request fails later, one of these pieces is often missing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-3-create-and-run-the-first-python-request\"><strong>Step 3: Create and Run the First Python Request<\/strong><\/h2>\n\n\n\n<p>Open a code editor, such as VS Code, Cursor, or TextEdit in plain text mode.<\/p>\n\n\n\n<p>Create a new file named:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"plaintext\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-plaintext\" data-rhino-code=\"quotes_api_scraper.py\"><\/code><\/pre><\/figure>\n\n\n<p>Paste the <strong>Python &#8211; Requests<\/strong> code generated by Postman into the file:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"python\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-python\" data-rhino-code=\"import%20requests%0A%0Aurl%20%3D%20%22https%3A%2F%2Fquotes.toscrape.com%2Fapi%2Fquotes%3Fpage%3D1%22%0A%0Apayload%20%3D%20%7B%7D%0A%0Aheaders%20%3D%20%7B%0A%0A%20%20%27accept%27%3A%20%27%2A%2F%2A%27%2C%0A%0A%20%20%27accept-language%27%3A%20%27en-US%2Cen%3Bq%3D0.9%27%2C%0A%0A%20%20%27priority%27%3A%20%27u%3D1%2C%20i%27%2C%0A%0A%20%20%27referer%27%3A%20%27https%3A%2F%2Fquotes.toscrape.com%2Fscroll%27%2C%0A%0A%20%20%27sec-ch-ua%27%3A%20%27%22Not%3DA%3FBrand%22%3Bv%3D%2299%22%2C%20%22Google%20Chrome%22%3Bv%3D%22151%22%2C%20%22Chromium%22%3Bv%3D%22151%22%27%2C%0A%0A%20%20%27sec-ch-ua-mobile%27%3A%20%27%3F1%27%2C%0A%0A%20%20%27sec-ch-ua-platform%27%3A%20%27%22Android%22%27%2C%0A%0A%20%20%27sec-fetch-dest%27%3A%20%27empty%27%2C%0A%0A%20%20%27sec-fetch-mode%27%3A%20%27cors%27%2C%0A%0A%20%20%27sec-fetch-site%27%3A%20%27same-origin%27%2C%0A%0A%20%20%27user-agent%27%3A%20%27Mozilla%2F5.0%20%28Linux%3B%20Android%2015%3B%20Pixel%209%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F151.0.0.0%20Mobile%20Safari%2F537.36%27%2C%0A%0A%20%20%27x-requested-with%27%3A%20%27XMLHttpRequest%27%0A%0A%7D%0A%0Aresponse%20%3D%20requests.request%28%22GET%22%2C%20url%2C%20headers%3Dheaders%2C%20data%3Dpayload%29%0A%0Aprint%28response.text%29\"><\/code><\/pre><\/figure>\n\n\n<p>Save the file.<\/p>\n\n\n\n<p>Open Terminal and go to the folder where you saved it. For example, if you saved it on Desktop, run:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"cd%20~%2FDesktop\"><\/code><\/pre><\/figure>\n\n\n<p><\/p>\n\n\n\n<p>Create a virtual environment:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"python3%20-m%20venv%20scraping-env\"><\/code><\/pre><\/figure>\n\n\n<p><\/p>\n\n\n\n<p>Activate it:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"source%20scraping-env%2Fbin%2Factivate\"><\/code><\/pre><\/figure>\n\n\n<p><\/p>\n\n\n\n<p>Install Requests inside the virtual environment:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"python3%20-m%20pip%20install%20requests\"><\/code><\/pre><\/figure>\n\n\n<p><\/p>\n\n\n\n<p>Run the script:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"python3%20quotes_api_scraper.py\"><\/code><\/pre><\/figure>\n\n\n<p><\/p>\n\n\n\n<p>If everything works, Terminal will print the JSON response.<\/p>\n\n\n\n<p>At this stage, the goal is simple: <strong>confirm that Python can send the same request you tested in Postman<\/strong>.<\/p>\n\n\n\n<p>If you see an error saying the file cannot be found, check the filename. On Mac, TextEdit may save the file as .rtf.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-4-collect-all-pages-and-save-to-csv\"><strong>Step 4: Collect All Pages and Save to CSV<\/strong><\/h2>\n\n\n\n<p>Go back to quotes_api_scraper.py.<\/p>\n\n\n\n<p>Now replace the test code with a full scraper. This version keeps the same headers from Postman, changes the page value automatically, and saves the results to quotes.csv.<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"python\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-python\" data-rhino-code=\"import%20csv%0A%0Aimport%20requests%0A%0Apayload%20%3D%20%7B%7D%0A%0Aheaders%20%3D%20%7B%0A%0A%C2%A0%C2%A0%27accept%27%3A%20%27%2A%2F%2A%27%2C%0A%0A%C2%A0%C2%A0%27accept-language%27%3A%20%27en-US%2Cen%3Bq%3D0.9%27%2C%0A%0A%C2%A0%C2%A0%27priority%27%3A%20%27u%3D1%2C%20i%27%2C%0A%0A%C2%A0%C2%A0%27referer%27%3A%20%27https%3A%2F%2Fquotes.toscrape.com%2Fscroll%27%2C%0A%0A%C2%A0%C2%A0%27sec-ch-ua%27%3A%20%27%22Not%3DA%3FBrand%22%3Bv%3D%2299%22%2C%20%22Google%20Chrome%22%3Bv%3D%22151%22%2C%20%22Chromium%22%3Bv%3D%22151%22%27%2C%0A%0A%C2%A0%C2%A0%27sec-ch-ua-mobile%27%3A%20%27%3F1%27%2C%0A%0A%C2%A0%C2%A0%27sec-ch-ua-platform%27%3A%20%27%22Android%22%27%2C%0A%0A%C2%A0%C2%A0%27sec-fetch-dest%27%3A%20%27empty%27%2C%0A%0A%C2%A0%C2%A0%27sec-fetch-mode%27%3A%20%27cors%27%2C%0A%0A%C2%A0%C2%A0%27sec-fetch-site%27%3A%20%27same-origin%27%2C%0A%0A%C2%A0%C2%A0%27user-agent%27%3A%20%27Mozilla%2F5.0%20%28Linux%3B%20Android%2015%3B%20Pixel%209%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F151.0.0.0%20Mobile%20Safari%2F537.36%27%2C%0A%0A%C2%A0%C2%A0%27x-requested-with%27%3A%20%27XMLHttpRequest%27%0A%0A%7D%0A%0Aall_quotes%20%3D%20%5B%5D%0A%0Apage%20%3D%201%0A%0Awhile%20True%3A%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0url%20%3D%20f%22https%3A%2F%2Fquotes.toscrape.com%2Fapi%2Fquotes%3Fpage%3D%7Bpage%7D%22%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0response%20%3D%20requests.request%28%22GET%22%2C%20url%2C%20headers%3Dheaders%2C%20data%3Dpayload%2C%20timeout%3D30%29%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0response.raise_for_status%28%29%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0data%20%3D%20response.json%28%29%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0all_quotes.extend%28data%5B%22quotes%22%5D%29%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0if%20not%20data%5B%22has_next%22%5D%3A%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0break%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0page%20%2B%3D%201%0A%0Awith%20open%28%22quotes.csv%22%2C%20%22w%22%2C%20newline%3D%22%22%2C%20encoding%3D%22utf-8%22%29%20as%20file%3A%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0writer%20%3D%20csv.DictWriter%28file%2C%20fieldnames%3D%5B%22text%22%2C%20%22author%22%2C%20%22tags%22%5D%29%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0writer.writeheader%28%29%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0for%20quote%20in%20all_quotes%3A%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0writer.writerow%28%7B%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%22text%22%3A%20quote%5B%22text%22%5D%2C%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%22author%22%3A%20quote%5B%22author%22%5D%5B%22name%22%5D%2C%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%22tags%22%3A%20%22%2C%20%22.join%28quote%5B%22tags%22%5D%29%2C%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%7D%29%0A%0Aprint%28f%22Saved%20%7Blen%28all_quotes%29%7D%20quotes%20to%20quotes.csv%22%29\"><\/code><\/pre><\/figure>\n\n\n<p>Save the file and run it again:<\/p>\n\n\n<figure class=\"rhino-code-snippet\" data-lang=\"bash\"><button type=\"button\" class=\"rhino-code-snippet__copy\" aria-label=\"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430\"><svg class=\"rhino-code-snippet__icon-copy\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg><svg class=\"rhino-code-snippet__icon-check\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg><\/button><span class=\"rhino-code-snippet__sr\" aria-live=\"polite\"><\/span><pre class=\"line-numbers\"><code class=\"language-bash\" data-rhino-code=\"python3%20quotes_api_scraper.py\"><\/code><\/pre><\/figure>\n\n\n<p><\/p>\n\n\n\n<p>You should now see a new file in the same folder:<\/p>\n\n\n\n<p><strong>quotes.csv<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"860\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4-1024x860.png\" alt=\"API Scraping tutorial\" class=\"wp-image-40511\" srcset=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4-1024x860.png 1024w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4-300x252.png 300w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4-768x645.png 768w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4-1536x1290.png 1536w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4-14x12.png 14w, https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-step-4.png 1676w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>That CSV is the final result of the tutorial. It contains the quote text, author name, and tags from all available pages.<\/p>\n\n\n\n<p>On real websites, keep the Postman-generated headers at first. Once the scraper works, you can remove optional headers one by one and test again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-api-scraping-needs-proxies-stable-sessions-or-geo-targeting\"><strong>Why API Scraping Needs Proxies, Stable Sessions, or Geo-Targeting<\/strong><\/h2>\n\n\n\n<p>API endpoint scraping is faster than browser automation, but <strong>requests still come from an IP address<\/strong>. At small scale, your normal connection may be enough. At larger scale, repeated endpoint requests can run into <strong>rate limits, regional responses, or IP reputation checks<\/strong>.<\/p>\n\n\n\n<p>For independent endpoint requests across many pages, <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/rotating-residential-proxies\/\">\u0440\u043e\u0442\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> help spread traffic across <strong>clean consumer IPs<\/strong>. For booking engines, local listings, or price monitoring, <strong>sticky \u0441\u0435\u0441\u0441\u0438\u0438<\/strong> help keep the request environment consistent during the job.<\/p>\n\n\n\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/isp-proxies\/\">ISP \u043f\u0440\u043e\u043a\u0441\u0438<\/a> \u043d\u0430 <strong>recurring monitoring from one stable IP<\/strong>. For Python scripts, NodeMaven&#8217;s <a href=\"https:\/\/nodemaven.com\/ru\/use-cases\/proxies-for-python\/\">\u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f Python<\/a> page covers common configuration patterns. If the endpoint returns local prices, delivery availability, or regional listings, <a href=\"https:\/\/nodemaven.com\/ru\/features\/zip-level-targeting\/\">\u0422\u0430\u0440\u0433\u0435\u0442\u0438\u043d\u0433 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 ZIP<\/a> helps tie the dataset to the target location.<\/p>\n\n\n\n<p>For a booking endpoint, <strong>prices, taxes, availability, and currency<\/strong> may change by country, city, cookies, and session state. If a scraper switches regions between requests, the CSV can become inconsistent even when the code runs correctly.<\/p>\n\n\n<div\n\t\t\t\n\t\t\tclass=\"so-widget-rhinocore-addons-rhino-alert-banner so-widget-rhinocore-addons-rhino-alert-banner-default-d75171398898\"\n\t\t\t\n\t\t><div class=\"rhino-widget rhino-widget--rhinocore-addons-rhino-alert-banner section-alert\"    style=\"--alert-background-color: #E6E6FF\"\n>\n            <div class=\"section-alert__icon\">\n            <img decoding=\"async\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/02\/icon-4.svg\" alt=\"\" loading=\"lazy\" width=\"64\" height=\"64\">        <\/div>\n    \n            <div class=\"section-alert__main\">\n                            <div class=\"section-alert__title\">Scale API Scraping With Clean Sessions<\/div>\n            \n                            <div class=\"section-alert__description\"><p>Use NodeMaven residential proxies, sticky sessions, geo-targeting, and Scraping Browser for tougher JavaScript-heavy pages. Start with <strong>750 \u041c\u0411 \u0434\u043b\u044f $3.50<\/strong>.<\/p>\n<\/div>\n                    <\/div>\n    \n            <a\n            class=\"section-alert__button b-btn b-btn--static-xl b-btn--secondary-black\"\n            href=\"https:\/\/dashboard.nodemaven.com\/checkout\/pag\/trial\"\n            >\n            \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441        <\/a>\n    <\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-common-problems-when-scraping-api-endpoints\"><strong>Common problems when scraping API endpoints<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-endpoint-works-in-chrome-but-fails-in-python\"><strong>The endpoint works in Chrome but fails in Python<\/strong><\/h3>\n\n\n\n<p>This usually means the Python request is missing something the browser sent automatically.<\/p>\n\n\n\n<p>Check headers, cookies, CSRF tokens, authorization values, signed request fields, and the POST payload. Compare the working request in DevTools with the Python request side by side.<\/p>\n\n\n\n<p>A <a href=\"https:\/\/stackoverflow.com\/questions\/67246415\/scraping-data-from-a-dynamic-web-table\">Stack Overflow thread about scraping a dynamic web table<\/a> shows this pattern clearly. The XHR requests needed a verification token from the page before the API request worked.<\/p>\n\n\n\n<p><strong>The API Returns 401, 403, or 429<\/strong><\/p>\n\n\n\n<p>A 401 or 403 usually means the endpoint requires authorization, a valid session, or a request signature. Do not force private endpoints.<\/p>\n\n\n\n<p>A 429 means too many requests. Slow down, add retries with backoff, and avoid sending every request from one IP. For larger public-data jobs, <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/rotating-residential-proxies\/\">\u0440\u043e\u0442\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> can spread requests across cleaner consumer IPs, while <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/isp-proxies\/\">ISP \u043f\u0440\u043e\u043a\u0441\u0438<\/a> are better for recurring checks that need one stable address.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-json-is-empty-or-missing-fields\"><strong>The JSON is empty or missing fields<\/strong><\/h3>\n\n\n\n<p>The request may need a date, region, search query, page number, filter, currency, or payload value.<\/p>\n\n\n\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 <strong>Payload<\/strong> \u0438 <strong>Query String Parameters<\/strong> tabs in DevTools. Then change one value and send the request again in Postman. This helps you learn which parameter controls which part of the response.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-endpoint-changes\"><strong>The endpoint changes<\/strong><\/h3>\n\n\n\n<p>Frontend endpoints are not stable contracts. A website can rename a route, change a payload, remove a field, or add a token check without warning.<\/p>\n\n\n\n<p>Add response validation before saving data. If a required field is missing, log the URL, status code, response snippet, and timestamp instead of writing broken rows into the CSV.<\/p>\n\n\n\n<p>If the endpoint depends on clicks, rendered content, private tokens, or constant browser state, switch back to browser scraping. For those cases, <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/scraping-browser\/\">\u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0434\u043b\u044f \u0441\u043a\u0440\u0430\u043f\u0438\u043d\u0433\u0430 NodeMaven<\/a> can run a real cloud browser with NodeMaven proxies, CAPTCHA support, Live Browser debugging, and session recordings.<\/p>\n\n\n<div\n\t\t\t\n\t\t\tclass=\"so-widget-rhinocore-addons-rhino-alert-banner so-widget-rhinocore-addons-rhino-alert-banner-default-d75171398898\"\n\t\t\t\n\t\t><div class=\"rhino-widget rhino-widget--rhinocore-addons-rhino-alert-banner section-alert\"    style=\"--alert-background-color: #E6E6FF\"\n>\n            <div class=\"section-alert__icon\">\n            <img decoding=\"async\" src=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/02\/icon-4.svg\" alt=\"\" loading=\"lazy\" width=\"64\" height=\"64\">        <\/div>\n    \n            <div class=\"section-alert__main\">\n                            <div class=\"section-alert__title\">Scale API Scraping With Clean Sessions<\/div>\n            \n                            <div class=\"section-alert__description\"><p>Use NodeMaven residential proxies, sticky sessions, geo-targeting, and Scraping Browser for tougher JavaScript-heavy pages. Start with <strong>750 \u041c\u0411 \u0434\u043b\u044f $3.50<\/strong>.<\/p>\n<\/div>\n                    <\/div>\n    \n            <a\n            class=\"section-alert__button b-btn b-btn--static-xl b-btn--secondary-black\"\n            href=\"https:\/\/dashboard.nodemaven.com\/checkout\/pag\/trial\"\n            >\n            \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441        <\/a>\n    <\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\"><strong>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/strong><\/h2>\n\n\n\n<p>Before building a Selenium scraper, check the Network tab. If the page already loads data through a JSON endpoint, API scraping can save time and return cleaner output.<\/p>\n\n\n\n<p>Start with one request. Test it in Postman. Convert it to Python. Add pagination. Save the data to CSV. Then check rate limits, region, cookies, session behavior, and proxy quality before scaling the job.<\/p>\n\n\n\n<p>For small tests, your own connection may be fine. For repeated API scraping, local prices, booking results, product availability, or cloud-based Python jobs, <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">clean proxies<\/a> and stable sessions can prevent a working script from turning into messy data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-faq\"><strong>FAQ<\/strong><\/h2>\n\n\n<div\n\t\t\t\n\t\t\tclass=\"so-widget-rhinocore-addons-faq so-widget-rhinocore-addons-faq-default-d75171398898\"\n\t\t\t\n\t\t>    <div class=\"rhino-widget rhino-widget--rhinocore-addons-faq section-faq\">\n        <div class=\"section-faq__list section-faq__list--columns-1\" role=\"list\" aria-label=\"\u0427\u0430\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043f\u0440\u043e\u043a\u0441\u0438 \u0432 Telegram\">\n                            <div class=\"section-faq__column\">\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">What is web scraping vs API scraping?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><a href=\"https:\/\/nodemaven.com\/ru\/blog\/web-scraping\/\"><b>\u0412\u0435\u0431-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/b><\/a><span style=\"font-weight: 400\"> extracts data from HTML or rendered pages. <\/span><b>API-\u0441\u043a\u0440\u0435\u0439\u043f\u0438\u043d\u0433<\/b><span style=\"font-weight: 400\"> sends requests to the endpoint a website uses to load structured data, usually JSON.<\/span><\/p>\n<p><span style=\"font-weight: 400\">If the page already receives clean JSON through Fetch\/XHR, API scraping is usually faster. If the data only appears after clicks, scrolling, or JavaScript rendering, browser scraping is the better route.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">How do I find an API endpoint on a website?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">Open Chrome DevTools, go to <\/span><b>\u0421\u0435\u0442\u044c<\/b><span style=\"font-weight: 400\">, filter by <\/span><b>Fetch\/XHR<\/b><span style=\"font-weight: 400\">, reload the page, and inspect requests that return JSON matching the data shown on the page.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Look for fields such as product names, prices, listing IDs, dates, authors, ratings, or pagination values. Then copy the request as cURL, test it in Postman, and convert it to Python.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">Is API scraping faster than Selenium?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">Often, yes. If the data is already available through a JSON endpoint, API scraping skips browser rendering, wait logic, selectors, images, CSS, and screenshots.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Use Selenium or Playwright when the workflow needs <\/span><b>real browser interaction<\/b><span style=\"font-weight: 400\">, such as login, forms, popups, scrolling, screenshots, or visual checks.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">Why does an API request work in Chrome but fail in Python?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">The Python request may be missing <\/span><b>headers, cookies, CSRF tokens, authorization values, query parameters, or POST payload data<\/b><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">That is why copying the request as cURL and testing it in Postman helps. It shows what the browser sent before you rewrite the request in Python.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">Do I need proxies for API scraping?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">Not for a small test. Proxies become helpful when requests are repeated, geo-specific, rate-limited, or running from cloud infrastructure.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For example, ecommerce prices, real estate listings, hotel availability, and delivery options can change by region. In those cases, residential proxies, sticky sessions, or ZIP-level targeting can help keep the dataset consistent.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">Can I scrape product prices from a major ecommerce site with API endpoints?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">Sometimes. Many ecommerce sites load prices, stock, reviews, shipping, or product recommendations through background requests.<\/span><\/p>\n<p><span style=\"font-weight: 400\">The hard part is keeping the request valid. Major ecommerce websites may use changing tokens, cookies, location settings, bot checks, and regional pricing. Start with one product page, validate the JSON response, and avoid scaling until the scraper returns the same price and availability you see in the browser.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">Can I use API scraping for real estate listings or hotel booking data?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">Yes, when the site exposes listing, price, availability, or search-result data through background requests that can be accessed within the site\u2019s rules.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For daily real estate or booking workflows, store the <\/span><b>source URL, timestamp, location, filters, and pagination values<\/b><span style=\"font-weight: 400\"> with every record. If listings depend on city, ZIP code, check-in date, or currency, keep those parameters stable across the whole run.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                            <div class=\"section-faq__item\" data-accordion=\"wrapper\" data-accordion-group=\"faq\" role=\"listitem\">\n                            <h3 class=\"section-faq__heading\">\n                                <button class=\"section-faq__trigger\" data-accordion=\"trigger\" type=\"button\" aria-expanded=\"false\">\n                                    <span class=\"section-faq__question\">Should I use API scraping for financial data or social media posts?<\/span>\n                                    <svg width=\"28\" height=\"28\" viewbox=\"0 0 28 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\">\n                                        <path d=\"M7 10.5L14 17.5L21 10.5\" stroke=\"#5D5D5D\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                                    <\/svg>\n                                <\/button>\n                            <\/h3>\n                            <div class=\"section-faq__content\">\n                                <div class=\"section-faq__answer\">\n                                    <p><span style=\"font-weight: 400\">For financial data, start with an <\/span><b>\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 API<\/b><span style=\"font-weight: 400\"> whenever possible. Portfolio projects usually need stable symbols, timestamps, prices, and historical data, so a documented API is cleaner than reverse-engineering a website endpoint.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For social media sentiment analysis, use official APIs or approved data sources first. Public web endpoints can change quickly, and logged-in or private data should not be treated as scrapeable just because it appears in the browser.<\/span><\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                    <\/div>\n                    <\/div>\n    <\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.","protected":false},"author":68,"featured_media":40513,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[212,213,205],"class_list":["post-40507","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-comparisons-reviews","tag-guides-tutorials","tag-web-scraping"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.1 (Yoast SEO v28.1) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Web Scraping vs API: Extract JSON Data With Python<\/title>\n<meta name=\"description\" content=\"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nodemaven.com\/ru\/blog\/web-scraping-vs-api\/\" \/>\n<meta property=\"og:locale\" content=\"ru_RU\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Web Scraping vs API: How to Extract JSON Data With Python\" \/>\n<meta property=\"og:description\" content=\"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nodemaven.com\/ru\/blog\/web-scraping-vs-api\/\" \/>\n<meta property=\"og:site_name\" content=\"NodeMaven\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/people\/NodeMaven\/100095402507825\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-31T14:43:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-31T14:43:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-scraping.png\" \/>\n\t<meta property=\"og:image:width\" content=\"870\" \/>\n\t<meta property=\"og:image:height\" content=\"490\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Anna\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u043e\u043c\" \/>\n\t<meta name=\"twitter:data1\" content=\"Anna\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 \u043c\u0438\u043d\u0443\u0442\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/\"},\"author\":{\"name\":\"Anna\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#\\\/schema\\\/person\\\/f3bc93327b3582e735259d2a98f7a7ff\"},\"headline\":\"Web Scraping vs API: How to Extract JSON Data With Python\",\"datePublished\":\"2026-08-31T14:43:04+00:00\",\"dateModified\":\"2026-08-31T14:43:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/\"},\"wordCount\":2266,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/web-scraping-vs-api-scraping.png\",\"keywords\":[\"Comparisons &amp; Reviews\",\"Guides &amp; Tutorials\",\"Web Scraping\"],\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"ru-RU\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/ru\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/\",\"name\":\"Web Scraping vs API: Extract JSON Data With Python\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/web-scraping-vs-api-scraping.png\",\"datePublished\":\"2026-08-31T14:43:04+00:00\",\"dateModified\":\"2026-08-31T14:43:05+00:00\",\"description\":\"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#breadcrumb\"},\"inLanguage\":\"ru-RU\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ru-RU\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#primaryimage\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/web-scraping-vs-api-scraping.png\",\"contentUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/web-scraping-vs-api-scraping.png\",\"width\":870,\"height\":490,\"caption\":\"Web Scraping vs API: Extract JSON Data With Python\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nodemaven.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Scraping vs API: How to Extract JSON Data With Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#website\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/\",\"name\":\"NodeMaven\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/nodemaven.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ru-RU\"},{\"@type\":[\"Organization\",\"Place\"],\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#organization\",\"name\":\"NodeMaven\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/\",\"logo\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#local-main-organization-logo\"},\"image\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#local-main-organization-logo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/people\\\/NodeMaven\\\/100095402507825\\\/\",\"https:\\\/\\\/t.me\\\/NodeMavenTG\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/nodemaven\\\/\"],\"telephone\":[],\"openingHoursSpecification\":[{\"@type\":\"OpeningHoursSpecification\",\"dayOfWeek\":[\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"],\"opens\":\"00:00\",\"closes\":\"23:59\"}],\"legalName\":\"NodeMaven FZ LLC\",\"email\":\"support@nodemaven.com\",\"description\":\"NodeMaven is a proxy infrastructure provider offering residential, mobile, and ISP proxies with IP quality filtering, precise geo-targeting, HTTPS and SOCKS5 support, and developer APIs.\",\"contactPoint\":[{\"@type\":\"ContactPoint\",\"contactType\":\"customer support\",\"email\":\"support@nodemaven.com\"},{\"@type\":\"ContactPoint\",\"contactType\":\"legal\",\"email\":\"legal.public@nodemaven.com\"}],\"award\":[\"People Love Us, awarded by Trustpilot (2025)\",\"Top Rated, awarded by Top Business Software (2025)\",\"Customers Love Us, awarded by Sourceforge (2025)\",\"Users Love Us, awarded by G2 (2025)\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#\\\/schema\\\/person\\\/f3bc93327b3582e735259d2a98f7a7ff\",\"name\":\"Anna\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ru-RU\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/anna-radziuk_avatar-96x96.jpg\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/anna-radziuk_avatar-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/anna-radziuk_avatar-96x96.jpg\",\"caption\":\"Anna\"},\"description\":\"Anna is a content manager at NodeMaven, and she specialises in turning complex technical topics into clear, practical guides backed by industry research, hands-on testing, and popular use cases.\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/ru\\\/author\\\/anna-radziuk\\\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"ru-RU\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/web-scraping-vs-api\\\/#local-main-organization-logo\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/cropped-Untitled-design-8-1.png\",\"contentUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/cropped-Untitled-design-8-1.png\",\"width\":512,\"height\":512,\"caption\":\"NodeMaven\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Web Scraping vs API: Extract JSON Data With Python","description":"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nodemaven.com\/ru\/blog\/web-scraping-vs-api\/","og_locale":"ru_RU","og_type":"article","og_title":"Web Scraping vs API: How to Extract JSON Data With Python","og_description":"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.","og_url":"https:\/\/nodemaven.com\/ru\/blog\/web-scraping-vs-api\/","og_site_name":"NodeMaven","article_publisher":"https:\/\/www.facebook.com\/people\/NodeMaven\/100095402507825\/","article_published_time":"2026-08-31T14:43:04+00:00","article_modified_time":"2026-08-31T14:43:05+00:00","og_image":[{"width":870,"height":490,"url":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-scraping.png","type":"image\/png"}],"author":"Anna","twitter_card":"summary_large_image","twitter_misc":{"\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u043e\u043c":"Anna","\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f":"11 \u043c\u0438\u043d\u0443\u0442"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#article","isPartOf":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/"},"author":{"name":"Anna","@id":"https:\/\/nodemaven.com\/#\/schema\/person\/f3bc93327b3582e735259d2a98f7a7ff"},"headline":"Web Scraping vs API: How to Extract JSON Data With Python","datePublished":"2026-08-31T14:43:04+00:00","dateModified":"2026-08-31T14:43:05+00:00","mainEntityOfPage":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/"},"wordCount":2266,"commentCount":0,"publisher":{"@id":"https:\/\/nodemaven.com\/#organization"},"image":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#primaryimage"},"thumbnailUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-scraping.png","keywords":["Comparisons &amp; Reviews","Guides &amp; Tutorials","Web Scraping"],"articleSection":["Uncategorized"],"inLanguage":"ru-RU","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/nodemaven.com\/ru\/#organization"}},{"@type":"WebPage","@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/","url":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/","name":"Web Scraping vs API: Extract JSON Data With Python","isPartOf":{"@id":"https:\/\/nodemaven.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#primaryimage"},"image":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#primaryimage"},"thumbnailUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-scraping.png","datePublished":"2026-08-31T14:43:04+00:00","dateModified":"2026-08-31T14:43:05+00:00","description":"Learn when to use web scraping vs API requests, how to find hidden JSON endpoints in Chrome DevTools, test them in Postman, and extract data with Python.","breadcrumb":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#breadcrumb"},"inLanguage":"ru-RU","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/"]}]},{"@type":"ImageObject","inLanguage":"ru-RU","@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#primaryimage","url":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-scraping.png","contentUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/08\/web-scraping-vs-api-scraping.png","width":870,"height":490,"caption":"Web Scraping vs API: Extract JSON Data With Python"},{"@type":"BreadcrumbList","@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nodemaven.com\/"},{"@type":"ListItem","position":2,"name":"Web Scraping vs API: How to Extract JSON Data With Python"}]},{"@type":"WebSite","@id":"https:\/\/nodemaven.com\/#website","url":"https:\/\/nodemaven.com\/","name":"NodeMaven","description":"","publisher":{"@id":"https:\/\/nodemaven.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nodemaven.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ru-RU"},{"@type":["Organization","Place"],"@id":"https:\/\/nodemaven.com\/#organization","name":"NodeMaven","url":"https:\/\/nodemaven.com\/","logo":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#local-main-organization-logo"},"image":{"@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#local-main-organization-logo"},"sameAs":["https:\/\/www.facebook.com\/people\/NodeMaven\/100095402507825\/","https:\/\/t.me\/NodeMavenTG","https:\/\/www.linkedin.com\/company\/nodemaven\/"],"telephone":[],"openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],"opens":"00:00","closes":"23:59"}],"legalName":"NodeMaven FZ LLC","email":"support@nodemaven.com","description":"NodeMaven \u2014 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043f\u0440\u043e\u043a\u0441\u0438-\u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u043d\u044b\u0435, \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0438 ISP-\u043f\u0440\u043e\u043a\u0441\u0438 \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 IP, \u0442\u043e\u0447\u043d\u044b\u043c \u0433\u0435\u043e-\u0442\u0430\u0440\u0433\u0435\u0442\u0438\u043d\u0433\u043e\u043c, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 HTTPS \u0438 SOCKS5, \u0430 \u0442\u0430\u043a\u0436\u0435 API \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.","contactPoint":[{"@type":"ContactPoint","contactType":"customer support","email":"support@nodemaven.com"},{"@type":"ContactPoint","contactType":"legal","email":"legal.public@nodemaven.com"}],"award":["People Love Us, awarded by Trustpilot (2025)","Top Rated, awarded by Top Business Software (2025)","Customers Love Us, awarded by Sourceforge (2025)","Users Love Us, awarded by G2 (2025)"]},{"@type":"Person","@id":"https:\/\/nodemaven.com\/#\/schema\/person\/f3bc93327b3582e735259d2a98f7a7ff","name":"\u0410\u043d\u043d\u0430","image":{"@type":"ImageObject","inLanguage":"ru-RU","@id":"https:\/\/nodemaven.com\/wp-content\/uploads\/2025\/05\/anna-radziuk_avatar-96x96.jpg","url":"https:\/\/nodemaven.com\/wp-content\/uploads\/2025\/05\/anna-radziuk_avatar-96x96.jpg","contentUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2025\/05\/anna-radziuk_avatar-96x96.jpg","caption":"Anna"},"description":"\u0410\u043d\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u0432 NodeMaven \u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0435\u043c\u044b \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044f \u0438\u0445 \u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0442\u0440\u0430\u0441\u043b\u0435\u0432\u044b\u0445 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439, \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f","url":"https:\/\/nodemaven.com\/ru\/author\/anna-radziuk\/"},{"@type":"ImageObject","inLanguage":"ru-RU","@id":"https:\/\/nodemaven.com\/blog\/web-scraping-vs-api\/#local-main-organization-logo","url":"https:\/\/nodemaven.com\/wp-content\/uploads\/2025\/03\/cropped-Untitled-design-8-1.png","contentUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2025\/03\/cropped-Untitled-design-8-1.png","width":512,"height":512,"caption":"NodeMaven"}]}},"_links":{"self":[{"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/posts\/40507","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/users\/68"}],"replies":[{"embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/comments?post=40507"}],"version-history":[{"count":3,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/posts\/40507\/revisions"}],"predecessor-version":[{"id":40515,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/posts\/40507\/revisions\/40515"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/media\/40513"}],"wp:attachment":[{"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/media?parent=40507"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/categories?post=40507"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/tags?post=40507"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}