{"id":40560,"date":"2026-09-03T13:08:49","date_gmt":"2026-09-03T13:08:49","guid":{"rendered":"https:\/\/nodemaven.com\/?p=40560"},"modified":"2026-09-03T13:13:57","modified_gmt":"2026-09-03T13:13:57","slug":"python-async-requests","status":"publish","type":"post","link":"https:\/\/nodemaven.com\/ru\/blog\/python-async-requests\/","title":{"rendered":"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits"},"content":{"rendered":"<p>Python web scrapers often become slow for a simple reason: a synchronous script waits for each response before it starts the next request. Async requests reduce that idle time by keeping several network requests in progress at once.<\/p>\n\n\n\n<p>Speed has a limit. Raising concurrency too quickly can overload the target, trigger <strong>429 rate limits<\/strong>, create connection errors, or return incomplete pages. In the <a href=\"https:\/\/blog.apify.com\/web-scraping-proxies\/\">Apify and The Web Scraping Club State of Web Scraping Report 2026<\/a>, <strong>65.8% of surveyed scraping professionals said they used more proxies in 2025 than the previous year<\/strong>. That reflects a common production problem: scaling a scraper also means managing the network route each request uses. For public 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> can avoid concentrating every request on one IP. For price checks, local listings, and other workflows that need one consistent region during a run, sticky sessions keep the connection more stable.<\/p>\n\n\n\n<p>This guide follows <strong>one step-by-step <\/strong><code><strong>\u0410\u0419\u041e HTTP<\/strong><\/code><strong> tutorial<\/strong>: send one request, run several requests concurrently, cap concurrency, add retries, and save results. Requests, <code>asyncio.to_thread()<\/code>, HTTPX, and <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> appear later as clearly labelled alternatives for different workflows.<\/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 Async Requests With Less Failed Requests<\/div>\n            \n                            <div class=\"section-alert__description\"><p data-pm-slice=\"1 1 []\">\u041a\u043e\u0433\u0434\u0430 <code>429<\/code> errors, unstable routes, or one-IP limits appear, add clean residential proxies instead of pushing concurrency higher. Test NodeMaven with <strong>750 MB of residential and mobile traffic for $3.50<\/strong> and keep every request on a more reliable route<\/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-python-async-requests-quick-answer\">Python Async Requests: Quick Answer<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Follow the <\/strong><code><strong>\u0410\u0419\u041e HTTP<\/strong><\/code><strong> tutorial below<\/strong> when you are building a new async scraper.<\/li>\n\n\n\n<li>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c <strong>Python Requests<\/strong> for a short local script or a small number of URLs.<\/li>\n\n\n\n<li>\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 <code><strong>asyncio.to_thread()<\/strong><\/code> when you already have a working Requests scraper and want concurrent runs without rewriting it immediately.<\/li>\n\n\n\n<li>\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 <strong>HTTPX<\/strong> when you prefer a Requests-like API with native async support.<\/li>\n\n\n\n<li>Move to browser automation when the target requires JavaScript, scrolling, clicks, forms, screenshots, or persistent browser state.<\/li>\n<\/ul>\n\n\n\n<p>Start with a small concurrency limit and validate the returned pages before increasing it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-normal-python-requests-get-slow\">Why Normal Python Requests Get Slow<\/h2>\n\n\n\n<p>A normal Requests script is synchronous. It sends a request, waits for the response, and only then starts the next URL.<\/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%0Aurls%20%3D%20%5B%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F1%22%2C%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F2%22%2C%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F3%22%2C%0A%5D%0A%0Afor%20url%20in%20urls%3A%0A%20%20%20%20response%20%3D%20requests.get%28url%2C%20timeout%3D30%29%0A%20%20%20%20print%28response.status_code%2C%20url%29\"><\/code><\/pre><\/figure>\n\n\n<p>This example is <strong>not part of the async tutorial<\/strong>. It shows the traditional Requests approach, where URLs are downloaded one by one.<\/p>\n\n\n\n<p><code>requests.get()<\/code> sends one request. The <code>\u043d\u0430<\/code> loop does not start the next URL until the previous response arrives. The <code>\u0410\u0419\u041e HTTP<\/code> tutorial below changes that behavior by keeping several requests in progress at once.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-choose-the-right-python-approach\">Choose the Right Python Approach<\/h2>\n\n\n\n<p><strong>\u0417\u0430\u043f\u0440\u043e\u0441\u044b<\/strong> fits a one-off check, a small local script, or a short list of URLs.<\/p>\n\n\n\n<p><code><strong>asyncio.to_thread()<\/strong><\/code> runs existing blocking Requests code in threads. It gives an older synchronous scraper a path to concurrency without a full rewrite. Python documents it primarily for I\/O-bound blocking functions, such as HTTP requests.<\/p>\n\n\n\n<p><strong>\u0410\u0419\u041e HTTP<\/strong> is the main library in this tutorial. It is built around <code>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439<\/code>, handles many in-flight HTTP requests, and uses a reusable <code>ClientSession<\/code> with connection pooling. The <a href=\"https:\/\/docs.aiohttp.org\/en\/stable\/client_quickstart.html\">aiohttp Client Quickstart<\/a> advises against creating a new session for every request.<\/p>\n\n\n\n<p><strong>HTTPX<\/strong> provides another async route with an API that resembles Requests. Its <a href=\"https:\/\/www.python-httpx.org\/async\/\">async documentation<\/a> \u0438 <a href=\"https:\/\/www.python-httpx.org\/advanced\/resource-limits\/\">resource limit settings<\/a> cover reusable clients, connection limits, and keep-alive connections.<\/p>\n\n\n\n<p><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> is for browser-based collection. It runs a real cloud browser for pages that need <strong>JavaScript rendering, scrolling, clicks, forms, screenshots, or saved browser sessions<\/strong>. A NodeMaven account can run up to <strong>50 active browser sessions<\/strong> at the same time by default.<\/p>\n\n\n\n<p>For a wider introduction to Requests, parsing, selectors, and browser automation, read NodeMaven\u2019s <a href=\"https:\/\/nodemaven.com\/ru\/blog\/python-web-scraping\/\">\u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u043e \u0432\u0435\u0431-\u0441\u043a\u0440\u0430\u043f\u0438\u043d\u0433\u0443 \u043d\u0430 Python<\/a>.<\/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\">Run Browser Workflows Without Browser Overhead<\/div>\n            \n                            <div class=\"section-alert__description\"><p data-pm-slice=\"1 1 []\">When async requests cannot render the page, start a NodeMaven proxy trial and run up to <strong>50 cloud browser sessions<\/strong> with Scraping Browser. <strong>The browser, profiles, and CAPTCHA solver have no separate browser fee<\/strong>: start with <strong>750 MB of residential and mobile traffic for $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<h1 class=\"wp-block-heading\" id=\"h-step-by-step-build-an-async-web-scraper-with-aiohttp\">Step-by-Step: Build an Async Web Scraper With aiohttp<\/h1>\n\n\n\n<p>This tutorial uses <a href=\"https:\/\/books.toscrape.com\/\">Books to Scrape<\/a>, a website created for scraping practice. The example first fetches one page, then several pages, then adds concurrency limits and retries.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-1-create-a-virtual-environment-and-install-aiohttp\">Step 1: Create a Virtual Environment and Install aiohttp<\/h2>\n\n\n\n<p>Open Terminal in the folder where you want to save the project.<\/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%0Asource%20scraping-env%2Fbin%2Factivate%0Apython3%20-m%20pip%20install%20aiohttp\"><\/code><\/pre><\/figure>\n\n\n<p>Create a file named <code>async_scraper.py<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-2-send-one-async-request\">Step 2: Send One Async Request<\/h2>\n\n\n\n<p>Start with one page. This confirms that your environment, connection, and code work before concurrency enters the picture.<\/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%20asyncio%0Aimport%20aiohttp%0A%0Aasync%20def%20fetch_page%28session%2C%20url%29%3A%0A%20%20%20%20async%20with%20session.get%28url%29%20as%20response%3A%0A%20%20%20%20%20%20%20%20response.raise_for_status%28%29%0A%20%20%20%20%20%20%20%20return%20await%20response.text%28%29%0A%0Aasync%20def%20main%28%29%3A%0A%20%20%20%20url%20%3D%20%22https%3A%2F%2Fbooks.toscrape.com%2F%22%0A%0A%20%20%20%20async%20with%20aiohttp.ClientSession%28%29%20as%20session%3A%0A%20%20%20%20%20%20%20%20html%20%3D%20await%20fetch_page%28session%2C%20url%29%0A%0A%20%20%20%20print%28html%5B%3A300%5D%29%0A%0Aasyncio.run%28main%28%29%29\"><\/code><\/pre><\/figure>\n\n\n<p>Run the file:<\/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%20async_scraper.py\"><\/code><\/pre><\/figure>\n\n\n<p>The terminal should print the opening part of the page HTML.<\/p>\n\n\n\n<p><code>ClientSession()<\/code> keeps a connection pool. Reusing the same session lets the scraper reuse connections instead of opening a new one for every page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-3-fetch-several-pages-with-asyncio-gather\">Step 3: Fetch Several Pages With asyncio.gather()<\/h2>\n\n\n\n<p>Replace the code with a version that downloads several category pages concurrently.<\/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%20asyncio%0Aimport%20aiohttp%0A%0Aurls%20%3D%20%5B%0A%20%20%20%20%22https%3A%2F%2Fbooks.toscrape.com%2Fcatalogue%2Fpage-1.html%22%2C%0A%20%20%20%20%22https%3A%2F%2Fbooks.toscrape.com%2Fcatalogue%2Fpage-2.html%22%2C%0A%20%20%20%20%22https%3A%2F%2Fbooks.toscrape.com%2Fcatalogue%2Fpage-3.html%22%2C%0A%5D%0A%0Aasync%20def%20fetch_page%28session%2C%20url%29%3A%0A%20%20%20%20async%20with%20session.get%28url%29%20as%20response%3A%0A%20%20%20%20%20%20%20%20response.raise_for_status%28%29%0A%20%20%20%20%20%20%20%20html%20%3D%20await%20response.text%28%29%0A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20url%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22status%22%3A%20response.status%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22html_length%22%3A%20len%28html%29%2C%0A%20%20%20%20%20%20%20%20%7D%0A%0Aasync%20def%20main%28%29%3A%0A%20%20%20%20timeout%20%3D%20aiohttp.ClientTimeout%28total%3D30%29%0A%0A%20%20%20%20async%20with%20aiohttp.ClientSession%28timeout%3Dtimeout%29%20as%20session%3A%0A%20%20%20%20%20%20%20%20results%20%3D%20await%20asyncio.gather%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%2A%28fetch_page%28session%2C%20url%29%20for%20url%20in%20urls%29%0A%20%20%20%20%20%20%20%20%29%0A%0A%20%20%20%20for%20result%20in%20results%3A%0A%20%20%20%20%20%20%20%20print%28result%29%0A%0Aasyncio.run%28main%28%29%29\"><\/code><\/pre><\/figure>\n\n\n<p><code>asyncio.gather()<\/code> starts the request tasks together and waits until they all finish. This is fine for three URLs, but a large list needs a concurrency limit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-4-add-a-concurrency-limit\">Step 4: Add a Concurrency Limit<\/h2>\n\n\n\n<p>A semaphore limits how many requests are active at once. The scraper can still process a large URL list, but only a defined number of connections remain open concurrently.<\/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%20asyncio%0Aimport%20aiohttp%0A%0Aurls%20%3D%20%5B%0A%20%20%20%20f%22https%3A%2F%2Fbooks.toscrape.com%2Fcatalogue%2Fpage-%7Bpage%7D.html%22%0A%20%20%20%20for%20page%20in%20range%281%2C%2011%29%0A%5D%0A%0Aconcurrency%20%3D%205%0A%0Aasync%20def%20fetch_page%28session%2C%20semaphore%2C%20url%29%3A%0A%20%20%20%20async%20with%20semaphore%3A%0A%20%20%20%20%20%20%20%20async%20with%20session.get%28url%29%20as%20response%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20response.raise_for_status%28%29%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20%3D%20await%20response.text%28%29%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20url%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22status%22%3A%20response.status%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22html_length%22%3A%20len%28html%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0Aasync%20def%20main%28%29%3A%0A%20%20%20%20timeout%20%3D%20aiohttp.ClientTimeout%28total%3D30%29%0A%20%20%20%20semaphore%20%3D%20asyncio.Semaphore%28concurrency%29%0A%0A%20%20%20%20async%20with%20aiohttp.ClientSession%28timeout%3Dtimeout%29%20as%20session%3A%0A%20%20%20%20%20%20%20%20tasks%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20fetch_page%28session%2C%20semaphore%2C%20url%29%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20url%20in%20urls%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20results%20%3D%20await%20asyncio.gather%28%2Atasks%29%0A%0A%20%20%20%20for%20result%20in%20results%3A%0A%20%20%20%20%20%20%20%20print%28result%29%0A%0Aasyncio.run%28main%28%29%29\"><\/code><\/pre><\/figure>\n\n\n<p>Here, the scraper has ten URLs but opens only <strong>five requests at a time<\/strong>. Start with 3, 5, or 10. Increase the number only after checking response quality and error rates.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-step-5-add-retries-and-save-results-to-csv\">Step 5: Add Retries and Save Results to CSV<\/h2>\n\n\n\n<p>The final version adds timeouts, exponential backoff for temporary failures, and a CSV output 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%20asyncio%0Aimport%20aiohttp%0Aimport%20csv%0A%0Aurls%20%3D%20%5B%0A%20%20%20%20f%22https%3A%2F%2Fbooks.toscrape.com%2Fcatalogue%2Fpage-%7Bpage%7D.html%22%0A%20%20%20%20for%20page%20in%20range%281%2C%2011%29%0A%5D%0A%0Aconcurrency%20%3D%205%0Amax_retries%20%3D%203%0A%0Aclass%20RetryableResponseError%28Exception%29%3A%0A%20%20%20%20pass%0A%0Aasync%20def%20fetch_page%28session%2C%20semaphore%2C%20url%29%3A%0A%20%20%20%20for%20attempt%20in%20range%281%2C%20max_retries%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20async%20with%20semaphore%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20async%20with%20session.get%28url%29%20as%20response%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20response.status%20%3D%3D%20429%20or%20response.status%20%3E%3D%20500%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20RetryableResponseError%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22Temporary%20response%3A%20%7Bresponse.status%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%29%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20response.raise_for_status%28%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20html%20%3D%20await%20response.text%28%29%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20url%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22status%22%3A%20response.status%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22html_length%22%3A%20len%28html%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20except%20RetryableResponseError%20as%20error%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20attempt%20%3D%3D%20max_retries%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20url%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22status%22%3A%20%22failed%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22html_length%22%3A%20str%28error%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20except%20%28aiohttp.ClientError%2C%20asyncio.TimeoutError%29%20as%20error%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20attempt%20%3D%3D%20max_retries%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20url%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22status%22%3A%20%22failed%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22html_length%22%3A%20str%28error%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20await%20asyncio.sleep%282%20%2A%2A%20attempt%29%0A%0Aasync%20def%20main%28%29%3A%0A%20%20%20%20timeout%20%3D%20aiohttp.ClientTimeout%28%0A%20%20%20%20%20%20%20%20total%3D30%2C%0A%20%20%20%20%20%20%20%20connect%3D10%2C%0A%20%20%20%20%20%20%20%20sock_read%3D20%2C%0A%20%20%20%20%29%0A%20%20%20%20semaphore%20%3D%20asyncio.Semaphore%28concurrency%29%0A%0A%20%20%20%20async%20with%20aiohttp.ClientSession%28timeout%3Dtimeout%29%20as%20session%3A%0A%20%20%20%20%20%20%20%20tasks%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20fetch_page%28session%2C%20semaphore%2C%20url%29%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20url%20in%20urls%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20results%20%3D%20await%20asyncio.gather%28%2Atasks%29%0A%0A%20%20%20%20with%20open%28%22scrape_results.csv%22%2C%20%22w%22%2C%20newline%3D%22%22%2C%20encoding%3D%22utf-8%22%29%20as%20file%3A%0A%20%20%20%20%20%20%20%20writer%20%3D%20csv.DictWriter%28%0A%20%20%20%20%20%20%20%20%20%20%20%20file%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fieldnames%3D%5B%22url%22%2C%20%22status%22%2C%20%22html_length%22%5D%2C%0A%20%20%20%20%20%20%20%20%29%0A%20%20%20%20%20%20%20%20writer.writeheader%28%29%0A%20%20%20%20%20%20%20%20writer.writerows%28results%29%0A%0A%20%20%20%20print%28f%22Saved%20%7Blen%28results%29%7D%20rows%20to%20scrape_results.csv%22%29%0A%0Aasyncio.run%28main%28%29%29\"><\/code><\/pre><\/figure>\n\n\n<p>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%20async_scraper.py\"><\/code><\/pre><\/figure>\n\n\n<p>The script creates <code>scrape_results.csv<\/code> in the same folder. In a production scraper, replace <code>html_length<\/code> with the fields you extract from each response, such as product title, price, stock status, listing URL, or JSON data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-test-concurrency-before-scaling\">Test Concurrency Before Scaling<\/h2>\n\n\n\n<p>Do not treat the highest possible concurrency number as the correct setting. A reliable scraper tracks <strong>successful, complete responses<\/strong>, not just completed requests.<\/p>\n\n\n\n<p>Test a small URL sample at several limits:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c<\/th><th>What to Record<\/th><\/tr><tr><td>1<\/td><td>Baseline response time and response quality<\/td><\/tr><tr><td>5<\/td><td>Success rate, <code>429<\/code> errors, and timeouts<\/td><\/tr><tr><td>10<\/td><td>Whether retries or blocks rise<\/td><\/tr><tr><td>20+<\/td><td>Whether the target still returns complete, valid pages<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Record <strong>total run time, success rate, retries, <\/strong><code><strong>403<\/strong><\/code><strong> \u0438 <\/strong><code><strong>429<\/strong><\/code><strong> responses, timeouts, and incomplete pages<\/strong>. Stop increasing concurrency when error rates rise or the returned content changes.<\/p>\n\n\n\n<p>If the workflow needs more coverage after you have found a safe request rate, do not simply push the semaphore higher. For permitted public-data collection, <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 distribute independent requests across clean IPs. For region-specific checks or multi-page flows with cookies and pagination, use <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">\u0437\u0430\u0442\u044f\u0436\u043d\u044b\u0435 \u0436\u0438\u043b\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438<\/a> so the scraper keeps one consistent location during the job.<\/p>\n\n\n\n<p>A GitHub discussion about <a href=\"https:\/\/github.com\/encode\/httpx\/discussions\/3084\">high-volume HTTPX requests<\/a> shows how thousands of concurrent requests can produce connection problems when client limits and connection pooling are not configured carefully.<\/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 Async Requests With Less Failed Requests<\/div>\n            \n                            <div class=\"section-alert__description\"><p data-pm-slice=\"1 1 []\">\u041a\u043e\u0433\u0434\u0430 <code>429<\/code> errors, unstable routes, or one-IP limits appear, add clean residential proxies instead of pushing concurrency higher. Test NodeMaven with <strong>750 MB of residential and mobile traffic for $3.50<\/strong> and keep every request on a more reliable route<\/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-an-alternative-for-existing-requests-scripts-asyncio-to-thread\">An Alternative for Existing Requests Scripts: asyncio.to_thread()<\/h2>\n\n\n\n<p>You do not need to rewrite a working Requests scraper on day one. <code>asyncio.to_thread()<\/code> can run blocking Requests functions concurrently.<\/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%20asyncio%0Aimport%20requests%0A%0Aurls%20%3D%20%5B%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F1%22%2C%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F2%22%2C%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F3%22%2C%0A%5D%0A%0Adef%20fetch%28url%29%3A%0A%20%20%20%20response%20%3D%20requests.get%28url%2C%20timeout%3D30%29%0A%20%20%20%20response.raise_for_status%28%29%0A%20%20%20%20return%20response.text%0A%0Aasync%20def%20main%28%29%3A%0A%20%20%20%20pages%20%3D%20await%20asyncio.gather%28%0A%20%20%20%20%20%20%20%20%2A%28asyncio.to_thread%28fetch%2C%20url%29%20for%20url%20in%20urls%29%0A%20%20%20%20%29%0A%0A%20%20%20%20print%28f%22Downloaded%20%7Blen%28pages%29%7D%20pages%22%29%0A%0Aasyncio.run%28main%28%29%29\"><\/code><\/pre><\/figure>\n\n\n<p>This is a <strong>transition approach<\/strong>, not a replacement for an async HTTP client at large scale. A scraper that already relies on Requests can gain concurrency first, then move to <code>\u0410\u0419\u041e HTTP<\/code> or HTTPX when it needs tighter control over connections and request behavior.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-httpx-asyncclient-a-requests-like-alternative\">HTTPX AsyncClient: A Requests-Like Alternative<\/h2>\n\n\n\n<p>HTTPX resembles Requests but supports native async requests. It is a natural choice when your team already knows the Requests API.<\/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%20asyncio%0Aimport%20httpx%0A%0Aurls%20%3D%20%5B%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F1%22%2C%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F2%22%2C%0A%20%20%20%20%22https%3A%2F%2Fexample.com%2Fproduct%2F3%22%2C%0A%5D%0A%0Aasync%20def%20fetch%28client%2C%20url%29%3A%0A%20%20%20%20response%20%3D%20await%20client.get%28url%29%0A%20%20%20%20response.raise_for_status%28%29%0A%20%20%20%20return%20response.text%0A%0Aasync%20def%20main%28%29%3A%0A%20%20%20%20limits%20%3D%20httpx.Limits%28%0A%20%20%20%20%20%20%20%20max_connections%3D10%2C%0A%20%20%20%20%20%20%20%20max_keepalive_connections%3D5%2C%0A%20%20%20%20%29%0A%20%20%20%20timeout%20%3D%20httpx.Timeout%2830.0%2C%20connect%3D10.0%29%0A%0A%20%20%20%20async%20with%20httpx.AsyncClient%28%0A%20%20%20%20%20%20%20%20limits%3Dlimits%2C%0A%20%20%20%20%20%20%20%20timeout%3Dtimeout%2C%0A%20%20%20%20%29%20as%20client%3A%0A%20%20%20%20%20%20%20%20pages%20%3D%20await%20asyncio.gather%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%2A%28fetch%28client%2C%20url%29%20for%20url%20in%20urls%29%0A%20%20%20%20%20%20%20%20%29%0A%0A%20%20%20%20print%28f%22Downloaded%20%7Blen%28pages%29%7D%20pages%22%29%0A%0Aasyncio.run%28main%28%29%29\"><\/code><\/pre><\/figure>\n\n\n<p>Keep one shared <code>AsyncClient<\/code> for the batch. Creating a new client inside every request discards the benefits of connection pooling. In one <a href=\"https:\/\/github.com\/encode\/httpx\/discussions\/3457\">HTTPX community benchmark discussion<\/a>, client reuse produced performance close to aiohttp for that contributor\u2019s test. Treat it as a developer example, not a universal benchmark.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-add-proxies-to-async-python-requests\">Add Proxies to Async Python Requests<\/h2>\n\n\n\n<p>At a small scale, a normal connection may be enough. Repeated requests from a cloud server or a single IP can run into <strong>rate limits, location mismatches, or IP reputation checks<\/strong>.<\/p>\n\n\n\n<p>For independent public 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> can distribute requests across clean consumer IPs. A <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> with a sticky session fits a job that needs a consistent location, cookies, or region during one collection run.<\/p>\n\n\n\n<p><a href=\"https:\/\/nodemaven.com\/ru\/proxies\/isp-proxies\/\">ISP \u043f\u0440\u043e\u043a\u0441\u0438<\/a> suit recurring monitoring where the same stable IP should be retained over time. For instance, a price tracker that checks a fixed product set every 15 minutes should not randomly change its network identity during an active workflow.<\/p>\n\n\n\n<p>HTTPX can send requests through a proxy:<\/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%20httpx%0A%0Aproxy_url%20%3D%20%22http%3A%2F%2FUSERNAME%3APASSWORD%40HOST%3APORT%22%0A%0Awith%20httpx.Client%28proxy%3Dproxy_url%2C%20timeout%3D30%29%20as%20client%3A%0A%20%20%20%20response%20%3D%20client.get%28%22https%3A%2F%2Fexample.com%2F%22%29%0A%20%20%20%20print%28response.status_code%29\"><\/code><\/pre><\/figure>\n\n\n<p>For async code, pass the same <code>\u043f\u0440\u043e\u043a\u0441\u0438<\/code> value to <code>httpx.AsyncClient<\/code>. NodeMaven\u2019s <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 Python routing patterns, while the <a href=\"https:\/\/nodemaven.com\/ru\/blog\/proxy-authentication-guide\/\">proxy authentication guide<\/a> explains credentials and authentication methods.<\/p>\n\n\n\n<p>Only collect data where access is permitted. Proxies do not grant permission to access private data, bypass paywalls, or ignore a website\u2019s rules.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-when-async-requests-are-the-wrong-tool\">When Async Requests Are the Wrong Tool<\/h2>\n\n\n\n<p>Async HTTP requests work when the target returns the data in HTML or JSON. They cannot interact with a page the way a browser can.<\/p>\n\n\n\n<p>Move to browser automation when the workflow needs:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u041a\u043e\u043d\u0442\u0435\u043d\u0442, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0439 JavaScript<\/strong><\/li>\n\n\n\n<li><strong>Scrolling, clicks, or form submissions<\/strong><\/li>\n\n\n\n<li><strong>Screenshots or visual checks<\/strong><\/li>\n\n\n\n<li><strong>Login state and saved cookies<\/strong><\/li>\n\n\n\n<li><strong>A browser profile that persists between runs<\/strong><\/li>\n<\/ul>\n\n\n\n<p><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> provides a cloud browser with NodeMaven proxies, managed browser settings, persistent profiles, CAPTCHA support, Live Browser debugging, and session recordings. It has <strong>\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u044b \u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/strong> for eligible NodeMaven customers. You pay for the rotating proxy traffic transferred during sessions.<\/p>\n\n\n\n<p>For code-first browser workflows, read the <a href=\"https:\/\/nodemaven.com\/ru\/blog\/playwright-scraping\/\">Playwright scraping guide<\/a>. For pages where rendering and visual interaction are not required, async HTTP requests are lighter to run.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-common-python-async-scraping-mistakes\">Common Python Async Scraping Mistakes<\/h2>\n\n\n\n<p><strong>Creating a new session per request:<\/strong> Create one <code>aiohttp.ClientSession<\/code> \u0438\u043b\u0438 <code>httpx.AsyncClient<\/code> for the batch. This preserves connection pooling and avoids repeatedly opening new connections.<\/p>\n\n\n\n<p><strong>Launching every task at once:<\/strong> <code>asyncio.gather()<\/code> has no built-in rate limit. Add a semaphore before running a large URL list. If a permitted workflow still needs more independent public requests after you have slowed it down, <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 clean consumer IPs instead of concentrating them on one route.<\/p>\n\n\n\n<p><strong>Retrying every error:<\/strong> Retry timeouts, connection problems, <code>429<\/code> responses, and temporary <code>5xx<\/code> errors with backoff. Do not repeatedly retry <code>400<\/code>, <code>401<\/code>, <code>403<\/code>, \u0438\u043b\u0438 <code>404<\/code> responses without changing the request. A <code>403<\/code> can point to permissions, a blocked route, or anti-bot controls. NodeMaven\u2019s <a href=\"https:\/\/nodemaven.com\/ru\/blog\/how-to-bypass-403-forbidden-error\/\">403 Forbidden guide<\/a> explains how to diagnose those cases.<\/p>\n\n\n\n<p><strong>Ignoring the response body:<\/strong> A <code>200 OK<\/code> response can still contain a CAPTCHA page, login page, access denied message, empty result, or <strong>\u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442<\/strong>. Validate an expected title, JSON field, or page marker before saving the result. Clean <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> can also reduce CAPTCHA and verification prompts on permitted public-data workflows because the traffic comes from consumer-network IP ranges rather than obvious hosting infrastructure. When a dataset needs a specific location, residential proxies can provide country, region, city, and ZIP-level routing.<\/p>\n\n\n\n<p><strong>Changing proxy location during a stateful workflow:<\/strong> Rotation suits independent requests. When the scraper relies on cookies, locations, pagination, or account state, keep one stable session. A sticky <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> works well for a defined collection run, while an <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/isp-proxies\/\">ISP \u043f\u0440\u043e\u043a\u0441\u0438<\/a> fits recurring monitoring from one static IP.<\/p>\n\n\n\n<p><strong>Treating browser problems as HTTP problems:<\/strong> If the target needs JavaScript, scrolling, clicks, or form submissions, increasing async concurrency will not reveal the missing content. <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> runs real cloud browser sessions with managed proxies, persistent profiles, CAPTCHA support, and Live Browser debugging, so you can inspect the rendered workflow rather than guessing from an HTTP response.<\/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 Async Requests With Less Failed Requests<\/div>\n            \n                            <div class=\"section-alert__description\"><p data-pm-slice=\"1 1 []\">\u041a\u043e\u0433\u0434\u0430 <code>429<\/code> errors, unstable routes, or one-IP limits appear, add clean residential proxies instead of pushing concurrency higher. Test NodeMaven with <strong>750 MB of residential and mobile traffic for $3.50<\/strong> and keep every request on a more reliable route<\/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\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n\n\n\n<p>Build an async scraper in layers. Start with <strong>one async request<\/strong>, then add concurrent tasks, a semaphore, timeouts, retries, and response validation.<\/p>\n\n\n\n<p>The key check is whether the returned pages are <strong>complete and correct<\/strong>. A fast scraper that collects block pages, wrong regional results, or missing records only creates more cleanup work.<\/p>\n\n\n\n<p>For HTML and JSON endpoints, <code>\u0410\u0419\u041e HTTP<\/code> or HTTPX can run high-volume workloads efficiently. When error rates rise after you have set a safe concurrency limit, <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 distribute independent public requests across clean IPs. Use <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">\u043b\u0438\u043f\u043a\u0438\u0435 \u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/isp-proxies\/\">ISP \u043f\u0440\u043e\u043a\u0441\u0438<\/a> when cookies, location, pagination, or recurring monitoring require a stable session.<\/p>\n\n\n\n<p>When the target needs JavaScript, persistent browser state, or interactive page behavior, move the workflow to <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>. It provides managed cloud browsers, proxy routing, CAPTCHA support, persistent profiles, and Live Browser debugging, with <strong>\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u044b \u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/strong> beyond the proxy traffic transferred during each session.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-faq\">FAQ<\/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 are Python async requests?<\/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>Python async requests are HTTP requests run with asynchronous code. While one request waits for a server response, the event loop can start or continue another request.<\/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 aiohttp better than Requests for web 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 id=\"block-e57df36f-d899-4bdc-88ac-d75c010785ba\" class=\"block-editor-rich-text__editable block-editor-block-list__block wp-block is-selected wp-block-paragraph rich-text\" role=\"document\" aria-label=\"\u0411\u043b\u043e\u043a: \u041f\u0430\u0440\u0430\u0433\u0440\u0430\u0444\" data-block=\"e57df36f-d899-4bdc-88ac-d75c010785ba\" data-type=\"core\/paragraph\" data-title=\"Paragraph\" data-empty=\"false\" data-wp-block-attribute-key=\"content\"><code>\u0410\u0419\u041e HTTP<\/code> handles many concurrent HTTP requests in one async event loop. Requests is simpler for small synchronous scripts. The right choice depends on request volume, target behavior, and how much connection control the scraper needs.<\/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 HTTPX better than aiohttp?<\/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>HTTPX has a Requests-like API, native async support, HTTP\/2 support, and configurable connection limits. aiohttp offers mature asyncio-focused client features and direct control over sessions and connections. Test both with your own target and response-validation rules.<\/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 avoid 429 errors with async 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>Begin with low concurrency, add a semaphore, respect <code>Retry-After<\/code> headers where available, retry with backoff, and validate responses. When repeated public requests are limited by one IP, route permitted workflows through <a href=\"https:\/\/nodemaven.com\/ru\/proxies\/residential-proxies\/\">\u0447\u0438\u0441\u0442\u044b\u0435 \u0436\u0438\u043b\u044b\u0435 \u043f\u0440\u043e\u043a\u0441\u0438<\/a> rather than sending every request through a single route.<\/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 Python async requests?<\/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>Not for a small test. Proxies are needed when the scraper needs regional responses, repeated public requests, a stable long-running identity, or a more reliable route from cloud infrastructure.<\/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 JavaScript pages with aiohttp?<\/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 id=\"block-d126b2e9-c0c3-4001-b6c6-60e4aa16f102\" class=\"block-editor-rich-text__editable block-editor-block-list__block wp-block is-selected wp-block-paragraph rich-text\" role=\"document\" aria-label=\"\u0411\u043b\u043e\u043a: \u041f\u0430\u0440\u0430\u0433\u0440\u0430\u0444\" data-block=\"d126b2e9-c0c3-4001-b6c6-60e4aa16f102\" data-type=\"core\/paragraph\" data-title=\"Paragraph\" data-empty=\"false\" data-wp-block-attribute-key=\"content\">\u041d\u0435\u0442. <code>\u0410\u0419\u041e HTTP<\/code> downloads the server response but does not run page JavaScript. Use Playwright, Selenium, or <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> when the content appears only after rendering or interaction.<\/p>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                                    <\/div>\n                    <\/div>\n    <\/div>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-\"><\/h3>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation","protected":false},"author":68,"featured_media":40562,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[213,205],"class_list":["post-40560","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","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>Python Async Requests: Faster Web Scraping With aiohttp<\/title>\n<meta name=\"description\" content=\"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation.\" \/>\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\/python-async-requests\/\" \/>\n<meta property=\"og:locale\" content=\"ru_RU\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits\" \/>\n<meta property=\"og:description\" content=\"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nodemaven.com\/ru\/blog\/python-async-requests\/\" \/>\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-09-03T13:08:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-03T13:13:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/09\/python-async.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=\"9 \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\\\/python-async-requests\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/\"},\"author\":{\"name\":\"Anna\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#\\\/schema\\\/person\\\/f3bc93327b3582e735259d2a98f7a7ff\"},\"headline\":\"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits\",\"datePublished\":\"2026-09-03T13:08:49+00:00\",\"dateModified\":\"2026-09-03T13:13:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/\"},\"wordCount\":1904,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/python-async.png\",\"keywords\":[\"Guides &amp; Tutorials\",\"Web Scraping\"],\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"ru-RU\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/ru\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/\",\"name\":\"Python Async Requests: Faster Web Scraping With aiohttp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/python-async.png\",\"datePublished\":\"2026-09-03T13:08:49+00:00\",\"dateModified\":\"2026-09-03T13:13:57+00:00\",\"description\":\"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#breadcrumb\"},\"inLanguage\":\"ru-RU\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ru-RU\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#primaryimage\",\"url\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/python-async.png\",\"contentUrl\":\"https:\\\/\\\/nodemaven.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/python-async.png\",\"width\":870,\"height\":490,\"caption\":\"Python Async | Make web scraping Faster | NodeMaven\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nodemaven.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits\"}]},{\"@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\\\/python-async-requests\\\/#local-main-organization-logo\"},\"image\":{\"@id\":\"https:\\\/\\\/nodemaven.com\\\/blog\\\/python-async-requests\\\/#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\\\/python-async-requests\\\/#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":"Python Async Requests: Faster Web Scraping With aiohttp","description":"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation.","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\/python-async-requests\/","og_locale":"ru_RU","og_type":"article","og_title":"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits","og_description":"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation.","og_url":"https:\/\/nodemaven.com\/ru\/blog\/python-async-requests\/","og_site_name":"NodeMaven","article_publisher":"https:\/\/www.facebook.com\/people\/NodeMaven\/100095402507825\/","article_published_time":"2026-09-03T13:08:49+00:00","article_modified_time":"2026-09-03T13:13:57+00:00","og_image":[{"width":870,"height":490,"url":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/09\/python-async.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":"9 \u043c\u0438\u043d\u0443\u0442"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#article","isPartOf":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/"},"author":{"name":"Anna","@id":"https:\/\/nodemaven.com\/#\/schema\/person\/f3bc93327b3582e735259d2a98f7a7ff"},"headline":"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits","datePublished":"2026-09-03T13:08:49+00:00","dateModified":"2026-09-03T13:13:57+00:00","mainEntityOfPage":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/"},"wordCount":1904,"commentCount":0,"publisher":{"@id":"https:\/\/nodemaven.com\/#organization"},"image":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#primaryimage"},"thumbnailUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/09\/python-async.png","keywords":["Guides &amp; Tutorials","Web Scraping"],"articleSection":["Uncategorized"],"inLanguage":"ru-RU","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nodemaven.com\/blog\/python-async-requests\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/nodemaven.com\/ru\/#organization"}},{"@type":"WebPage","@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/","url":"https:\/\/nodemaven.com\/blog\/python-async-requests\/","name":"Python Async Requests: Faster Web Scraping With aiohttp","isPartOf":{"@id":"https:\/\/nodemaven.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#primaryimage"},"image":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#primaryimage"},"thumbnailUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/09\/python-async.png","datePublished":"2026-09-03T13:08:49+00:00","dateModified":"2026-09-03T13:13:57+00:00","description":"Learn Python async requests with aiohttp. Build a faster web scraper with concurrency limits, retries, proxy routing, and response validation.","breadcrumb":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#breadcrumb"},"inLanguage":"ru-RU","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nodemaven.com\/blog\/python-async-requests\/"]}]},{"@type":"ImageObject","inLanguage":"ru-RU","@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#primaryimage","url":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/09\/python-async.png","contentUrl":"https:\/\/nodemaven.com\/wp-content\/uploads\/2026\/09\/python-async.png","width":870,"height":490,"caption":"Python Async | Make web scraping Faster | NodeMaven"},{"@type":"BreadcrumbList","@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nodemaven.com\/"},{"@type":"ListItem","position":2,"name":"Python Async Requests: Speed Up Web Scraping Without Breaking Rate Limits"}]},{"@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\/python-async-requests\/#local-main-organization-logo"},"image":{"@id":"https:\/\/nodemaven.com\/blog\/python-async-requests\/#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\/python-async-requests\/#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\/40560","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=40560"}],"version-history":[{"count":5,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/posts\/40560\/revisions"}],"predecessor-version":[{"id":40566,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/posts\/40560\/revisions\/40566"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/media\/40562"}],"wp:attachment":[{"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/media?parent=40560"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/categories?post=40560"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nodemaven.com\/ru\/wp-json\/wp\/v2\/tags?post=40560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}