{"id":497367,"date":"2026-10-05T10:23:49","date_gmt":"2026-10-05T10:23:49","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=497367"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2026-10-05T10:23:49","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=497367","title":{"rendered":"\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0430 Python: HTTP, Scrapy \u0438\u043b\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u2014 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041a\u043e\u0433\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u043d\u0430 Python, \u0432 \u043e\u0434\u0438\u043d \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442 BeautifulSoup, Selenium, Scrapy \u0438 Playwright. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u0432\u044b\u0431\u043e\u0440 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432, \u043d\u043e \u044d\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439. BeautifulSoup \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u0441\u0435\u0442\u044c. Selenium \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u0430\u0440\u0441\u0435\u0440. Scrapy \u2014 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440. \u0421\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043b\u043e\u0431 \u2014 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043a\u0430\u043a \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0440\u043e\u0431\u043a\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0447 \u0438 \u0442\u0430\u043a\u0441\u0438.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044d\u0442\u0430 \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u0430 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u043e\u0440\u043e\u0433\u043e. \u0414\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0438\u0437 \u043f\u0430\u0440\u044b \u0442\u044b\u0441\u044f\u0447 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u044e\u0442 Selenium \u0441 Chrome, \u0445\u043e\u0442\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c HTML. \u0418\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442: \u043f\u043e\u043b\u0434\u043d\u044f \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c requests\u2019\u043e\u043c \u0442\u043e, \u0447\u0442\u043e \u0440\u0438\u0441\u0443\u0435\u0442 JavaScript, \u0438 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e\u0442, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u0443\u0441\u0442\u043e\u0439 <code>&lt;div id=\"root\"&gt;<\/code>.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043f\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u044f \u0441\u043e\u0431\u0440\u0430\u043b\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0442\u0435\u043d\u0434 \u0441 \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u043c\u0438: \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 HTML, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 JavaScript, \u043c\u0430\u0441\u0441\u043e\u0432\u044b\u0439 \u043e\u0431\u0445\u043e\u0434 \u0441\u043e\u0442\u0435\u043d \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0433\u0434\u0435 \u043d\u0430\u0434\u043e \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 \u0438 \u0436\u0434\u0430\u0442\u044c \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u043a\u0438. \u0412 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0440\u043e\u0433\u043d\u0430\u043b\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0430 \u043d\u0430 \u0432\u0440\u0435\u043c\u044f, \u043f\u0430\u043c\u044f\u0442\u044c, \u043e\u0431\u044a\u0451\u043c \u043a\u043e\u0434\u0430 \u0438 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0421\u043f\u043e\u0439\u043b\u0435\u0440: \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0435 \u00ab\u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435\u00bb, \u0430 \u00ab\u0433\u0434\u0435 \u043b\u0435\u0436\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0435\u00bb. \u041a\u043e\u0433\u0434\u0430 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c.<\/p>\n<h3>\u0427\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c<\/h3>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0441\u043b\u043e\u0438, \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043b\u043e\u044f.<\/p>\n<p><strong>HTTP-\u043a\u043b\u0438\u0435\u043d\u0442<\/strong> (requests, httpx) \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043e\u0442\u0434\u0430\u0451\u0442 \u043e\u0442\u0432\u0435\u0442 \u043a\u0430\u043a \u0435\u0441\u0442\u044c: \u0431\u0430\u0439\u0442\u044b, \u0442\u0435\u043a\u0441\u0442, JSON. \u041f\u0440\u043e HTML \u043e\u043d \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, JavaScript \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442.<\/p>\n<p><strong>HTML-\u043f\u0430\u0440\u0441\u0435\u0440<\/strong> (BeautifulSoup, lxml, selectolax) \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 HTML \u0432 \u0434\u0435\u0440\u0435\u0432\u043e, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c CSS-\u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438\u043b\u0438 XPath. \u041e\u0442\u043a\u0443\u0434\u0430 \u0432\u0437\u044f\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u043e\u043a\u0430, \u0435\u043c\u0443 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e.<\/p>\n<pre><code>HTTP CLIENT (requests \/ httpx)      \u2193   HTML \/ JSON      \u2193PARSER (BeautifulSoup \/ lxml \/ selectolax)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper\"><\/span><\/a><\/div><\/pre>\n<p><strong>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/strong> (Selenium, Playwright) \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043c \u0438\u0437 Python. \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442, \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0438 DOM \u0441\u0442\u0440\u043e\u0438\u0442 \u0441\u0430\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0430 Python \u0447\u0438\u0442\u0430\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<pre><code>BROWSER AUTOMATION (Selenium \/ Playwright)      \u2193\u0431\u0440\u0430\u0443\u0437\u0435\u0440: \u0441\u0435\u0442\u044c \u2192 HTML \u2192 CSS \u2192 JavaScript      \u2193   DOM (\u0442\u043e, \u0447\u0442\u043e \u0432\u0438\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><strong>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a<\/strong> (Scrapy) \u2014 \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 HTTP: \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u0432\u0442\u043e\u0440\u044b, \u0444\u0438\u043b\u044c\u0442\u0440 \u0434\u0443\u0431\u043b\u0435\u0439, \u044d\u043a\u0441\u043f\u043e\u0440\u0442. \u0412\u043d\u0443\u0442\u0440\u0438 \u0443 \u043d\u0435\u0433\u043e parsel \u043f\u043e\u0432\u0435\u0440\u0445 lxml, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438 selectolax.<\/p>\n<pre><code>SCRAPY      \u2193HTTP + scheduler + retries + middlewares + pipelines + spiders<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h4>\u0427\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0436\u0438\u0432\u043e<\/h4>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u044f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0430 \u0441\u0432\u0435\u0436\u0438\u0435 \u0440\u0435\u043b\u0438\u0437\u044b \u043d\u0430 PyPI \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432 (\u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2026).<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u043b\u043e\u0439<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0435\u0440\u0441\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0435\u043b\u0438\u0437<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0417\u0430\u043c\u0435\u0442\u043a\u0430<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/requests\/\" rel=\"noopener nofollow\">requests<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP-\u043a\u043b\u0438\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.34<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043c\u0430\u0439 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e sync<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/httpx\/\" rel=\"noopener nofollow\">httpx<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP-\u043a\u043b\u0438\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.28<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0435\u043a\u0430\u0431\u0440\u044c 2024<\/p>\n<\/td>\n<td>\n<p align=\"left\">sync \u0438 async, HTTP\/2; \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 \u0434\u0430\u0432\u043d\u043e \u043d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/beautifulsoup4\/\" rel=\"noopener nofollow\">beautifulsoup4<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u0430\u0440\u0441\u0435\u0440 (\u043e\u0431\u0451\u0440\u0442\u043a\u0430)<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.15<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0438\u044e\u043d\u044c 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u043e\u0432\u0435\u0440\u0445 html.parser, lxml \u0438\u043b\u0438 html5lib<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/lxml\/\" rel=\"noopener nofollow\">lxml<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u0430\u0440\u0441\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.1<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">libxml2, XPath<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/selectolax\/\" rel=\"noopener nofollow\">selectolax<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u0430\u0440\u0441\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.4<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0432\u0438\u0436\u043a\u0438 Lexbor \u0438 Modest, \u0442\u043e\u043b\u044c\u043a\u043e CSS<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/Scrapy\/\" rel=\"noopener nofollow\">Scrapy<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.19<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">Twisted + asyncio<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/selenium\/\" rel=\"noopener nofollow\">selenium<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.50<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442 Selenium Manager<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/playwright\/\" rel=\"noopener nofollow\">playwright<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.63<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026<\/p>\n<\/td>\n<td>\n<p align=\"left\">Chromium, Firefox, WebKit; sync \u0438 async<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/MechanicalSoup\/\" rel=\"noopener nofollow\">MechanicalSoup<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP + \u0444\u043e\u0440\u043c\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.4<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043c\u0430\u0439 2025<\/p>\n<\/td>\n<td>\n<p align=\"left\">requests + BeautifulSoup, \u0431\u0435\u0437 JS<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/pyppeteer\/\" rel=\"noopener nofollow\">pyppeteer<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0444\u0435\u0432\u0440\u0430\u043b\u044c 2024<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432 README: \u00abThis repo is unmaintained\u00bb<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"https:\/\/pypi.org\/project\/cloudscraper\/\" rel=\"noopener nofollow\">cloudscraper<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP-\u043a\u043b\u0438\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.2<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0430\u043f\u0440\u0435\u043b\u044c 2023<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0440\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0438. <strong>Pyppeteer<\/strong> \u043a\u043e\u0433\u0434\u0430-\u0442\u043e \u0431\u044b\u043b \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c headless Chrome \u0438\u0437 asyncio, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0430\u0432\u0442\u043e\u0440\u044b \u0441\u0430\u043c\u0438 \u043f\u0438\u0448\u0443\u0442, \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0438 \u0441\u043e\u0432\u0435\u0442\u0443\u044e\u0442 Playwright. <strong>MechanicalSoup<\/strong> \u2014 \u044d\u0442\u043e requests \u0438 BeautifulSoup \u0441 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439 \u0441 HTML-\u0444\u043e\u0440\u043c\u0430\u043c\u0438; JavaScript \u043e\u043d \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u043a\u0435 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u0432\u044f\u0437\u043a\u0438 requests + BS4, \u0430 \u043d\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u043a\u0435 \u043d\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u0435\u0442 \u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u043c\u0438. \u0421\u0432\u043e\u044f \u043d\u0438\u0448\u0430 \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c: \u0441\u0442\u0430\u0440\u044b\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0441\u0430\u0439\u0442\u044b \u0441 \u0444\u043e\u0440\u043c\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0438\u043b\u0438 \u043f\u043e\u0438\u0441\u043a\u0430. <strong>cloudscraper<\/strong> \u043f\u0440\u044f\u043c\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043e\u0431\u0445\u043e\u0434\u0430 \u0437\u0430\u0449\u0438\u0442\u044b Cloudflare, \u0430 \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u043f\u0440\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u043b\u0438 \u0441\u0430\u0439\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u043c challenge-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u044d\u0442\u043e \u043f\u043e\u0432\u043e\u0434 \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 API \u0438\u043b\u0438 \u0434\u043e\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c.<\/p>\n<p>\u041f\u0440\u043e httpx \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 \u043d\u0435\u0442 \u0441 \u043a\u043e\u043d\u0446\u0430 2024 \u0433\u043e\u0434\u0430, \u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 0.x. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u0438 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u0430\u044f, \u043d\u043e \u043d\u0438\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0433\u0434\u0435 \u044d\u0442\u043e \u0430\u0443\u043a\u043d\u0443\u043b\u043e\u0441\u044c.<\/p>\n<h3>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043d\u0434<\/h3>\n<p>\u0412\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0438\u0434\u0443\u0442 \u043f\u0440\u043e\u0442\u0438\u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 Starlette. \u0416\u0438\u0432\u043e\u0439 \u0441\u0430\u0439\u0442 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0433\u043e\u043d\u0430\u043c\u0438, \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f CDN \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441 \u0440\u0430\u0437\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e, \u0442\u0430\u043a \u0447\u0442\u043e \u0446\u0438\u0444\u0440\u044b \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0442\u044b\u0441\u044f\u0447\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e 64 \u0432 \u0447\u0443\u0436\u043e\u0439 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a, \u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u0447\u0443\u0436\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p>\u0423 localhost \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0431\u0435\u0434\u0430: \u0441\u0435\u0442\u044c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u0430\u044f, \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u0436\u0434\u0451\u0442 50 \u043c\u0441 \u0447\u0435\u0440\u0435\u0437 <code>asyncio.sleep<\/code>, \u0434\u0440\u0443\u0433\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442. \u0413\u0440\u0443\u0431\u0430\u044f, \u043d\u043e \u0447\u0435\u0441\u0442\u043d\u0430\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0441\u0430\u0439\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043d\u0435 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041c\u0430\u0440\u0448\u0440\u0443\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0442\u0430\u043c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/catalog?page=N<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 HTML: 20 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a + \u043c\u0435\u043d\u044e \u0438 \u043f\u0440\u043e\u043c\u043e-\u0431\u043b\u043e\u043a\u0438, \u043e\u043a\u043e\u043b\u043e 75 \u041a\u0411, 1000 \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/p>\n<\/td>\n<td>\n<p align=\"left\">1, 3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/flaky\/catalog?page=N<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e \u0436\u0435, \u043d\u043e \u043a\u0430\u0436\u0434\u0430\u044f 10-\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 503<\/p>\n<\/td>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/spa<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u0443\u0441\u0442\u043e\u0439 <code>&lt;div id=\"app\"&gt;<\/code> \u0438 <code>app.js<\/code> \u0441 <code>fetch<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/api\/products?page=N<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">JSON, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 <code>app.js<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/ui<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0444\u043e\u0440\u043c\u0430 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0435\u0449\u0451\u00bb<\/p>\n<\/td>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041c\u0430\u0448\u0438\u043d\u0430 \u2014 \u043d\u043e\u0443\u0442\u0431\u0443\u043a \u043d\u0430 Intel Core Ultra 5 125H \u0441 16 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438, Windows 11, Python 3.14. Selenium \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c Chrome 154, Playwright \u2014 \u0441\u043e \u0441\u0432\u043e\u0438\u043c Chromium, \u043e\u0431\u0430 \u0432 headless-\u0440\u0435\u0436\u0438\u043c\u0435. \u0421\u0435\u0440\u0432\u0435\u0440 \u0441\u0442\u0435\u043d\u0434\u0430 \u043a\u0440\u0443\u0442\u0438\u043b\u0441\u044f \u043d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u043c\u0430\u0448\u0438\u043d\u0435.<\/p>\n<p>\u041a\u0430\u043a \u043c\u0435\u0440\u0438\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 \u043d\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435, \u0447\u0442\u043e\u0431\u044b \u0432 \u0437\u0430\u043c\u0435\u0440 \u043f\u043e\u043f\u0430\u043b\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u043b\u0430\u0442\u0438\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a: \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u0441\u0442\u0430\u0440\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u0441\u0442\u0430\u0440\u0442 \u0440\u0435\u0430\u043a\u0442\u043e\u0440\u0430 Twisted;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0430\u043c\u044f\u0442\u044c \u2014 \u043f\u0438\u043a \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0433\u043e RSS \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0438 \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432 (chromedriver, \u0434\u0440\u0430\u0439\u0432\u0435\u0440 Playwright, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b Chrome) \u0447\u0435\u0440\u0435\u0437 psutil. Chrome \u0434\u0435\u043b\u0438\u0442 \u0447\u0430\u0441\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u0446\u0438\u0444\u0440\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u044b\u0448\u0435\u043d\u044b;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0433\u0440\u0435\u0432\u043e\u0447\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a, \u043f\u043e\u0442\u043e\u043c 5\u20137 \u0437\u0430\u0447\u0451\u0442\u043d\u044b\u0445, \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u043c\u0435\u0434\u0438\u0430\u043d\u0430;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0433\u043e\u043d \u0437\u0430\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432\u0435\u0440\u043d\u0443\u043b \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0442\u043e\u0432\u0430\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0434 \u0441\u0442\u0435\u043d\u0434\u0430 \u0438 \u0432\u0441\u0435\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432: [\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439].<\/p>\n<h3>\u0422\u0435\u0441\u0442 \u21161. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 HTML<\/h3>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u044c 20 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u0438 \u0446\u0435\u043d. \u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 HTML.<\/p>\n<h4>requests + BeautifulSoup<\/h4>\n<pre><code class=\"python\">resp = requests.get(URL, timeout=10)resp.raise_for_status()soup = BeautifulSoup(resp.text, \"lxml\")items = [    {\"title\": card.select_one(\".title\").get_text(strip=True),     \"price\": float(card.select_one(\".price\").get_text())}    for card in soup.select(\"article.product\")]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>timeout<\/code> \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0434\u043b\u044f \u043a\u0440\u0430\u0441\u043e\u0442\u044b: \u0431\u0435\u0437 \u043d\u0435\u0433\u043e requests \u0431\u0443\u0434\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u0435\u0447\u043d\u043e. <code>raise_for_status()<\/code> \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 404 \u0438 503 \u0432 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u2014 \u0438\u043d\u0430\u0447\u0435 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0432\u0435\u0440\u043d\u0451\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a. \u0412\u0442\u043e\u0440\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>BeautifulSoup<\/code> \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u043a \u044d\u0442\u043e\u043c\u0443 \u0435\u0449\u0451 \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0435: \u043a\u043e\u0434 \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<h4>httpx + selectolax<\/h4>\n<pre><code class=\"python\">resp = httpx.get(URL, timeout=10)resp.raise_for_status()tree = LexborHTMLParser(resp.text)items = [    {\"title\": node.css_first(\".title\").text(strip=True),     \"price\": float(node.css_first(\".price\").text())}    for node in tree.css(\"article.product\")]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0447\u0442\u0438 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435: \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b httpx \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441 \u043f\u043e\u0445\u043e\u0436\u0438\u043c API. <code>css_first<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>None<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u0451\u043b, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0435 \u0431\u0435\u0437 \u0446\u0435\u043d\u044b \u043a\u043e\u0434 \u0443\u043f\u0430\u0434\u0451\u0442 \u0441 <code>AttributeError<\/code>. XPath \u0432 selectolax \u043d\u0435\u0442.<\/p>\n<h4>Scrapy<\/h4>\n<pre><code class=\"python\">class OnePage(scrapy.Spider):    name = \"one\"    start_urls = [URL]    def parse(self, response):        for card in response.css(\"article.product\"):            yield {\"title\": card.css(\".title::text\").get(),                   \"price\": float(card.css(\".price::text\").get())}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u0430\u0443\u043a \u0441\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442. \u041e\u043d \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442, \u043e\u0442\u043a\u0443\u0434\u0430 \u043d\u0430\u0447\u0430\u0442\u044c \u0438 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043e\u0442\u0432\u0435\u0442\u043e\u043c, \u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439, \u043f\u043e\u0432\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u043e\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0438\u0436\u043e\u043a. <code>yield<\/code> \u043e\u0442\u0434\u0430\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 pipeline, \u0430 \u043d\u0435 \u0432 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0434, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0437 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0449\u0451 \u0441\u0442\u0440\u043e\u043a \u043f\u044f\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c \u043e\u0431\u0432\u044f\u0437\u043a\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u0438\u0445 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 <code>scrapy crawl one -o items.json<\/code>.<\/p>\n<p>\u0411\u0440\u0430\u0443\u0437\u0435\u0440\u044b \u044f \u043f\u0440\u043e\u0433\u043d\u0430\u043b\u0430 \u043d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0435 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u0438\u043c JS-\u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0438 \u043d\u0430\u0438\u0432\u043d\u043e, \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/p>\n<h4>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f, \u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0430\u043c\u044f\u0442\u044c, \u041c\u0411<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests + BeautifulSoup<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,3<\/p>\n<\/td>\n<td>\n<p align=\"left\">~40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">httpx + selectolax \/ lxml<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,6<\/p>\n<\/td>\n<td>\n<p align=\"left\">~50<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Playwright<\/p>\n<\/td>\n<td>\n<p align=\"left\">~1,0<\/p>\n<\/td>\n<td>\n<p align=\"left\">~380<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Scrapy<\/p>\n<\/td>\n<td>\n<p align=\"left\">~1,0<\/p>\n<\/td>\n<td>\n<p align=\"left\">~90<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Selenium<\/p>\n<\/td>\n<td>\n<p align=\"left\">~3,3<\/p>\n<\/td>\n<td>\n<p align=\"left\">~570<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0421 \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0432\u0441\u0451 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e: \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 \u0434\u0435\u0441\u044f\u0442\u044c \u0440\u0430\u0437 \u0431\u043e\u043b\u044c\u0448\u0435. \u0410 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0442\u0440\u0438 \u0432\u0435\u0449\u0438 \u043c\u0435\u043d\u044f \u0443\u0434\u0438\u0432\u0438\u043b\u0438.<\/p>\n<p><strong>httpx \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 requests \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u044c \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/strong> \u0420\u0430\u0437\u043b\u043e\u0436\u0438\u043b\u0430 \u043f\u043e \u0448\u0430\u0433\u0430\u043c: \u0441\u0430\u043c \u0438\u043c\u043f\u043e\u0440\u0442 \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u0430 \u0432\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 <code>httpx.Client()<\/code> \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u043a\u043e\u043b\u043e 0,3 \u0441 \u0434\u0430\u0436\u0435 \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e HTTP \u2014 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 SSL-\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0433\u0440\u0443\u0437\u0438\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b. <code>httpx.get()<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u0430\u043a\u043e\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432. \u0412 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c \u0434\u043e\u043b\u0433\u043e\u0436\u0438\u0432\u0443\u0449\u0438\u043c <code>Client<\/code> \u044d\u0442\u043e \u0440\u0430\u0437\u043e\u0432\u0430\u044f \u0446\u0435\u043d\u0430, \u0432 \u0446\u0438\u043a\u043b\u0435 \u0438\u0437 <code>httpx.get()<\/code> \u2014 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u044f.<\/p>\n<p><strong>Scrapy \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043d\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 Playwright.<\/strong> \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b\u0430, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u043b\u0441\u044f. \u0421\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u043e\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0442\u044b\u0435 \u0434\u043e\u043b\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0432\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u2014 \u0438\u043c\u043f\u043e\u0440\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0441\u0442\u0430\u0440\u0442 \u0440\u0435\u0430\u043a\u0442\u043e\u0440\u0430, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f middlewares \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439. \u0414\u043b\u044f \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0430 \u043d\u0430 \u0447\u0430\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u043e \u043d\u0438\u0447\u0442\u043e. \u0414\u043b\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 cron \u0434\u0451\u0440\u0433\u0430\u0435\u0442 \u0440\u0430\u0437 \u0432 \u043c\u0438\u043d\u0443\u0442\u0443 \u0440\u0430\u0434\u0438 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u2014 \u0437\u0430\u043c\u0435\u0442\u043d\u043e.<\/p>\n<p><strong>Selenium \u0432\u0442\u0440\u043e\u0435 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 Playwright, \u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0442\u0443\u0442 \u043d\u0438 \u043f\u0440\u0438 \u0447\u0451\u043c.<\/strong> \u0417\u0430\u043f\u0443\u0441\u043a Chrome \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0437\u0430\u043d\u044f\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0430 <code>driver.quit()<\/code> \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u043b \u043e\u043a\u043e\u043b\u043e \u0434\u0432\u0443\u0445. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430\u0448\u0451\u043b\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 Selenium (<code>webdriver\/common\/service.py<\/code>): \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043d \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0437\u0430\u043a\u0440\u044b\u043b\u0441\u044f \u043b\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440, \u0432 \u0446\u0438\u043a\u043b\u0435 \u0441 <code>sleep(1)<\/code>. chromedriver \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u0437\u0430\u043a\u0440\u044b\u0442\u044c\u0441\u044f \u043a \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u2014 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0434\u0432\u0443\u0445 \u0441\u0435\u043a\u0443\u043d\u0434. \u0411\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0441 Playwright \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u0447\u0435\u0437\u0430\u0435\u0442.<\/p>\n<p>\u041d\u0430\u0438\u0432\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u043e \u0434\u0435\u0441\u044f\u0442\u044b\u0435 \u0434\u043e\u043b\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b: \u0443 Selenium \u043a\u0430\u0436\u0434\u044b\u0439 <code>find_element<\/code> \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 <code>.text<\/code> \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441 \u043a chromedriver. \u041d\u0430 \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u0438 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430\u0445 \u044d\u0442\u043e \u043c\u0435\u043b\u043e\u0447\u044c, \u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0432 \u0442\u044b\u0441\u044f\u0447\u0443 \u0441\u0442\u0440\u043e\u043a \u0443\u0436\u0435 \u043d\u0435\u0442.<\/p>\n<p>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e\u0439: \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0435\u0441\u0442\u044c \u0432 HTML, \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0432\u0435\u0440\u043d\u0451\u0442 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0432 3\u201310 \u0440\u0430\u0437 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0438 \u0441 \u0434\u0435\u0441\u044f\u0442\u0438\u043a\u0440\u0430\u0442\u043d\u044b\u043c \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u043c \u043f\u0430\u043c\u044f\u0442\u0438. \u041d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c. \u041d\u0430 \u0442\u044b\u0441\u044f\u0447\u0435 \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u0434\u0435\u043d\u044c\u0433\u0438 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u044b.<\/p>\n<h3>\u0422\u0435\u0441\u0442 \u21162. JavaScript<\/h3>\n<p>\u0422\u0435 \u0436\u0435 20 \u0442\u043e\u0432\u0430\u0440\u043e\u0432, \u043d\u043e <code>\/spa<\/code> \u043e\u0442\u0434\u0430\u0451\u0442 \u043f\u043e\u0447\u0442\u0438 \u043f\u0443\u0441\u0442\u043e\u0439 HTML, \u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0440\u0438\u0441\u0443\u0435\u0442 <code>app.js<\/code> \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a JSON API. \u0422\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 React \u0438 Vue \u0431\u0435\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<h4>\u0427\u0442\u043e \u0432\u0438\u0434\u0438\u0442 requests<\/h4>\n<pre><code class=\"python\">resp = requests.get(\"http:\/\/127.0.0.1:8000\/spa\", timeout=10)soup = BeautifulSoup(resp.text, \"lxml\")soup.select(\"article.product\")   # []<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437. \u0412\u0435\u0441\u044c \u043e\u0442\u0432\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430:<\/p>\n<pre><code>&lt;body&gt;&lt;div id='app'&gt;\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u2026&lt;\/div&gt;&lt;script src='\/static\/app.js'&gt;&lt;\/script&gt;&lt;\/body&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f HTTP-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 <code>&lt;script&gt;<\/code> \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u043a\u0441\u0442. \u041d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442 <code>app.js<\/code> \u0438 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0435\u0433\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 DOM, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043d \u0441\u0442\u0440\u043e\u0438\u0442, \u043d\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f. \u042d\u0442\u043e \u043d\u0435 \u0431\u0430\u0433 requests, \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d.<\/p>\n<h4>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 Network, \u0430 \u043f\u043e\u0442\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0439\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/h4>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043c\u044b\u0441\u043b\u044c \u043f\u0440\u0438 \u0432\u0438\u0434\u0435 \u043f\u0443\u0441\u0442\u043e\u0433\u043e <code>&lt;div id=\"app\"&gt;<\/code> \u2014 \u00ab\u043d\u0443\u0436\u0435\u043d Selenium\u00bb. \u041d\u043e \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u0431\u0435\u0440\u0451\u0442 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u043c HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430 \u043c\u0438\u043d\u0443\u0442\u0443:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c DevTools (F12), \u0432\u043a\u043b\u0430\u0434\u043a\u0430 <strong>Network<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440 <strong>Fetch\/XHR<\/strong> \u0438 <strong>Preserve log<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <strong>Response<\/strong> \u0438\u043b\u0438 <strong>Preview<\/strong> \u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. Ctrl+F \u0432 \u043f\u0430\u043d\u0435\u043b\u0438 Network \u0438\u0449\u0435\u0442 \u0438 \u043f\u043e \u0442\u0435\u043b\u0430\u043c \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0431\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0439\u0434\u044f \u043d\u0443\u0436\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0441\u0434\u0435\u043b\u0430\u0442\u044c <strong>Copy \u2192 Copy as cURL<\/strong> \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435. \u041e\u0442\u0432\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u043b \u2014 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430 \u0441\u0442\u0435\u043d\u0434\u0435 \u0442\u0430\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f <code>GET \/api\/products?page=1<\/code>, \u0438 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0442\u0440\u0451\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c:<\/p>\n<pre><code class=\"python\">resp = httpx.get(\"http:\/\/127.0.0.1:8000\/api\/products\", params={\"page\": 1}, timeout=10)resp.raise_for_status()items = resp.json()[\"items\"]   # id, title, price, in_stock<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0432\u043e\u0432\u0441\u0435: \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0446\u0435\u043d\u0430 \u2014 \u0447\u0438\u0441\u043b\u043e, \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u2014 \u0431\u0443\u043b\u0435\u0432\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0430 \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u0430 \u00ab\u043d\u0435\u0442 \u0432 \u043d\u0430\u043b\u0438\u0447\u0438\u0438\u00bb. \u0412\u0451\u0440\u0441\u0442\u043a\u0430 \u0442\u043e\u0436\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0451\u0442 \u0431\u044b\u0442\u044c \u0432\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439: \u043f\u0440\u0438 \u0440\u0435\u0434\u0438\u0437\u0430\u0439\u043d\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b, \u0430 \u0444\u043e\u0440\u043c\u0430\u0442 API \u0442\u0440\u043e\u0433\u0430\u044e\u0442 \u043a\u0443\u0434\u0430 \u0440\u0435\u0436\u0435, \u043d\u0430 \u043d\u0451\u043c \u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0441\u0430\u043c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434.<\/p>\n<p>\u0421 GraphQL \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435: \u0432 Network \u0432\u0438\u0434\u0435\u043d <code>POST \/graphql<\/code> \u0441 \u0442\u0435\u043b\u043e\u043c <code>{\"query\": ..., \"variables\": ...}<\/code>, \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 <code>httpx.post(url, json=payload)<\/code>. \u0418\u043d\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 HTML, \u043d\u043e \u043d\u0435 \u0432 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0435, \u0430 \u0432 <code>&lt;script type=\"application\/json\"&gt;<\/code> \u0438\u043b\u0438 <code>application\/ld+json<\/code> \u2014 \u0442\u043e\u0433\u0434\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0442\u0435\u0433 \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c <code>json.loads<\/code>.<\/p>\n<p>\u0413\u0440\u0430\u043d\u0438\u0446\u044b \u0443 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d \u0442\u043e\u043a\u0435\u043d\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 JavaScript, \u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0434\u0443\u0442 \u043f\u043e WebSocket \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u044d\u0442\u043e \u0440\u0443\u043a\u0430\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0440\u043e\u0436\u0435, \u0447\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440. \u0418 \u043d\u0435\u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 API \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043e\u0431\u0435\u0449\u0430\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c, \u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0441\u0430\u0439\u0442\u0430.<\/p>\n<h4>Selenium<\/h4>\n<pre><code class=\"python\">driver.get(SPA_URL)WebDriverWait(driver, 10).until(    EC.presence_of_all_elements_located((By.CSS_SELECTOR, \"article.product\")))cards = driver.find_elements(By.CSS_SELECTOR, \"article.product\")<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>driver.get()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>load<\/code>, \u043a\u043e\u0433\u0434\u0430 <code>fetch<\/code> \u0435\u0449\u0451 \u0438\u0434\u0451\u0442. \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0430: \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 <code>get<\/code> \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043d\u043e\u043b\u044c. \u041e\u0442\u0441\u044e\u0434\u0430 \u044f\u0432\u043d\u043e\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435: <code>WebDriverWait<\/code> \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438 \u0447\u0435\u0440\u0435\u0437 10 \u0441\u0435\u043a\u0443\u043d\u0434 \u0441\u0434\u0430\u0451\u0442\u0441\u044f \u0441 <code>TimeoutException<\/code>. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u043d \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0440\u0430\u0437 \u0432 \u043f\u043e\u043b\u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0438 \u044d\u0442\u043e \u0432\u0438\u0434\u043d\u043e: \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0447\u0442\u0438 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435. \u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <code>poll_frequency<\/code>.<\/p>\n<h4>Playwright<\/h4>\n<pre><code class=\"python\">page.goto(SPA_URL)cards = page.locator(\"article.product\")cards.first.wait_for()titles = cards.locator(\".title\").all_inner_texts()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0432\u0435\u0449\u044c \u2014 locator. <code>page.locator(...)<\/code> \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0449\u0435\u0442 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430, \u044d\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0437\u0430\u043d\u043e\u0432\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438. <code>click()<\/code> \u0438\u043b\u0438 <code>inner_text()<\/code> \u0441\u0430\u043c\u0438 \u0434\u043e\u0436\u0434\u0443\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0430 \u043a\u043b\u0438\u043a \u2014 \u0435\u0449\u0451 \u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u0442\u0430\u043b \u0432\u0438\u0434\u0438\u043c\u044b\u043c \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c. \u041d\u043e \u0441\u043f\u0438\u0441\u043e\u0447\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u2014 <code>all()<\/code>, <code>count()<\/code>, <code>all_inner_texts()<\/code> \u2014 \u043d\u0435 \u0436\u0434\u0443\u0442, \u043e \u0447\u0451\u043c \u043f\u0440\u044f\u043c\u043e \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f. \u0411\u0435\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 <code>wait_for()<\/code> \u043a\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u0445, \u0440\u043e\u0432\u043d\u043e \u043a\u0430\u043a Selenium \u0431\u0435\u0437 <code>WebDriverWait<\/code>.<\/p>\n<p>\u0415\u0441\u0442\u044c \u0438 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442: \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c, \u043d\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0437\u044f\u0442\u044c \u043d\u0435 \u0438\u0437 DOM, \u0430 \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430 API, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0441\u0430\u043c:<\/p>\n<pre><code class=\"python\">with page.expect_response(lambda r: \"\/api\/products\" in r.url) as resp_info:    page.goto(SPA_URL)items = resp_info.value.json()[\"items\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0422\u043e\u043a\u0435\u043d\u044b, cookies \u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434, \u0430 \u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0447\u0438\u0441\u0442\u044b\u0439 JSON \u0431\u0435\u0437 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432.<\/p>\n<h4>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041d\u0430\u0448\u0451\u043b \u0442\u043e\u0432\u0430\u0440\u043e\u0432<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f, \u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0430\u043c\u044f\u0442\u044c, \u041c\u0411<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests, HTML \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,3<\/p>\n<\/td>\n<td>\n<p align=\"left\">~40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">httpx, \u0437\u0430\u043f\u0440\u043e\u0441 \u043a API<\/p>\n<\/td>\n<td>\n<p align=\"left\">20<\/p>\n<\/td>\n<td>\n<p align=\"left\">~0,6<\/p>\n<\/td>\n<td>\n<p align=\"left\">~45<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Playwright, \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u043e\u0442\u0432\u0435\u0442\u0430 API<\/p>\n<\/td>\n<td>\n<p align=\"left\">20<\/p>\n<\/td>\n<td>\n<p align=\"left\">~0,8<\/p>\n<\/td>\n<td>\n<p align=\"left\">~330<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Playwright, \u0447\u0442\u0435\u043d\u0438\u0435 DOM<\/p>\n<\/td>\n<td>\n<p align=\"left\">20<\/p>\n<\/td>\n<td>\n<p align=\"left\">~0,9<\/p>\n<\/td>\n<td>\n<p align=\"left\">~340<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Selenium, \u0447\u0442\u0435\u043d\u0438\u0435 DOM<\/p>\n<\/td>\n<td>\n<p align=\"left\">20<\/p>\n<\/td>\n<td>\n<p align=\"left\">~3,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">~540<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0440\u044f\u043c\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a API \u2014 \u0441\u0430\u043c\u044b\u0439 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0438\u0437 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 \u0441\u0435\u043c\u044c \u0440\u0430\u0437 \u044d\u043a\u043e\u043d\u043e\u043c\u043d\u0435\u0435 \u043f\u043e \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u2014 \u0432\u0441\u0451 \u0442\u0435 \u0436\u0435 0,3 \u0441 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041d\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u0430 \u0442\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0437\u0430\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u0432 DevTools. \u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0430\u0439\u0442 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0443\u0436\u0435\u043d Selenium \u0438\u043b\u0438 Playwright.<\/p>\n<h3>\u0422\u0435\u0441\u0442 \u21163. \u041c\u0430\u0441\u0441\u043e\u0432\u044b\u0439 \u0441\u0431\u043e\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/h3>\n<p>\u041e\u0431\u043e\u0439\u0442\u0438 500 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c 10 000 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439. \u0422\u0443\u0442 \u0432\u0430\u0436\u0435\u043d \u0443\u0436\u0435 \u043d\u0435 \u0441\u0442\u0430\u0440\u0442, \u0430 \u0442\u043e, \u043a\u0430\u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0430\u0435\u0442\u0441\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435\u043c \u0441\u0435\u0442\u0438. \u041f\u0430\u0440\u0441\u0435\u0440 \u0432\u0435\u0437\u0434\u0435 selectolax, \u043a\u0440\u043e\u043c\u0435 Scrapy \u0441\u043e \u0441\u0432\u043e\u0438\u043c parsel.<\/p>\n<h4>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 requests<\/h4>\n<pre><code class=\"python\">retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[429, 500, 502, 503, 504])with requests.Session() as s:    s.mount(\"http:\/\/\", HTTPAdapter(max_retries=retry))    for url in URLS:        resp = s.get(url, timeout=10)        if resp.ok:            items += parse(resp.text)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>Session<\/code> \u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c\u0438, \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0434\u0451\u0442 \u043f\u043e \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u043c\u0443 TCP. <code>Retry<\/code> \u0438\u0437 urllib3 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u0434\u0430\u043c\u0438 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0430\u0443\u0437\u0443. \u0414\u0435\u0442\u0430\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0443\u0432\u0438\u0434\u0435\u043b\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445: \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0432\u0442\u043e\u0440 \u0438\u0434\u0451\u0442 \u0441\u0440\u0430\u0437\u0443, \u043f\u0430\u0443\u0437\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u0434\u0440\u044f\u0434. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430: \u043f\u043e\u043a\u0430 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u0436\u0434\u0451\u0442 \u043e\u0442\u0432\u0435\u0442\u0430, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442.<\/p>\n<p>\u0422\u043e\u0442 \u0436\u0435 requests \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0442\u044c \u043f\u0443\u043b\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f <code>Session<\/code> \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0442\u043e\u043a:<\/p>\n<pre><code class=\"python\">local = threading.local()def fetch(url):    if not hasattr(local, \"s\"):        local.s = requests.Session()    resp = local.s.get(url, timeout=10)    return parse(resp.text) if resp.ok else []with ThreadPoolExecutor(max_workers=16) as pool:    chunks = list(pool.map(fetch, URLS))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0442\u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u0432 Python \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e: \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 GIL \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f. \u0414\u0435\u0441\u044f\u0442\u043a\u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0442\u044b\u0441\u044f\u0447\u0438 \u2014 \u0443\u0436\u0435 \u043f\u043e\u0432\u043e\u0434 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 asyncio.<\/p>\n<h4>Async httpx<\/h4>\n<pre><code class=\"python\">sem = asyncio.Semaphore(CONCURRENCY)limits = httpx.Limits(max_connections=CONCURRENCY, max_keepalive_connections=CONCURRENCY)async with httpx.AsyncClient(timeout=10, limits=limits) as client:    async def fetch(url):        async with sem:            resp = await client.get(url)        return parse(resp.text) if resp.is_success else []    chunks = await asyncio.gather(*(fetch(u) for u in URLS))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0435\u043b\u0435\u0439 \u0434\u0432\u0430: \u0441\u0435\u043c\u0430\u0444\u043e\u0440 \u0434\u0435\u0440\u0436\u0438\u0442 \u0447\u0438\u0441\u043b\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, <code>Limits<\/code> \u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0443\u043b\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439. \u0411\u0435\u0437 \u0441\u0435\u043c\u0430\u0444\u043e\u0440\u0430 \u0432\u0441\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0440\u0430\u0437\u043e\u043c \u0432\u0441\u0442\u0430\u043d\u0443\u0442 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0443\u043b\u0430, \u0433\u0434\u0435 \u0443 \u043d\u0438\u0445 \u0441\u0432\u043e\u0439 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f. \u0412\u0442\u043e\u0440\u0430\u044f \u043b\u043e\u0432\u0443\u0448\u043a\u0430 \u2014 <code>parse()<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b: \u044d\u0442\u043e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 CPU-\u043a\u043e\u0434, \u0438 \u043f\u043e\u043a\u0430 \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, event loop \u0441\u0442\u043e\u0438\u0442. \u0421 selectolax \u044d\u0442\u043e \u0434\u043e\u043b\u0438 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0441 BeautifulSoup \u2014 \u0432 \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c \u0440\u0430\u0437 \u0431\u043e\u043b\u044c\u0448\u0435. \u041f\u043e\u0432\u0442\u043e\u0440\u044b \u0441 \u043f\u0430\u0443\u0437\u0430\u043c\u0438 \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0449\u0451 \u0434\u0435\u0441\u044f\u0442\u043e\u043a \u0441\u0442\u0440\u043e\u043a.<\/p>\n<h4>Scrapy<\/h4>\n<p>\u041a\u043e\u0434 \u043f\u0430\u0443\u043a\u0430 \u043f\u043e\u0447\u0442\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435, \u043a\u0430\u043a \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0442\u0435\u0441\u0442\u0435, \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/p>\n<pre><code class=\"python\">settings = {    \"CONCURRENT_REQUESTS\": 16,    \"CONCURRENT_REQUESTS_PER_DOMAIN\": 16,    \"DOWNLOAD_DELAY\": 0,    \"RETRY_TIMES\": 3,}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0412\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u0432\u0438\u0436\u043e\u043a:<\/p>\n<pre><code>Spider (start_urls, parse)   \u2193 RequestScheduler \u2014 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430\u043c\u0438 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u0434\u0443\u0431\u043b\u0435\u0439   \u2193Downloader middlewares \u2014 User-Agent, cookies, retry, redirect, \u0441\u0436\u0430\u0442\u0438\u0435, robots.txt   \u2193Downloader \u2014 \u043b\u0438\u043c\u0438\u0442\u044b \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043f\u043e \u0434\u043e\u043c\u0435\u043d\u0443, \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438, AutoThrottle   \u2193 ResponseSpider.parse \u2192 Item \/ \u043d\u043e\u0432\u044b\u0435 Request   \u2193Item pipelines \u2014 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f, \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f, \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0411\u0414   \u2193Feed exports \u2014 JSON, JSON Lines, CSV, XML<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0442\u043e, \u0447\u0442\u043e \u0432 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u043c asyncio-\u043a\u043e\u0434\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438: \u043f\u043e\u0432\u0442\u043e\u0440\u044b \u043d\u0430 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0435 \u043a\u043e\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a, \u043e\u0431\u0445\u043e\u0434 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0430\u043c \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u0443\u0436\u0435 \u043f\u043e\u0441\u0435\u0449\u0451\u043d\u043d\u044b\u0445, \u043b\u0438\u043c\u0438\u0442\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0434\u043e\u043c\u0435\u043d, AutoThrottle, \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u043a\u043e\u0434\u0430\u043c \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0420\u0430\u0434\u0438 \u043e\u0434\u043d\u043e\u0433\u043e URL \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0431\u043e\u0440. \u0414\u043b\u044f \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u0434\u0435\u043b\u044f\u043c\u0438 \u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u0443 \u0441\u0430\u0439\u0442\u043e\u0432, \u2014 \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>\u041e\u0434\u043d\u0430 \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0430: <code>RetryMiddleware<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u0442 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0431\u0435\u0437 \u044d\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u0443\u0437\u044b. \u0417\u0430\u043c\u0435\u0434\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 Scrapy \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f AutoThrottle, \u0430 \u043d\u0435 \u0440\u0435\u0442\u0440\u0430\u0438.<\/p>\n<h4>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b: 500 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, 16 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/h4>\n<p>\u041f\u0440\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0435 50 \u043c\u0441 \u0438 16 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u2014 \u043e\u043a\u043e\u043b\u043e \u043f\u043e\u043b\u0443\u0442\u043e\u0440\u0430 \u0441\u0435\u043a\u0443\u043d\u0434. \u0412\u0441\u0451 \u0441\u0432\u0435\u0440\u0445\u0443 \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0438 \u0441\u0430\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u0442\u0435\u043d\u0434\u0430.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f, \u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0442\u0440\u0430\u043d\u0438\u0446\/\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0430\u043c\u044f\u0442\u044c, \u041c\u0411<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests \u0431\u0435\u0437 Session, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">~34<\/p>\n<\/td>\n<td>\n<p align=\"left\">~15<\/p>\n<\/td>\n<td>\n<p align=\"left\">~40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests + Session, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">~31<\/p>\n<\/td>\n<td>\n<p align=\"left\">~16<\/p>\n<\/td>\n<td>\n<p align=\"left\">~40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests, 16 \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2,7<\/p>\n<\/td>\n<td>\n<p align=\"left\">~190<\/p>\n<\/td>\n<td>\n<p align=\"left\">~50<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">async httpx, 16 \u0437\u0430\u0434\u0430\u0447<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2,7<\/p>\n<\/td>\n<td>\n<p align=\"left\">~180<\/p>\n<\/td>\n<td>\n<p align=\"left\">~70<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Scrapy<\/p>\n<\/td>\n<td>\n<p align=\"left\">~4,7<\/p>\n<\/td>\n<td>\n<p align=\"left\">~105<\/p>\n<\/td>\n<td>\n<p align=\"left\">~350<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u043c\u0443 \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u0432 \u0434\u0435\u0441\u044f\u0442\u044c \u0440\u0430\u0437, \u0438 \u044d\u0442\u043e \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0442\u0438. \u0410 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438 asyncio \u043d\u0430 16 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 \u0434\u0430\u043b\u0438 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435. Session \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u043b\u0430 \u043e\u043a\u043e\u043b\u043e 10% \u0434\u0430\u0436\u0435 \u043d\u0430 localhost; \u0441 TLS \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u044c\u044e \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>Scrapy \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u043e\u0447\u0442\u0438 \u0432\u0434\u0432\u043e\u0435 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u0441\u044a\u0435\u043b \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438. \u0427\u0430\u0441\u0442\u044c \u2014 \u0441\u0435\u043a\u0443\u043d\u0434\u0430 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442, \u0447\u0430\u0441\u0442\u044c \u2014 middlewares \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0438 parsel \u0432\u043c\u0435\u0441\u0442\u043e selectolax. \u041e\u0442\u043a\u0443\u0434\u0430 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043c\u044f\u0442\u0438, \u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0441\u0442\u0430\u043b\u0430.<\/p>\n<h4>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b: 1000 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, 64 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/h4>\n<p>\u0410 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u043f\u043e\u0448\u043b\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0442\u0430\u043a, \u043a\u0430\u043a \u044f \u043e\u0436\u0438\u0434\u0430\u043b\u0430.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f, \u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0442\u0440\u0430\u043d\u0438\u0446\/\u0441<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests, 64 \u043f\u043e\u0442\u043e\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">~1,8<\/p>\n<\/td>\n<td>\n<p align=\"left\">~570<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Scrapy<\/p>\n<\/td>\n<td>\n<p align=\"left\">7\u20139<\/p>\n<\/td>\n<td>\n<p align=\"left\">~110<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">async httpx, 64 \u0437\u0430\u0434\u0430\u0447\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">~11,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">~90<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u043e\u0442\u043e\u043a\u0438 \u0443\u0441\u043a\u043e\u0440\u0438\u043b\u0438\u0441\u044c \u0432\u0442\u0440\u043e\u0435, \u0430 async httpx \u0441\u0442\u0430\u043b <em>\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435<\/em>, \u0447\u0435\u043c \u043d\u0430 16. \u041f\u0435\u0440\u0432\u043e\u0439 \u043c\u044b\u0441\u043b\u044c\u044e \u0431\u044b\u043b\u043e, \u0447\u0442\u043e \u0432\u0438\u043d\u043e\u0432\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432 event loop \u0438\u043b\u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 asyncio \u043d\u0430 Windows. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0430 \u0442\u043e\u0442 \u0436\u0435 \u043e\u0431\u0445\u043e\u0434 \u0431\u0435\u0437 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 event loop\u2019\u0430\u043c\u0438:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043b\u0438\u0435\u043d\u0442, 1000 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0431\u0435\u0437 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">16 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/p>\n<\/th>\n<th>\n<p align=\"left\">64 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests, \u043f\u043e\u0442\u043e\u043a\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">~4 \u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">~1 \u0441<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">aiohttp<\/p>\n<\/td>\n<td>\n<p align=\"left\">~4 \u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">~1,3 \u0441<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">httpx<\/p>\n<\/td>\n<td>\n<p align=\"left\">~5 \u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">~8\u20139 \u0441<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>aiohttp \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 asyncio \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0437\u043d\u0430\u0447\u0438\u0442, \u0434\u0435\u043b\u043e \u0432 httpx. \u041f\u043e\u0434 cProfile \u043a\u0430\u0440\u0442\u0438\u043d\u0430 \u0441\u0442\u0430\u043b\u0430 \u044f\u0441\u043d\u043e\u0439: \u0431\u043e\u043b\u044c\u0448\u0435 80% \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0443\u0445\u043e\u0434\u0438\u043b\u043e \u0432 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0443\u043b\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 httpcore, <code>_assign_requests_to_connections<\/code>, \u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 <code>is_idle()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u044b \u0440\u0430\u0437 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0435\u0441\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 <a href=\"https:\/\/github.com\/encode\/httpcore\/pull\/1035\" rel=\"noopener nofollow\">PR #1035<\/a>, \u0433\u0434\u0435 \u0430\u0432\u0442\u043e\u0440 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0435\u0451 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c. \u0412 \u0432\u0435\u0440\u0441\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0441 httpx 0.28, \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u0442.<\/p>\n<p>\u0412\u044b\u0432\u043e\u0434 \u0443\u0437\u043a\u0438\u0439, \u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439: \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c httpx \u043f\u0443\u043b \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441\u0430\u043c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0443\u0437\u043a\u0438\u043c \u043c\u0435\u0441\u0442\u043e\u043c. \u0414\u043e 16 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0432\u0438\u0434\u043d\u043e. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0445\u043e\u0441\u0442\u0443, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 aiohttp \u0438\u043b\u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u2014 \u0438 \u043d\u0435 \u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e async \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u043d\u0430\u0447\u0438\u0442 \u00ab\u0431\u044b\u0441\u0442\u0440\u0435\u0435\u00bb.<\/p>\n<p>Scrapy \u043d\u0430 64 \u0442\u043e\u0436\u0435 \u043d\u0435 \u0443\u0441\u043a\u043e\u0440\u0438\u043b\u0441\u044f \u0438 \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u00ab\u0433\u0443\u043b\u044f\u043b\u00bb \u043e\u0442 \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u043a \u043f\u0440\u043e\u0433\u043e\u043d\u0443. \u041f\u043e\u0434\u043e\u0437\u0440\u0435\u0432\u0430\u044e, \u0447\u0442\u043e \u043e\u043d \u0443\u043f\u0451\u0440\u0441\u044f \u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 CPU \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u0430. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, 110 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u2014 \u0438 \u0442\u0430\u043a \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430 \u0447\u0443\u0436\u043e\u0439 \u0441\u0430\u0439\u0442.<\/p>\n<h4>\u041f\u043e\u0432\u0442\u043e\u0440\u044b: \u043a\u0430\u0436\u0434\u0430\u044f 10-\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 503<\/h4>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043d\u0435 \u043f\u0440\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u041d\u0430 <code>\/flaky\/catalog<\/code> \u043a\u0430\u0436\u0434\u0430\u044f \u0434\u0435\u0441\u044f\u0442\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 503, \u0430 \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u043e\u0431\u0440\u0430\u043d\u043e \u0438\u0437 10 000<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0432\u044b\u0432\u043e\u0434\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests + Session<\/p>\n<\/td>\n<td>\n<p align=\"left\">9 000<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests + Session + Retry<\/p>\n<\/td>\n<td>\n<p align=\"left\">10 000<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">async httpx<\/p>\n<\/td>\n<td>\n<p align=\"left\">9 000<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">async httpx \u0441 \u0440\u0435\u0442\u0440\u0430\u044f\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">10 000<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Scrapy, \u0440\u0435\u0442\u0440\u0430\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\">10 000<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0431\u0435\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432 \u043c\u043e\u043b\u0447\u0430 \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0438 50 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438\u0437 500. <code>if resp.ok:<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e, \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c 0, \u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 10% \u043c\u0435\u043d\u044c\u0448\u0435. \u0423 Scrapy \u043f\u043e\u0432\u0442\u043e\u0440\u044b \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0438 \u0432\u0438\u0434\u043d\u044b \u0432 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0435 \u043f\u0440\u043e\u0433\u043e\u043d\u0430. \u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u0432\u0435\u0449\u0438, \u0430 \u043d\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0438 \u043e\u043f\u0440\u0430\u0432\u0434\u044b\u0432\u0430\u044e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0435.<\/p>\n<h3>\u0422\u0435\u0441\u0442 \u21164. \u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 UI<\/h3>\n<p>\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u043d\u0430 <code>\/ui<\/code>: \u0432\u0432\u0435\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441, \u043d\u0430\u0436\u0430\u0442\u044c \u00ab\u041d\u0430\u0439\u0442\u0438\u00bb, \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0445 20 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a \u0438 \u0436\u0430\u0442\u044c \u00ab\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0435\u0449\u0451\u00bb, \u043f\u043e\u043a\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u043d\u0435\u0442 \u2014 \u043f\u044f\u0442\u044c \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u043e\u043a, \u0441\u0442\u043e \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a. \u041a\u0430\u0436\u0434\u0430\u044f \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u043a\u0430 \u2014 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a API \u043f\u043b\u044e\u0441 300 \u043c\u0441 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 \u0442\u044f\u0436\u0451\u043b\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u041f\u043e\u043a\u0430 \u0438\u0434\u0451\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u043a\u043d\u043e\u043f\u043a\u0430 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u044e\u0442 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438.<\/p>\n<p>\u0421\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0442\u0443\u0442 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 API. \u0422\u0435\u0441\u0442 \u043f\u0440\u043e \u0437\u0430\u0434\u0430\u0447\u0438, \u0433\u0434\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438 \u0435\u0441\u0442\u044c \u0446\u0435\u043b\u044c: e2e-\u0442\u0435\u0441\u0442\u044b, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0444\u043e\u0440\u043c, \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u044b.<\/p>\n<h4>Selenium<\/h4>\n<pre><code class=\"python\">wait = WebDriverWait(driver, 10)driver.get(UI_URL)driver.find_element(By.ID, \"q\").send_keys(\"\u0442\u043e\u0432\u0430\u0440\")driver.find_element(By.ID, \"search\").click()wait.until(EC.presence_of_element_located(cards))while driver.find_elements(By.ID, \"load-more\"):    before = len(driver.find_elements(*cards))    wait.until(EC.element_to_be_clickable((By.ID, \"load-more\"))).click()    wait.until(lambda d: len(d.find_elements(*cards)) &gt; before)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>find_element<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>WebElement<\/code> \u2014 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0443\u0437\u0435\u043b DOM. <code>find_elements<\/code> \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0434\u043e\u0431\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u00ab\u043a\u043d\u043e\u043f\u043a\u0430 \u0435\u0449\u0451 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435?\u00bb. \u0412\u0441\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e, \u0437\u0430\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u043d\u043e, \u0447\u0435\u0433\u043e \u0436\u0434\u0451\u0442 \u043a\u043e\u0434.<\/p>\n<p>\u0410 \u0432\u043e\u0442 \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0438 \u043a\u043b\u0438\u043a\u0430\u0442\u044c \u043f\u043e \u043d\u0435\u0439 \u0432 \u0446\u0438\u043a\u043b\u0435:<\/p>\n<pre><code class=\"python\">button = wait.until(EC.element_to_be_clickable((By.ID, \"load-more\")))for _ in range(4):    button.click()    wait.until(EC.element_to_be_clickable((By.ID, \"load-more\")))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<pre><code>selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference:stale element not found in the current frame<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043a\u043b\u0438\u043a \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442, \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0430\u0434\u0430\u0435\u0442: \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0438\u043b\u043e \u0441\u0442\u0430\u0440\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u043e \u043d\u043e\u0432\u0443\u044e \u0441 \u0442\u0435\u043c \u0436\u0435 <code>id<\/code>. <code>WebElement<\/code> \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b, \u0438 \u0442\u043e, \u0447\u0442\u043e \u0440\u044f\u0434\u043e\u043c \u0435\u0441\u0442\u044c \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0436\u0435 \u043a\u043d\u043e\u043f\u043a\u0430, \u0435\u043c\u0443 \u043d\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442. \u042d\u0442\u043e \u043d\u0435 \u0431\u0430\u0433, \u0430 \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u00ab\u044d\u043b\u0435\u043c\u0435\u043d\u0442 = \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0443\u0437\u0435\u043b\u00bb, \u043d\u043e \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0430 \u0434\u0430\u0451\u0442 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<h4>Playwright<\/h4>\n<pre><code class=\"python\">page.goto(UI_URL)page.locator(\"#q\").fill(\"\u0442\u043e\u0432\u0430\u0440\")page.locator(\"#search\").click()cards = page.locator(\"article.product\")more = page.locator(\"#load-more\")expect(cards).to_have_count(20)while more.count():    before = cards.count()    more.click()    expect(cards).not_to_have_count(before)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>more<\/code> \u2014 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430, \u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u00ab\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 <code>id=load-more<\/code>\u00bb. \u041f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u043a\u043b\u0438\u043a\u043e\u043c Playwright \u0438\u0449\u0435\u0442 \u0435\u0433\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u0438 \u0436\u0434\u0451\u0442, \u043f\u043e\u043a\u0430 \u043e\u043d \u0441\u0442\u0430\u043d\u0435\u0442 \u0432\u0438\u0434\u0438\u043c\u044b\u043c, \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0438 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u044b\u043c. <code>expect(...)<\/code> \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043e \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430. \u041f\u0440\u0438\u0451\u043c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u043c\u0430\u043b\u0441\u044f Selenium, \u2014 \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043d\u043e\u043f\u043a\u0438 \u043d\u0430 \u0432\u0441\u0435 \u043a\u043b\u0438\u043a\u0438 \u2014 \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<h4>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h4>\n<p>\u00ab4 \u0441\u0435\u0441\u0441\u0438\u0438\u00bb \u2014 \u0442\u043e\u0442 \u0436\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0447\u0435\u0442\u044b\u0440\u0435 \u0440\u0430\u0437\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u0441 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 cookies \u0438 storage.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f, \u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0430\u043c\u044f\u0442\u044c, \u041c\u0411<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Selenium, \u043e\u0434\u043d\u0430 \u0441\u0435\u0441\u0441\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">~5,8<\/p>\n<\/td>\n<td>\n<p align=\"left\">~600<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u0441\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Selenium, \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0439 <code>WebElement<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Playwright, \u043e\u0434\u043d\u0430 \u0441\u0435\u0441\u0441\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">~5,0<\/p>\n<\/td>\n<td>\n<p align=\"left\">~360<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u0441\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Selenium, 4 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">~8<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2200<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u0441\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Playwright, 4 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">~5,0<\/p>\n<\/td>\n<td>\n<p align=\"left\">~640<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u0441\u0435<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 Playwright \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u2014 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c Selenium \u0442\u0440\u0430\u0442\u0438\u0442 \u043d\u0430 <code>quit()<\/code>. \u0422\u043e \u0435\u0441\u0442\u044c \u0441\u0430\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 Selenium \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b \u0434\u0430\u0436\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u042f \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u043b\u0430 \u0448\u0430\u0433\u0438 Playwright \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438: \u043a\u0430\u0436\u0434\u0430\u044f \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 <code>expect<\/code> \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430 \u043e\u043a\u043e\u043b\u043e 0,85 \u0441, \u0445\u043e\u0442\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0430\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0437\u0430 0,35. \u0412 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 Playwright \u0437\u0430\u0448\u0438\u0442\u0430 \u043b\u0435\u0441\u0442\u043d\u0438\u0446\u0430 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432 \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u2014 100, 250, 500 \u0438 1000 \u043c\u0441, \u0438 \u0432\u0440\u0435\u043c\u044f \u0442\u043e\u0447\u043d\u043e \u0432 \u043d\u0435\u0451 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f: \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043b\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435. \u0423 Selenium \u0448\u0430\u0433 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0439, \u043f\u043e\u043b\u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0438 \u0437\u0434\u0435\u0441\u044c \u043e\u043d \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0443\u0434\u0430\u0447\u043d\u0435\u0435. \u0421 <code>page.wait_for_function()<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>expect<\/code> \u043f\u043e\u0438\u0441\u043a \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b \u0432\u0434\u0432\u043e\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u044d\u0442\u043e \u043d\u0435\u0432\u0430\u0436\u043d\u043e, \u0432 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0437 \u0441\u043e\u0442\u0435\u043d \u0448\u0430\u0433\u043e\u0432 \u2014 \u0432\u043f\u043e\u043b\u043d\u0435. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0434\u0430\u044e\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430 \u043d\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432\u0438\u0434\u043d\u0430 \u043d\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0441\u0441\u0438\u044f\u0445. Selenium \u0434\u043b\u044f \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 chromedriver \u0438 \u0447\u0435\u0442\u044b\u0440\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430: \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0432\u0443\u0445 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u0440\u043e\u0441 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. Playwright \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 <code>browser.new_context()<\/code> \u0432 \u043e\u0434\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u2014 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0438 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 cookies \u0438 localStorage, \u043a\u0430\u043a \u043e\u043a\u043d\u0430 \u0438\u043d\u043a\u043e\u0433\u043d\u0438\u0442\u043e. \u0412\u0440\u0435\u043c\u044f \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u0435\u043c \u0436\u0435, \u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0443\u0448\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0435\u043c \u0432\u0434\u0432\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043d\u0430 \u043e\u0434\u043d\u0443 \u0441\u0435\u0441\u0441\u0438\u044e.<\/p>\n<p>\u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0447\u0443\u0442\u044c \u043d\u0435 \u0443\u043f\u0443\u0441\u0442\u0438\u043b\u0430. \u0412 headless-\u0440\u0435\u0436\u0438\u043c\u0435 Playwright \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 Chromium, \u0430 \u043e\u0431\u043b\u0435\u0433\u0447\u0451\u043d\u043d\u0443\u044e \u0441\u0431\u043e\u0440\u043a\u0443 <code>chromium_headless_shell<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a Selenium \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c Chrome. \u041a\u043e\u0433\u0434\u0430 \u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0430 Playwright \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u043c Chrome (<code>launch(channel=\"chrome\")<\/code>), \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u043d \u0441\u044a\u0435\u043b \u0434\u0430\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c Selenium. \u0422\u0430\u043a \u0447\u0442\u043e \u0432\u044b\u0438\u0433\u0440\u044b\u0448 Playwright \u043f\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 \u043c\u043e\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 \u2014 \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u0437\u0430\u0441\u043b\u0443\u0433\u0430 \u0441\u0431\u043e\u0440\u043a\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u0430 \u043d\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0434\u0435\u0432\u0430\u0435\u0442\u0441\u044f: \u043e\u043d\u043e \u043f\u0440\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443.<\/p>\n<h4>Selenium \u0438 Playwright \u043f\u043e \u043f\u0443\u043d\u043a\u0442\u0430\u043c<\/h4>\n<p>\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u2014 \u043d\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0435\u043c \u043e\u043d\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f. \u0412\u043e\u0442 \u0441 \u0447\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0448\u044c\u0441\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 (selenium 4.50, playwright 1.63):<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\n<\/th>\n<th>\n<p align=\"left\">Selenium<\/p>\n<\/th>\n<th>\n<p align=\"left\">Playwright<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u044f\u0432\u043d\u044b\u0435 (<code>WebDriverWait<\/code>) \u0438\u043b\u0438 \u043d\u0435\u044f\u0432\u043d\u044b\u0435 (<code>implicitly_wait<\/code>), \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0436\u0434\u0443\u0442 \u0441\u0430\u043c\u0438, <code>expect<\/code> \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442; <code>all()<\/code> \u0438 <code>count()<\/code> \u043d\u0435 \u0436\u0434\u0443\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u042d\u043b\u0435\u043c\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>WebElement<\/code> \u2014 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0443\u0437\u0435\u043b, \u043c\u043e\u0436\u0435\u0442 \u0443\u0441\u0442\u0430\u0440\u0435\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>Locator<\/code> \u2014 \u0437\u0430\u043f\u0440\u043e\u0441, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u0437\u043e\u043b\u044f\u0446\u0438\u044f \u0441\u0435\u0441\u0441\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043e\u0434\u0438\u043d \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u2014 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0444\u0438\u043b\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043c\u043d\u043e\u0433\u043e <code>new_context()<\/code> \u0432 \u043e\u0434\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0441\u0435\u0442\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">WebDriver BiDi (<code>enable_bidi<\/code>), \u0434\u043b\u044f Chromium \u0435\u0449\u0451 CDP<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>page.route()<\/code>, <code>expect_response()<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Async API<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442, \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u043b\u0438 Grid<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0435\u0441\u0442\u044c, \u043d\u0430\u0440\u044f\u0434\u0443 \u0441 sync<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u0440\u0430\u0443\u0437\u0435\u0440\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 Chrome, Edge, Firefox, Safari<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0432\u043e\u0438 Chromium, Firefox, WebKit \u043f\u043b\u044e\u0441 Chrome\/Edge; Safari \u043d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">iframe<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>switch_to.frame()<\/code>, \u043f\u043e\u0442\u043e\u043c \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>frame_locator()<\/code> \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>send_keys(path)<\/code>; \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>set_input_files()<\/code>, <code>expect_download()<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Cookies \u0438 storage<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>get_cookies()<\/code> \/ <code>add_cookie()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>storage_state()<\/code> \u0432 \u0444\u0430\u0439\u043b \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0442\u043b\u0430\u0434\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043b\u043e\u0433\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">Trace Viewer, <code>playwright codegen<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">Grid, \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0444\u0435\u0440\u043c\u044b, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 W3C, \u043c\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043e\u0434\u0438\u043d \u0432\u0435\u043d\u0434\u043e\u0440, \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0447\u0435\u0440\u0435\u0437 <code>connect()<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0423 Selenium \u0435\u0441\u0442\u044c \u0441\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043c\u043e\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0435 \u043f\u0440\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c: \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Safari, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 W3C \u0438 Grid, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f\u0445 \u0443\u0436\u0435 \u0440\u0430\u0437\u0432\u0451\u0440\u043d\u0443\u0442. \u0418 \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 Selenium \u0438\u0437 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0439 \u043f\u044f\u0442\u0438\u043b\u0435\u0442\u043d\u0435\u0439 \u0434\u0430\u0432\u043d\u043e\u0441\u0442\u0438: \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0430\u0434\u043e \u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438, \u0430 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0441\u0435\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 BiDi \u0435\u0441\u0442\u044c \u0438 \u0432 Python. \u041d\u043e \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043b\u043e\u043a\u0430\u0442\u043e\u0440\u044b \u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u044b Playwright \u0441\u043d\u0438\u043c\u0430\u044e\u0442 \u0446\u0435\u043b\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0438 \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u0435\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u0432 \u0434\u043e\u043b\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<h3>BeautifulSoup, lxml \u0438 selectolax \u2014 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c\u0438 \u0442\u043e\u043d\u0435\u0442 \u0432 \u0441\u0435\u0442\u0438 \u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430. \u0427\u0442\u043e\u0431\u044b \u0435\u0451 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u044f \u0443\u0431\u0440\u0430\u043b\u0430 \u0441\u0435\u0442\u044c \u0432\u043e\u0432\u0441\u0435: \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 HTML \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0440\u0435\u0436\u043d\u044f\u044f.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0430\u0440\u0441\u0435\u0440<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u043c\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BeautifulSoup + <code>html.parser<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">~22<\/p>\n<\/td>\n<td>\n<p align=\"left\">CSS, \u043c\u0435\u0442\u043e\u0434\u044b <code>find<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BeautifulSoup + <code>lxml<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">~16<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e \u0436\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">parsel<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2<\/p>\n<\/td>\n<td>\n<p align=\"left\">CSS \u0438 XPath<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">lxml<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2<\/p>\n<\/td>\n<td>\n<p align=\"left\">XPath, CSS \u0447\u0435\u0440\u0435\u0437 cssselect<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">selectolax<\/p>\n<\/td>\n<td>\n<p align=\"left\">~1<\/p>\n<\/td>\n<td>\n<p align=\"left\">CSS<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>BeautifulSoup \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 lxml \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0438 \u0440\u0430\u0437 \u0432 \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 selectolax. \u041f\u0440\u0438\u0447\u0451\u043c \u0437\u0430\u043c\u0435\u043d\u0430 <code>html.parser<\/code> \u043d\u0430 <code>lxml<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441\u043b\u0430\u0431\u043e: \u0441\u0430\u043c lxml \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u043e \u043f\u043e\u0442\u043e\u043c BeautifulSoup \u0441\u0442\u0440\u043e\u0438\u0442 \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e Python-\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0438 \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0434\u043e\u0440\u043e\u0433\u043e\u0435. lxml \u0438 selectolax \u0434\u0435\u0440\u0436\u0430\u0442 \u0434\u0435\u0440\u0435\u0432\u043e \u0432 C \u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 Python-\u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0443\u0437\u043b\u043e\u0432, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u043b\u0438\u0441\u044c.<\/p>\n<p>\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u0435 \u0446\u0438\u0444\u0440\u044b \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u043c\u0430\u0448\u0438\u043d\u044b \u2014 \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0438\u0436\u0435, \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e \u043f\u043e\u043b\u043e\u043c\u043a\u0438. \u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u043c \u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442:<\/p>\n<ul>\n<li>\n<p><strong>\u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0438 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/strong> \u2014 \u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u043e, \u0447\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0444\u043e\u043d\u0435 \u0441\u0435\u0442\u0438, \u0430 \u0443 BeautifulSoup \u043b\u0443\u0447\u0448\u0430\u044f \u0442\u0435\u0440\u043f\u0438\u043c\u043e\u0441\u0442\u044c \u043a \u043a\u0440\u0438\u0432\u043e\u043c\u0443 HTML \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><strong>\u0442\u044b\u0441\u044f\u0447\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0441 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e<\/strong> \u2014 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u0442\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0451\u0439 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432, \u0430 \u0432 asyncio \u043e\u043d \u0435\u0449\u0451 \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 event loop;<\/p>\n<\/li>\n<li>\n<p><strong>\u043d\u0443\u0436\u0435\u043d XPath<\/strong> \u2014 lxml \u0438\u043b\u0438 parsel, \u0432 selectolax \u0435\u0433\u043e \u043d\u0435\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0435\u0449\u0451: \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u00abBeautifulSoup \u043f\u0440\u043e\u0442\u0438\u0432 Selenium\u00bb \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430. HTML \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 (<code>page.content()<\/code> \u0438\u043b\u0438 <code>driver.page_source<\/code>) \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0434\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u043c\u0443 \u0438\u0437 \u044d\u0442\u0438\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u0440\u043e\u0436\u0435<\/h3>\n<p>\u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0435\u0441\u043b\u0438 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0423 HTTP-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043e\u043d \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439:<\/p>\n<pre><code>Python-\u043f\u0440\u043e\u0446\u0435\u0441\u0441  \u2192 TCP\/TLS-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 (\u0438\u0437 \u043f\u0443\u043b\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c Session\/Client)  \u2192 \u043e\u0434\u0438\u043d HTTP-\u043e\u0442\u0432\u0435\u0442 (HTML \u0438\u043b\u0438 JSON)  \u2192 \u043f\u0430\u0440\u0441\u0435\u0440<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0423 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u2014 \u0434\u043b\u0438\u043d\u043d\u044b\u0439, \u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u0432 \u043d\u0451\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e:<\/p>\n<pre><code>Python-\u043f\u0440\u043e\u0446\u0435\u0441\u0441  \u2192 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438      Selenium:   HTTP \u2192 chromedriver \u2192 Chrome      Playwright: \u043f\u0430\u0439\u043f \u2192 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u2192 CDP \u2192 Chromium  \u2192 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430: \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439, \u0441\u0435\u0442\u044c, GPU, \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u044b  \u2192 HTML \u0438 \u0432\u0441\u0435 \u043f\u043e\u0434\u0440\u0435\u0441\u0443\u0440\u0441\u044b: CSS, JS, \u0448\u0440\u0438\u0444\u0442\u044b, \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438  \u2192 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 JavaScript  \u2192 DOM \u2192 \u0441\u0442\u0438\u043b\u0438 \u2192 layout \u2192 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430  \u2192 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0441\u044e\u0434\u0430 \u0442\u0440\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432: \u0441\u0442\u0430\u0440\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435, \u043b\u0438\u0448\u043d\u044f\u044f \u0434\u043b\u044f \u043d\u0430\u0441 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 (layout, \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u0448\u0440\u0438\u0444\u0442\u044b) \u0438 \u043c\u0435\u0436\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0438\u0437 Python.<\/p>\n<p>\u0411\u0440\u0430\u0443\u0437\u0435\u0440 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043b\u043e\u0445\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c. \u0412\u0441\u0451 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u2014 \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0440\u0430\u0434\u0438 \u0447\u0435\u0433\u043e \u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442, \u043a\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0447\u0443\u0436\u043e\u0433\u043e JavaScript. \u0412\u043e\u043f\u0440\u043e\u0441 \u043b\u0438\u0448\u044c \u0432 \u0442\u043e\u043c, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u044d\u0442\u043e \u0432 \u0432\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e, \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0435\u0437\u0430\u0442\u044c: \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0430 \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0438 \u0448\u0440\u0438\u0444\u0442\u044b \u0447\u0435\u0440\u0435\u0437 <code>page.route()<\/code> \u0438 \u0437\u0430\u0431\u0438\u0440\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0434\u043d\u0438\u043c JS-\u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u043e\u0442\u043d\u0438 \u043c\u0435\u043b\u043a\u0438\u0445.<\/p>\n<h3>\u041e \u0447\u0451\u043c \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h3>\n<p>\u0421\u0442\u0435\u043d\u0434 \u0443 \u043c\u0435\u043d\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439, \u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u0447\u0443\u0436\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440. \u041a\u043e\u0440\u043e\u0442\u043a\u043e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<p><strong>robots.txt \u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0441\u0430\u0439\u0442\u0430.<\/strong> robots.txt \u2014 \u043d\u0435 \u0437\u0430\u043a\u043e\u043d \u0438 \u043d\u0435 \u0437\u0430\u0449\u0438\u0442\u0430, \u0430 \u044f\u0432\u043d\u043e \u0432\u044b\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 (<a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9309\" rel=\"noopener nofollow\">RFC 9309<\/a>). \u0412 Scrapy \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e <code>ROBOTSTXT_OBEY = False<\/code>, \u043d\u043e \u0448\u0430\u0431\u043b\u043e\u043d <code>scrapy startproject<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0435\u0433\u043e \u2014 \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430. \u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0441\u0430\u0439\u0442\u0430 \u0438 \u0437\u0430\u043a\u043e\u043d\u044b \u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0430\u0436\u043d\u0435\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0430 \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e API \u0440\u0430\u0437\u0443\u043c\u043d\u0435\u0435 \u0432\u0437\u044f\u0442\u044c \u0435\u0433\u043e.<\/p>\n<p><strong>\u041b\u0438\u043c\u0438\u0442\u044b \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438.<\/strong> \u0428\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Scrapy \u0441\u0442\u0430\u0432\u0438\u0442 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u043d\u0430 \u0434\u043e\u043c\u0435\u043d. \u042d\u0442\u043e \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043a\u0438 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0446\u0438\u0444\u0440 \u0438\u0437 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430, \u0438 \u0442\u0430\u043a \u0438 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c: \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0443\u043c\u0435\u0441\u0442\u043d\u0430 \u043f\u0440\u043e\u0442\u0438\u0432 \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u043b\u0438 API \u0441 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u043b\u0438\u043c\u0438\u0442\u0430\u043c\u0438. \u041e\u0442\u0432\u0435\u0442 429 \u2014 \u0441\u0438\u0433\u043d\u0430\u043b \u043f\u0440\u0438\u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c, \u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>Retry-After<\/code> \u0441\u0442\u043e\u0438\u0442 \u0443\u0432\u0430\u0436\u0430\u0442\u044c; urllib3 <code>Retry<\/code> \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0441\u0430\u043c.<\/p>\n<p><strong>\u0422\u0430\u0439\u043c\u0430\u0443\u0442\u044b.<\/strong> requests \u0431\u0435\u0437 <code>timeout<\/code> \u0436\u0434\u0451\u0442 \u0432\u0435\u0447\u043d\u043e. \u0423 httpx \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 5 \u0441\u0435\u043a\u0443\u043d\u0434, \u0443 Scrapy \u2014 \u0442\u0440\u0438 \u043c\u0438\u043d\u0443\u0442\u044b. \u041e\u0434\u0438\u043d \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0435\u0437 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043d\u043e\u0447\u043d\u043e\u0439 \u0441\u0431\u043e\u0440.<\/p>\n<p><strong>User-Agent.<\/strong> \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e requests \u0438 Scrapy \u0447\u0435\u0441\u0442\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0432\u043e\u0438\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438. \u0425\u043e\u0440\u043e\u0448\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u2014 UA \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u043e\u0442\u0430 \u0438 \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u043c\u043e\u0433 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0430\u043c, \u0430 \u043d\u0435 \u0441\u0440\u0430\u0437\u0443 \u0431\u0430\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u0441\u0435\u0442\u044c.<\/p>\n<p><strong>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0442\u043e\u043a\u0435\u043d\u044b.<\/strong> \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430, \u0443\u0434\u043e\u0431\u043d\u043e \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 (\u0432 Playwright \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c <code>storage_state<\/code>), \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0445\u043e\u0434\u0438\u0442\u044c HTTP-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0441 \u0442\u0435\u043c\u0438 \u0436\u0435 cookies. CSRF-\u0442\u043e\u043a\u0435\u043d\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b; \u0435\u0441\u043b\u0438 \u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 JS, \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043e\u0432\u043e\u0434 \u0432 \u043f\u043e\u043b\u044c\u0437\u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430.<\/p>\n<p><strong>\u041f\u0440\u043e\u043a\u0441\u0438<\/strong> \u2014 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c: \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0441\u0435\u0442\u044c, \u0440\u0435\u0433\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0430\u0439\u0442\u0430, \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 IP \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u043e\u0431\u043b\u0430\u043a\u0430. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0438\u0445 \u0432\u0441\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p><strong>CAPTCHA \u0438 \u0430\u043d\u0442\u0438\u0431\u043e\u0442-\u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/strong> \u042d\u0442\u043e \u043d\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u0430 \u043f\u0440\u044f\u043c\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 \u0441\u0430\u0439\u0442\u0430: \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0441\u044e\u0434\u0430 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d. \u042f \u0441\u0447\u0438\u0442\u0430\u044e \u044d\u0442\u043e \u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u043e\u0441\u0442\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0438 \u043e\u0431\u0445\u043e\u0434 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e. \u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u2014 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 API, \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u0441 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c \u0438\u043b\u0438 \u043e\u0442\u043a\u0430\u0437 \u043e\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430.<\/p>\n<h3>\u0427\u0442\u043e \u0441\u043b\u043e\u043c\u0430\u043b\u043e\u0441\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u0441\u0442\u043e\u0432<\/h3>\n<p>\u0412\u0441\u0451 \u043d\u0438\u0436\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043f\u043e\u043a\u0430 \u044f \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0430 \u0441\u0442\u0430\u0442\u044c\u044e.<\/p>\n<p><strong>\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0435\u0440\u0438\u044f \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043c\u0443\u0441\u043e\u0440\u043e\u043c.<\/strong> \u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430 \u0446\u0438\u0444\u0440\u044b \u0432 3\u20134 \u0440\u0430\u0437\u0430 \u043b\u0443\u0447\u0448\u0435. \u0412 \u0436\u0443\u0440\u043d\u0430\u043b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 Windows \u043d\u0430\u0448\u043b\u0430\u0441\u044c \u0441\u043c\u0435\u043d\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043f\u0438\u0442\u0430\u043d\u0438\u044f \u0440\u043e\u0432\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0438\u044f\u043c\u0438: \u043f\u0435\u0440\u0432\u0430\u044f \u0448\u043b\u0430 \u043e\u0442 \u0431\u0430\u0442\u0430\u0440\u0435\u0438. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0432\u0441\u0451 \u043e\u0442 \u0441\u0435\u0442\u0438, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438 \u0446\u0438\u0444\u0440\u044b. \u041b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u043e, \u0447\u0442\u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 \u00ab\u0431\u0430\u0442\u0430\u0440\u0435\u0439\u043d\u043e\u0439\u00bb \u0441\u0435\u0440\u0438\u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c. \u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u043c \u0446\u0438\u0444\u0440\u0430\u043c \u0441 \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u0430 \u0441\u0442\u043e\u0438\u0442 \u0432\u0435\u0440\u0438\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u043c.<\/p>\n<p><strong>Git Bash \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b URL.<\/strong> \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>\/flaky\/catalog<\/code> \u0432 Git Bash \u043d\u0430 Windows \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0441\u044f \u0432 <code>C:\\Program Files\\Git\\flaky\\catalog<\/code> \u2014 MSYS \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 POSIX-\u043f\u0443\u0442\u044c. requests \u0438 httpx \u0447\u0435\u0441\u0442\u043d\u043e \u0443\u043f\u0430\u043b\u0438 \u0441 <code>InvalidURL<\/code>. \u0410 Scrapy \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c 0, \u0441\u043e\u0431\u0440\u0430\u0432 \u043d\u043e\u043b\u044c \u0442\u043e\u0432\u0430\u0440\u043e\u0432, \u0438 \u0431\u0435\u0437 \u0435\u0434\u0438\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 <code>LOG_LEVEL=WARNING<\/code>. \u041c\u043e\u0440\u0430\u043b\u044c: \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u0434\u043e \u043d\u0435 \u043a\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0430, \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p><strong>lambda \u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u0435 Scrapy \u043c\u043e\u043b\u0447\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/strong> <code>crawler.signals.connect(lambda item, **kw: items.append(item), ...)<\/code> \u0434\u0430\u043b \u043d\u043e\u043b\u044c \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a. Scrapy \u0445\u0440\u0430\u043d\u0438\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043f\u043e \u0441\u043b\u0430\u0431\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435, \u0438 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f, \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430. \u041f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 feed export.<\/p>\n<p>\u0415\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439 \u044f \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u043d\u044f\u043b\u0430 \u0437\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u0442\u0435\u043d\u0434\u0430: \u0434\u0432\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0432 <code>driver.quit()<\/code>, \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 <code>httpx.Client()<\/code>, \u0434\u0435\u0433\u0440\u0430\u0434\u0430\u0446\u0438\u044e \u043f\u0443\u043b\u0430 httpcore, \u043b\u0435\u0441\u0442\u043d\u0438\u0446\u0443 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432 \u0432 <code>expect<\/code> \u0438 \u043e\u0431\u043b\u0435\u0433\u0447\u0451\u043d\u043d\u0443\u044e \u0441\u0431\u043e\u0440\u043a\u0443 Chromium. \u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0440\u0430\u0437\u0431\u043e\u0440 \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u0438\u043b\u0438 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0435\u0440 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<\/p>\n<h3>\u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430<\/h3>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0422\u0438\u043f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u0442 JS<\/p>\n<\/th>\n<th>\n<p align=\"left\">Async<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c (\u043f\u043e \u043c\u043e\u0438\u043c \u0437\u0430\u043c\u0435\u0440\u0430\u043c)<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0430\u043c\u044f\u0442\u044c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0440\u043e\u0433 \u0432\u0445\u043e\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041a\u043e\u0433\u0434\u0430 \u0431\u0440\u0430\u0442\u044c<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">requests + BeautifulSoup<\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP-\u043a\u043b\u0438\u0435\u043d\u0442 + \u043f\u0430\u0440\u0441\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442, \u043d\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0430\u043c\u044b\u0439 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442; \u0432 \u043f\u043e\u0442\u043e\u043a\u0430\u0445 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440.\/\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0440\u0435\u0434\u043d\u0435\u0435: \u043f\u043e\u0442\u043e\u043a\u0438, \u0440\u0435\u0442\u0440\u0430\u0438 \u0447\u0435\u0440\u0435\u0437 urllib3<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0438\u0437\u043a\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 HTML, \u0434\u043e \u0441\u043e\u0442\u0435\u043d \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">httpx + selectolax<\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP-\u043a\u043b\u0438\u0435\u043d\u0442 + \u043f\u0430\u0440\u0441\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433; \u043f\u0443\u043b \u043f\u0440\u043e\u0441\u0435\u0434\u0430\u0435\u0442 \u043d\u0430 \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0440\u0435\u0434\u043d\u0435\u0435, \u0432\u0441\u0451 \u0440\u0443\u043a\u0430\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0438\u0437\u043a\u0438\u0439 \u0434\u043b\u044f sync, \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0434\u043b\u044f async<\/p>\n<\/td>\n<td>\n<p align=\"left\">JSON API, async-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, HTTP\/2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Scrapy<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442 (\u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043e\u043a\u043e\u043b\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430 \u0441\u0442\u0430\u0440\u0442, ~100 \u0441\u0442\u0440.\/\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u044b\u0441\u043e\u043a\u043e\u0435: \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043b\u0438\u043c\u0438\u0442\u044b \u043f\u043e \u0434\u043e\u043c\u0435\u043d\u0430\u043c, \u0440\u0435\u0442\u0440\u0430\u0438, AutoThrottle<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0440\u0435\u0434\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Selenium<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, ~2 \u0441 \u043d\u0430 <code>quit()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u044b\u0441\u043e\u043a\u0430\u044f, \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0430 \u0441\u0435\u0441\u0441\u0438\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u043b\u0438 Grid<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0440\u0435\u0434\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0433\u043e\u0442\u043e\u0432\u044b\u0439 Grid, \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Safari, \u043c\u043d\u043e\u0433\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Playwright<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043e\u043a\u043e\u043b\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0432\u044b\u0441\u043e\u043a\u0430\u044f, \u043d\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u044b \u0434\u0435\u043b\u044f\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u044b, async<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0441\u0440\u0435\u0434\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">JS-\u0441\u0430\u0439\u0442\u044b \u0431\u0435\u0437 \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e API, \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u0439 UI, \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>\u041a\u0430\u043a \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442<\/h3>\n<p>\u041f\u043e \u0438\u0442\u043e\u0433\u0430\u043c \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u00ab\u0435\u0441\u0442\u044c \u043b\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 JavaScript\u00bb, \u0430 \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u00ab\u0433\u0434\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\u00bb.<\/p>\n<pre><code>\u0415\u0441\u0442\u044c \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 API \u0438\u043b\u0438 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0430?\u2502\u251c\u2500 \u0414\u0430 \u2192 \u0431\u0435\u0440\u0438\u0442\u0435 \u0435\u0433\u043e, \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d\u2502\u2514\u2500 \u041d\u0435\u0442    \u2502    \u0414\u0430\u043d\u043d\u044b\u0435 \u0435\u0441\u0442\u044c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c HTML (View Source, \u0430 \u043d\u0435 Elements)?    \u2502    \u251c\u2500 \u0414\u0430    \u2502   \u251c\u2500 \u0434\u0435\u0441\u044f\u0442\u043a\u0438\u2013\u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446          \u2192 requests + BeautifulSoup\/lxml    \u2502   \u251c\u2500 \u0442\u044b\u0441\u044f\u0447\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u043e\u0434\u0438\u043d \u0441\u0430\u0439\u0442, \u0440\u0430\u0437\u043e\u0432\u043e \u2192 \u043f\u043e\u0442\u043e\u043a\u0438 + selectolax\/lxml    \u2502   \u2514\u2500 \u043c\u043d\u043e\u0433\u043e \u0441\u0430\u0439\u0442\u043e\u0432, \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e,    \u2502      \u043d\u0443\u0436\u043d\u044b \u0440\u0435\u0442\u0440\u0430\u0438 \u0438 \u043b\u0438\u043c\u0438\u0442\u044b \u043f\u043e \u0434\u043e\u043c\u0435\u043d\u0443  \u2192 Scrapy    \u2502    \u2514\u2500 \u041d\u0435\u0442, \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0438\u0441\u0443\u0435\u0442 JavaScript        \u2502        \u0412 Network \u0432\u0438\u0434\u0435\u043d XHR\/fetch\/GraphQL \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438?        \u2502        \u251c\u2500 \u0414\u0430, \u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 cURL        \u2502     \u2192 HTTP-\u043a\u043b\u0438\u0435\u043d\u0442 \u0438 JSON        \u2502        \u251c\u2500 \u0414\u0430, \u043d\u043e \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043a\u0435\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 JS        \u2502     \u2192 Playwright + expect_response,        \u2502       \u0438\u043b\u0438 \u0432\u0437\u044f\u0442\u044c cookies \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 HTTP-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c        \u2502        \u2514\u2500 \u041d\u0435\u0442, \u0438\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 (\u0444\u043e\u0440\u043c\u044b, \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u044b, e2e)              \u251c\u2500 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 \u2192 Playwright              \u2514\u2500 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c Selenium Grid, \u043d\u0443\u0436\u0435\u043d Safari \u2192 Selenium<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h3>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430<\/h3>\n<p>\u042d\u0442\u043e \u0437\u0430\u043c\u0435\u0440\u044b \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u0435 \u0441 Windows, \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0445 \u043d\u0430 \u0441\u0432\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0443\u0436\u043d\u043e \u0441 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<ul>\n<li>\n<p><strong>\u0421\u0435\u0442\u044c.<\/strong> \u0421\u0435\u0440\u0432\u0435\u0440 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435, \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u044f, \u0431\u0435\u0437 TLS \u0438 \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0441\u0430\u0439\u0442\u0430. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0438 \u0446\u0435\u043d\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u0438 \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u043e\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430 \u0431\u0443\u0434\u0443\u0442 \u0434\u0440\u0443\u0433\u0438\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u0435\u0440\u0432\u0435\u0440 \u0441\u0442\u0435\u043d\u0434\u0430<\/strong> \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u043c\u0430\u0448\u0438\u043d\u0435 \u0438 \u0434\u0435\u043b\u0438\u0442 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438 CPU.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/strong> \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0438 \u043f\u043e\u0447\u0442\u0438 \u0431\u0435\u0437 JavaScript. \u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0441 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432, \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u0438 \u0448\u0440\u0438\u0444\u0442\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u044b \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0434\u043e\u0440\u043e\u0436\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u0435\u0440\u0441\u0438\u0438.<\/strong> \u0414\u0432\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0432 <code>quit()<\/code> \u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0443\u043b\u0430 httpcore \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u0447\u0435\u0437\u043d\u0443\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0440\u0435\u043b\u0438\u0437\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0421.<\/strong> \u041d\u0430 Linux-\u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u043d\u043e \u044d\u0442\u043e \u044f \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b<\/strong> Firefox \u0438 WebKit, \u0440\u0435\u0436\u0438\u043c \u0441 \u043e\u043a\u043d\u043e\u043c, HTTP\/2, Selenium Grid \u0438 scrapy-playwright.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0427\u0442\u043e \u044f \u0432 \u0438\u0442\u043e\u0433\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430 \u0431\u044b<\/h3>\n<p><strong>\u0414\u043b\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 HTML-\u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/strong> \u2014 requests + BeautifulSoup: \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442 \u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043e\u0434. \u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0441\u0442\u0430\u043d\u0435\u0442 \u043c\u043d\u043e\u0433\u043e, \u043f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043f\u043e\u043c\u0435\u043d\u044f\u044e \u043f\u0430\u0440\u0441\u0435\u0440, \u0430 \u043d\u0435 HTTP-\u043a\u043b\u0438\u0435\u043d\u0442.<\/p>\n<p><strong>\u0414\u043b\u044f \u0440\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0430 \u0442\u044b\u0441\u044f\u0447 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0430\u0439\u0442\u0430<\/strong> \u2014 requests \u0432 \u043f\u0443\u043b\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441 <code>Retry<\/code>. \u041d\u0430 \u043c\u043e\u0451\u043c \u0441\u0442\u0435\u043d\u0434\u0435 \u044d\u0442\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 async httpx, \u0430 \u043a\u043e\u0434 \u043a\u043e\u0440\u043e\u0447\u0435. \u0412 \u0443\u0436\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u2014 httpx \u043f\u0440\u0438 \u0443\u043c\u0435\u0440\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 aiohttp, \u0435\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u043c\u043d\u043e\u0433\u043e.<\/p>\n<p><strong>\u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0430<\/strong> \u2014 Scrapy, \u0445\u043e\u0442\u044f \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u043e\u043d \u043d\u0435 \u0431\u044b\u043b. \u0420\u0435\u0442\u0440\u0430\u0438, \u043b\u0438\u043c\u0438\u0442\u044b \u043f\u043e \u0434\u043e\u043c\u0435\u043d\u0430\u043c, AutoThrottle \u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0441\u0442\u043e\u044f\u0442 \u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435, \u0438 \u043b\u0438\u0448\u043d\u0435\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p><strong>\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 SPA<\/strong> \u2014 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 Network, \u043f\u043e\u0442\u043e\u043c HTTP-\u043a\u043b\u0438\u0435\u043d\u0442 \u0438 JSON. \u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0442\u0435\u0441\u0442\u0435 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0432 \u0440\u0430\u0437\u044b \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u0438 \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u044d\u043a\u043e\u043d\u043e\u043c\u043d\u0435\u0435 \u043f\u043e \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p><strong>\u0414\u043b\u044f JavaScript-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438<\/strong> \u2014 Playwright. Selenium \u2014 \u0442\u0430\u043c, \u0433\u0434\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c Grid, \u043d\u0443\u0436\u0435\u043d \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Safari \u0438\u043b\u0438 \u043e\u0434\u0438\u043d \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f\u0437\u044b\u043a\u043e\u0432.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u2014 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0432\u044b\u0431\u043e\u0440 \u0441\u043e \u0441\u043b\u043e\u0432 \u00ab\u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u043f\u0430\u0440\u0441\u0435\u0440\u00bb. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0433\u0434\u0435 \u043b\u0435\u0436\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0435: \u0432 HTML, \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 API \u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u043e\u0441\u043b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041e\u0442 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0432 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0440\u0430\u0437, \u0430 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u044f \u0443\u0436\u0435 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u0430.<\/p>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u043c\u044b\u0441\u043b\u044c \u2014 \u043f\u0440\u043e \u0446\u0438\u0444\u0440\u044b. \u041f\u043e\u0447\u0442\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u043b\u0441\u044f \u043d\u0435 \u0442\u0435\u043c, \u0447\u0442\u043e \u00ab\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 X \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0430\u044f\u00bb, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043a\u043e\u0434\u0430: <code>sleep(1)<\/code> \u043f\u0440\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435, \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c \u043e\u043f\u0440\u043e\u0441\u0430, \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u0432 \u043f\u0443\u043b\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0443\u0436\u0438\u0435 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u044d\u0442\u043e\u0442, \u0441\u0442\u043e\u0438\u0442 \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430 \u0441\u0432\u043e\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u0438 \u0441\u0432\u043e\u0451\u043c \u0441\u0430\u0439\u0442\u0435. \u0421\u0442\u0435\u043d\u0434 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043b\u043e\u0436\u0435\u043d \u0446\u0435\u043b\u0438\u043a\u043e\u043c.<\/p>\n<p>\u0418 \u0442\u0440\u0435\u0442\u044c\u044f \u2014 \u043f\u0440\u043e \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c. \u041e\u043f\u0430\u0441\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043d\u0435 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b, \u0430 \u0442\u0435, \u0447\u0442\u043e \u0442\u0438\u0445\u043e \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043a\u043e\u0434\u043e\u043c 0: \u0431\u0435\u0437 \u0440\u0435\u0442\u0440\u0430\u0435\u0432, \u0431\u0435\u0437 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f, \u0441 lambda \u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u0435. \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u00ab\u0441\u043e\u0431\u0440\u0430\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c\u00bb \u043f\u043e\u043b\u0435\u0437\u043d\u0435\u0435 \u043b\u044e\u0431\u043e\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>\u0410 \u043a\u0430\u043a\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0432\u0430\u0441 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0441 HTTP-\u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u2014 \u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442?<\/p>\n<h3>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438<\/h3>\n<ul>\n<li>\n<p>PyPI: <a href=\"https:\/\/pypi.org\/project\/requests\/\" rel=\"noopener nofollow\">requests<\/a>, <a href=\"https:\/\/pypi.org\/project\/httpx\/\" rel=\"noopener nofollow\">httpx<\/a>, <a href=\"https:\/\/pypi.org\/project\/beautifulsoup4\/\" rel=\"noopener nofollow\">beautifulsoup4<\/a>, <a href=\"https:\/\/pypi.org\/project\/lxml\/\" rel=\"noopener nofollow\">lxml<\/a>, <a href=\"https:\/\/pypi.org\/project\/selectolax\/\" rel=\"noopener nofollow\">selectolax<\/a>, <a href=\"https:\/\/pypi.org\/project\/parsel\/\" rel=\"noopener nofollow\">parsel<\/a>, <a href=\"https:\/\/pypi.org\/project\/Scrapy\/\" rel=\"noopener nofollow\">Scrapy<\/a>, <a href=\"https:\/\/pypi.org\/project\/selenium\/\" rel=\"noopener nofollow\">selenium<\/a>, <a href=\"https:\/\/pypi.org\/project\/playwright\/\" rel=\"noopener nofollow\">playwright<\/a>, <a href=\"https:\/\/pypi.org\/project\/MechanicalSoup\/\" rel=\"noopener nofollow\">MechanicalSoup<\/a>, <a href=\"https:\/\/pypi.org\/project\/pyppeteer\/\" rel=\"noopener nofollow\">pyppeteer<\/a>, <a href=\"https:\/\/pypi.org\/project\/cloudscraper\/\" rel=\"noopener nofollow\">cloudscraper<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/pyppeteer\/pyppeteer\" rel=\"noopener nofollow\">pyppeteer README<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.scrapy.org\/en\/latest\/topics\/architecture.html\" rel=\"noopener nofollow\">Scrapy: Architecture overview<\/a>, <a href=\"https:\/\/docs.scrapy.org\/en\/latest\/topics\/settings.html\" rel=\"noopener nofollow\">Settings<\/a>, <a href=\"https:\/\/docs.scrapy.org\/en\/latest\/topics\/autothrottle.html\" rel=\"noopener nofollow\">AutoThrottle<\/a>, <a href=\"https:\/\/github.com\/scrapy\/scrapy\/blob\/master\/scrapy\/templates\/project\/module\/settings.py.tmpl\" rel=\"noopener nofollow\">\u0448\u0430\u0431\u043b\u043e\u043d settings.py<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/playwright.dev\/python\/docs\/actionability\" rel=\"noopener nofollow\">Playwright: Auto-waiting<\/a>, <a href=\"https:\/\/playwright.dev\/python\/docs\/locators\" rel=\"noopener nofollow\">Locators<\/a>, <a href=\"https:\/\/playwright.dev\/python\/docs\/browser-contexts\" rel=\"noopener nofollow\">Browser contexts<\/a>, <a href=\"https:\/\/playwright.dev\/python\/docs\/network\" rel=\"noopener nofollow\">Network<\/a>, <a href=\"https:\/\/playwright.dev\/python\/docs\/browsers\" rel=\"noopener nofollow\">Browsers<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.selenium.dev\/documentation\/webdriver\/waits\/\" rel=\"noopener nofollow\">Selenium: Waiting strategies<\/a>, <a href=\"https:\/\/www.selenium.dev\/documentation\/selenium_manager\/\" rel=\"noopener nofollow\">Selenium Manager<\/a>, <a href=\"https:\/\/www.selenium.dev\/documentation\/webdriver\/bidi\/\" rel=\"noopener nofollow\">WebDriver BiDi<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/requests.readthedocs.io\/en\/latest\/user\/advanced\/#timeouts\" rel=\"noopener nofollow\">requests: Timeouts<\/a>, <a href=\"https:\/\/www.python-httpx.org\/advanced\/resource-limits\/\" rel=\"noopener nofollow\">httpx: Resource limits<\/a>, <a href=\"https:\/\/urllib3.readthedocs.io\/en\/stable\/reference\/urllib3.util.html#urllib3.util.Retry\" rel=\"noopener nofollow\">urllib3: Retry<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/encode\/httpcore\/pull\/1035\" rel=\"noopener nofollow\">httpcore PR #1035<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/rushter\/selectolax\" rel=\"noopener nofollow\">selectolax<\/a>, <a href=\"https:\/\/www.crummy.com\/software\/BeautifulSoup\/bs4\/doc\/#installing-a-parser\" rel=\"noopener nofollow\">BeautifulSoup: Installing a parser<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9309\" rel=\"noopener nofollow\">RFC 9309 \u2014 Robots Exclusion Protocol<\/a>, <a href=\"https:\/\/developer.chrome.com\/docs\/devtools\/network\" rel=\"noopener nofollow\">Chrome DevTools: Network<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1090444\/\">https:\/\/habr.com\/ru\/articles\/1090444\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041a\u043e\u0433\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u043d\u0430 Python, \u0432 \u043e\u0434\u0438\u043d \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442 BeautifulSoup, Selenium, Scrapy \u0438 Playwright. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u0432\u044b\u0431\u043e\u0440 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432, \u043d\u043e \u044d\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439. BeautifulSoup \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u0441\u0435\u0442\u044c. Selenium \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u0430\u0440\u0441\u0435\u0440. Scrapy \u2014 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440. \u0421\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043b\u043e\u0431 \u2014 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043a\u0430\u043a \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0440\u043e\u0431\u043a\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0447 \u0438 \u0442\u0430\u043a\u0441\u0438.\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044d\u0442\u0430 \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u0430 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u043e\u0440\u043e\u0433\u043e. \u0414\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0438\u0437 \u043f\u0430\u0440\u044b \u0442\u044b\u0441\u044f\u0447 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u044e\u0442 Selenium \u0441 Chrome, \u0445\u043e\u0442\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c HTML. \u0418\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442: \u043f\u043e\u043b\u0434\u043d\u044f \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c requests\u2019\u043e\u043c \u0442\u043e, \u0447\u0442\u043e \u0440\u0438\u0441\u0443\u0435\u0442 JavaScript, \u0438 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e\u0442, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u0443\u0441\u0442\u043e\u0439 &lt;div id=&#187;root&#187;&gt;.\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043f\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u044f \u0441\u043e\u0431\u0440\u0430\u043b\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0442\u0435\u043d\u0434 \u0441 \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u043c\u0438: \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 HTML, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 JavaScript, \u043c\u0430\u0441\u0441\u043e\u0432\u044b\u0439 \u043e\u0431\u0445\u043e\u0434 \u0441\u043e\u0442\u0435\u043d \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0433\u0434\u0435 \u043d\u0430\u0434\u043e \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 \u0438 \u0436\u0434\u0430\u0442\u044c \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u043a\u0438. \u0412 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0440\u043e\u0433\u043d\u0430\u043b\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0430 \u043d\u0430 \u0432\u0440\u0435\u043c\u044f, \u043f\u0430\u043c\u044f\u0442\u044c, \u043e\u0431\u044a\u0451\u043c \u043a\u043e\u0434\u0430 \u0438 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f.\u0421\u043f\u043e\u0439\u043b\u0435\u0440: \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0435 \u00ab\u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435\u00bb, \u0430 \u00ab\u0433\u0434\u0435 \u043b\u0435\u0436\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0435\u00bb. \u041a\u043e\u0433\u0434\u0430 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c.\u0427\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0441\u043b\u043e\u0438, \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043b\u043e\u044f.HTTP-\u043a\u043b\u0438\u0435\u043d\u0442 (requests, httpx) \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043e\u0442\u0434\u0430\u0451\u0442 \u043e\u0442\u0432\u0435\u0442 \u043a\u0430\u043a \u0435\u0441\u0442\u044c: \u0431\u0430\u0439\u0442\u044b, \u0442\u0435\u043a\u0441\u0442, JSON. \u041f\u0440\u043e HTML \u043e\u043d \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, JavaScript \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442.HTML-\u043f\u0430\u0440\u0441\u0435\u0440 (BeautifulSoup, lxml, selectolax) \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 HTML \u0432 \u0434\u0435\u0440\u0435\u0432\u043e, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c CSS-\u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438\u043b\u0438 XPath. \u041e\u0442\u043a\u0443\u0434\u0430 \u0432\u0437\u044f\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u043e\u043a\u0430, \u0435\u043c\u0443 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e.HTTP CLIENT (requests \/ httpx)      \u2193   HTML \/ JSON      \u2193PARSER (BeautifulSoup \/ lxml \/ selectolax)\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 (Selenium, Playwright) \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043c \u0438\u0437 Python. \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442, \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0438 DOM \u0441\u0442\u0440\u043e\u0438\u0442 \u0441\u0430\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0430 Python \u0447\u0438\u0442\u0430\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.BROWSER AUTOMATION (Selenium \/ Playwright)      \u2193\u0431\u0440\u0430\u0443\u0437\u0435\u0440: \u0441\u0435\u0442\u044c \u2192 HTML \u2192 CSS \u2192 JavaScript      \u2193   DOM (\u0442\u043e, \u0447\u0442\u043e \u0432\u0438\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c)\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a (Scrapy) \u2014 \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 HTTP: \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u0432\u0442\u043e\u0440\u044b, \u0444\u0438\u043b\u044c\u0442\u0440 \u0434\u0443\u0431\u043b\u0435\u0439, \u044d\u043a\u0441\u043f\u043e\u0440\u0442. \u0412\u043d\u0443\u0442\u0440\u0438 \u0443 \u043d\u0435\u0433\u043e parsel \u043f\u043e\u0432\u0435\u0440\u0445 lxml, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438 selectolax.SCRAPY      \u2193HTTP + scheduler + retries + middlewares + pipelines + spiders\u0427\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0436\u0438\u0432\u043e\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u044f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0430 \u0441\u0432\u0435\u0436\u0438\u0435 \u0440\u0435\u043b\u0438\u0437\u044b \u043d\u0430 PyPI \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432 (\u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2026).\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0421\u043b\u043e\u0439\u0412\u0435\u0440\u0441\u0438\u044f\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0435\u043b\u0438\u0437\u0417\u0430\u043c\u0435\u0442\u043a\u0430requestsHTTP-\u043a\u043b\u0438\u0435\u043d\u04422.34\u043c\u0430\u0439 2026\u0442\u043e\u043b\u044c\u043a\u043e synchttpxHTTP-\u043a\u043b\u0438\u0435\u043d\u04420.28\u0434\u0435\u043a\u0430\u0431\u0440\u044c 2024sync \u0438 async, HTTP\/2; \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 \u0434\u0430\u0432\u043d\u043e \u043d\u0435\u0442beautifulsoup4\u043f\u0430\u0440\u0441\u0435\u0440 (\u043e\u0431\u0451\u0440\u0442\u043a\u0430)4.15\u0438\u044e\u043d\u044c 2026\u043f\u043e\u0432\u0435\u0440\u0445 html.parser, lxml \u0438\u043b\u0438 html5liblxml\u043f\u0430\u0440\u0441\u0435\u04406.1\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026libxml2, XPathselectolax\u043f\u0430\u0440\u0441\u0435\u04400.4\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026\u0434\u0432\u0438\u0436\u043a\u0438 Lexbor \u0438 Modest, \u0442\u043e\u043b\u044c\u043a\u043e CSSScrapy\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a2.19\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026Twisted + asyncioselenium\u0431\u0440\u0430\u0443\u0437\u0435\u04404.50\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026\u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442 Selenium Managerplaywright\u0431\u0440\u0430\u0443\u0437\u0435\u04401.63\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2026Chromium, Firefox, WebKit; sync \u0438 asyncMechanicalSoupHTTP + \u0444\u043e\u0440\u043c\u044b1.4\u043c\u0430\u0439 2025requests + BeautifulSoup, \u0431\u0435\u0437 JSpyppeteer\u0431\u0440\u0430\u0443\u0437\u0435\u04402.0\u0444\u0435\u0432\u0440\u0430\u043b\u044c 2024\u0432 README: \u00abThis repo is unmaintained\u00bbcloudscraperHTTP-\u043a\u043b\u0438\u0435\u043d\u04421.2\u0430\u043f\u0440\u0435\u043b\u044c 2023\u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442\u0422\u0440\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0438. Pyppeteer \u043a\u043e\u0433\u0434\u0430-\u0442\u043e \u0431\u044b\u043b \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c headless Chrome \u0438\u0437 asyncio, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0430\u0432\u0442\u043e\u0440\u044b \u0441\u0430\u043c\u0438 \u043f\u0438\u0448\u0443\u0442, \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0438 \u0441\u043e\u0432\u0435\u0442\u0443\u044e\u0442 Playwright. MechanicalSoup \u2014 \u044d\u0442\u043e requests \u0438 BeautifulSoup \u0441 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439 \u0441 HTML-\u0444\u043e\u0440\u043c\u0430\u043c\u0438; JavaScript \u043e\u043d \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u043a\u0435 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u0432\u044f\u0437\u043a\u0438 requests + BS4, \u0430 \u043d\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u043a\u0435 \u043d\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u0435\u0442 \u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u043c\u0438. \u0421\u0432\u043e\u044f \u043d\u0438\u0448\u0430 \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c: \u0441\u0442\u0430\u0440\u044b\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0441\u0430\u0439\u0442\u044b \u0441 \u0444\u043e\u0440\u043c\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0438\u043b\u0438 \u043f\u043e\u0438\u0441\u043a\u0430. cloudscraper \u043f\u0440\u044f\u043c\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043e\u0431\u0445\u043e\u0434\u0430 \u0437\u0430\u0449\u0438\u0442\u044b Cloudflare, \u0430 \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u043f\u0440\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u043b\u0438 \u0441\u0430\u0439\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u043c challenge-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u044d\u0442\u043e \u043f\u043e\u0432\u043e\u0434 \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 API \u0438\u043b\u0438 \u0434\u043e\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c.\u041f\u0440\u043e httpx \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 \u043d\u0435\u0442 \u0441 \u043a\u043e\u043d\u0446\u0430 2024 \u0433\u043e\u0434\u0430, \u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 0.x. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u0438 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u0430\u044f, \u043d\u043e \u043d\u0438\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0433\u0434\u0435 \u044d\u0442\u043e \u0430\u0443\u043a\u043d\u0443\u043b\u043e\u0441\u044c.\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043d\u0434\u0412\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0438\u0434\u0443\u0442 \u043f\u0440\u043e\u0442\u0438\u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 Starlette. \u0416\u0438\u0432\u043e\u0439 \u0441\u0430\u0439\u0442 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0433\u043e\u043d\u0430\u043c\u0438, \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f CDN \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441 \u0440\u0430\u0437\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e, \u0442\u0430\u043a \u0447\u0442\u043e \u0446\u0438\u0444\u0440\u044b \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0442\u044b\u0441\u044f\u0447\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e 64 \u0432 \u0447\u0443\u0436\u043e\u0439 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a, \u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u0447\u0443\u0436\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440.\u0423 localhost \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0431\u0435\u0434\u0430: \u0441\u0435\u0442\u044c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u0430\u044f, \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u0436\u0434\u0451\u0442 50 \u043c\u0441 \u0447\u0435\u0440\u0435\u0437 asyncio.sleep, \u0434\u0440\u0443\u0433\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442. \u0413\u0440\u0443\u0431\u0430\u044f, \u043d\u043e \u0447\u0435\u0441\u0442\u043d\u0430\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0441\u0430\u0439\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043d\u0435 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e.\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0427\u0442\u043e \u0442\u0430\u043c\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439\/catalog?page=N\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 HTML: 20 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a + \u043c\u0435\u043d\u044e \u0438 \u043f\u0440\u043e\u043c\u043e-\u0431\u043b\u043e\u043a\u0438, \u043e\u043a\u043e\u043b\u043e 75 \u041a\u0411, 1000 \u0441\u0442\u0440\u0430\u043d\u0438\u04461, 3\/flaky\/catalog?page=N\u0442\u043e \u0436\u0435, \u043d\u043e \u043a\u0430\u0436\u0434\u0430\u044f 10-\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 5033\/spa\u043f\u0443\u0441\u0442\u043e\u0439 &lt;div id=&#187;app&#187;&gt; \u0438 app.js \u0441 fetch2\/api\/products?page=NJSON, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 app.js2\/ui\u0444\u043e\u0440\u043c\u0430 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0435\u0449\u0451\u00bb4\u041c\u0430\u0448\u0438\u043d\u0430 \u2014 \u043d\u043e\u0443\u0442\u0431\u0443\u043a \u043d\u0430 Intel Core Ultra 5 125H \u0441 16 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438, Windows 11, Python 3.14. Selenium \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c Chrome 154, Playwright \u2014 \u0441\u043e \u0441\u0432\u043e\u0438\u043c Chromium, \u043e\u0431\u0430 \u0432 headless-\u0440\u0435\u0436\u0438\u043c\u0435. \u0421\u0435\u0440\u0432\u0435\u0440 \u0441\u0442\u0435\u043d\u0434\u0430 \u043a\u0440\u0443\u0442\u0438\u043b\u0441\u044f \u043d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u043c\u0430\u0448\u0438\u043d\u0435.\u041a\u0430\u043a \u043c\u0435\u0440\u0438\u043b\u0430:\u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 \u043d\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435, \u0447\u0442\u043e\u0431\u044b \u0432 \u0437\u0430\u043c\u0435\u0440 \u043f\u043e\u043f\u0430\u043b\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u043b\u0430\u0442\u0438\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a: \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u0441\u0442\u0430\u0440\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u0441\u0442\u0430\u0440\u0442 \u0440\u0435\u0430\u043a\u0442\u043e\u0440\u0430 Twisted;\u043f\u0430\u043c\u044f\u0442\u044c \u2014 \u043f\u0438\u043a \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0433\u043e RSS \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0438 \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432 (chromedriver, \u0434\u0440\u0430\u0439\u0432\u0435\u0440 Playwright, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b Chrome) \u0447\u0435\u0440\u0435\u0437 psutil. Chrome \u0434\u0435\u043b\u0438\u0442 \u0447\u0430\u0441\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u0446\u0438\u0444\u0440\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u044b\u0448\u0435\u043d\u044b;\u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0433\u0440\u0435\u0432\u043e\u0447\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a, \u043f\u043e\u0442\u043e\u043c 5\u20137 \u0437\u0430\u0447\u0451\u0442\u043d\u044b\u0445, \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u043c\u0435\u0434\u0438\u0430\u043d\u0430;\u043f\u0440\u043e\u0433\u043e\u043d \u0437\u0430\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432\u0435\u0440\u043d\u0443\u043b \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0442\u043e\u0432\u0430\u0440\u043e\u0432.\u041a\u043e\u0434 \u0441\u0442\u0435\u043d\u0434\u0430 \u0438 \u0432\u0441\u0435\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432: [\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439].\u0422\u0435\u0441\u0442 \u21161. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 HTML\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u044c 20 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u0438 \u0446\u0435\u043d. \u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 HTML.requests + BeautifulSoupresp = requests.get(URL, timeout=10)resp.raise_for_status()soup = BeautifulSoup(resp.text, &#171;lxml&#187;)items = [    {&#171;title&#187;: card.select_one(&#171;.title&#187;).get_text(strip=True),     &#171;price&#187;: float(card.select_one(&#171;.price&#187;).get_text())}    for card in soup.select(&#171;article.product&#187;)]timeout \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0434\u043b\u044f \u043a\u0440\u0430\u0441\u043e\u0442\u044b: \u0431\u0435\u0437 \u043d\u0435\u0433\u043e requests \u0431\u0443\u0434\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u0435\u0447\u043d\u043e. raise_for_status() \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 404 \u0438 503 \u0432 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u2014 \u0438\u043d\u0430\u0447\u0435 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0432\u0435\u0440\u043d\u0451\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a. \u0412\u0442\u043e\u0440\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 BeautifulSoup \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u043a \u044d\u0442\u043e\u043c\u0443 \u0435\u0449\u0451 \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0435: \u043a\u043e\u0434 \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u0441\u0435\u0440\u0432\u0435\u0440.httpx + selectolaxresp = httpx.get(URL, timeout=10)resp.raise_for_status()tree = LexborHTMLParser(resp.text)items = [    {&#171;title&#187;: node.css_first(&#171;.title&#187;).text(strip=True),     &#171;price&#187;: float(node.css_first(&#171;.price&#187;).text())}    for node in tree.css(&#171;article.product&#187;)]\u041f\u043e\u0447\u0442\u0438 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435: \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b httpx \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441 \u043f\u043e\u0445\u043e\u0436\u0438\u043c API. css_first \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 None, \u0435\u0441\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u0451\u043b, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0435 \u0431\u0435\u0437 \u0446\u0435\u043d\u044b \u043a\u043e\u0434 \u0443\u043f\u0430\u0434\u0451\u0442 \u0441 AttributeError. XPath \u0432 selectolax \u043d\u0435\u0442.Scrapyclass OnePage(scrapy.Spider):    name = &#171;one&#187;    start_urls = [URL]    def parse(self, response):        for card in response.css(&#171;article.product&#187;):            yield {&#171;title&#187;: card.css(&#171;.title::text&#187;).get(),                   &#171;price&#187;: float(card.css(&#171;.price::text&#187;).get())}\u041f\u0430\u0443\u043a \u0441\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442. \u041e\u043d \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442, \u043e\u0442\u043a\u0443\u0434\u0430 \u043d\u0430\u0447\u0430\u0442\u044c \u0438 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043e\u0442\u0432\u0435\u0442\u043e\u043c, \u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439, \u043f\u043e\u0432\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u043e\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0438\u0436\u043e\u043a. yield \u043e\u0442\u0434\u0430\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 pipeline, \u0430 \u043d\u0435 \u0432 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0434, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0437 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0449\u0451 \u0441\u0442\u0440\u043e\u043a \u043f\u044f\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c \u043e\u0431\u0432\u044f\u0437\u043a\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u0438\u0445 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 scrapy crawl one -o items.json.\u0411\u0440\u0430\u0443\u0437\u0435\u0440\u044b \u044f \u043f\u0440\u043e\u0433\u043d\u0430\u043b\u0430 \u043d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0435 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u0438\u043c JS-\u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0438 \u043d\u0430\u0438\u0432\u043d\u043e, \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u0412\u0440\u0435\u043c\u044f, \u0441\u041f\u0430\u043c\u044f\u0442\u044c, \u041c\u0411requests + BeautifulSoup0,3~40httpx + selectolax \/ lxml0,6~50Playwright~1,0~380Scrapy~1,0~90Selenium~3,3~570\u0421 \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0432\u0441\u0451 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e: \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 \u0434\u0435\u0441\u044f\u0442\u044c \u0440\u0430\u0437 \u0431\u043e\u043b\u044c\u0448\u0435. \u0410 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0442\u0440\u0438 \u0432\u0435\u0449\u0438 \u043c\u0435\u043d\u044f \u0443\u0434\u0438\u0432\u0438\u043b\u0438.httpx \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 requests \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u044c \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0420\u0430\u0437\u043b\u043e\u0436\u0438\u043b\u0430 \u043f\u043e \u0448\u0430\u0433\u0430\u043c: \u0441\u0430\u043c \u0438\u043c\u043f\u043e\u0440\u0442 \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u0430 \u0432\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 httpx.Client() \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u043a\u043e\u043b\u043e 0,3 \u0441 \u0434\u0430\u0436\u0435 \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e HTTP \u2014 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 SSL-\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0433\u0440\u0443\u0437\u0438\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b. httpx.get() \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u0430\u043a\u043e\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432. \u0412 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c \u0434\u043e\u043b\u0433\u043e\u0436\u0438\u0432\u0443\u0449\u0438\u043c Client \u044d\u0442\u043e \u0440\u0430\u0437\u043e\u0432\u0430\u044f \u0446\u0435\u043d\u0430, \u0432 \u0446\u0438\u043a\u043b\u0435 \u0438\u0437 httpx.get() \u2014 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u044f.Scrapy \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043d\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 Playwright. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b\u0430, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u043b\u0441\u044f. \u0421\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u043e\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0442\u044b\u0435 \u0434\u043e\u043b\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0432\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u2014 \u0438\u043c\u043f\u043e\u0440\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0441\u0442\u0430\u0440\u0442 \u0440\u0435\u0430\u043a\u0442\u043e\u0440\u0430, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f middlewares \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439. \u0414\u043b\u044f \u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0430 \u043d\u0430 \u0447\u0430\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u043e \u043d\u0438\u0447\u0442\u043e. \u0414\u043b\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 cron \u0434\u0451\u0440\u0433\u0430\u0435\u0442 \u0440\u0430\u0437 \u0432 \u043c\u0438\u043d\u0443\u0442\u0443 \u0440\u0430\u0434\u0438 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u2014 \u0437\u0430\u043c\u0435\u0442\u043d\u043e.Selenium \u0432\u0442\u0440\u043e\u0435 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 Playwright, \u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0442\u0443\u0442 \u043d\u0438 \u043f\u0440\u0438 \u0447\u0451\u043c. \u0417\u0430\u043f\u0443\u0441\u043a Chrome \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0437\u0430\u043d\u044f\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0430 driver.quit() \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u043b \u043e\u043a\u043e\u043b\u043e \u0434\u0432\u0443\u0445. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430\u0448\u0451\u043b\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 Selenium (webdriver\/common\/service.py): \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043d \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0437\u0430\u043a\u0440\u044b\u043b\u0441\u044f \u043b\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440, \u0432 \u0446\u0438\u043a\u043b\u0435 \u0441 sleep(1). chromedriver \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u0437\u0430\u043a\u0440\u044b\u0442\u044c\u0441\u044f \u043a \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u2014 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0434\u0432\u0443\u0445 \u0441\u0435\u043a\u0443\u043d\u0434. \u0411\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0441 Playwright \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u0447\u0435\u0437\u0430\u0435\u0442.\u041d\u0430\u0438\u0432\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u043e \u0434\u0435\u0441\u044f\u0442\u044b\u0435 \u0434\u043e\u043b\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b: \u0443 Selenium \u043a\u0430\u0436\u0434\u044b\u0439 find_element \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 .text \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441 \u043a chromedriver. \u041d\u0430 \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u0438 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430\u0445 \u044d\u0442\u043e \u043c\u0435\u043b\u043e\u0447\u044c, \u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0432 \u0442\u044b\u0441\u044f\u0447\u0443 \u0441\u0442\u0440\u043e\u043a \u0443\u0436\u0435 \u043d\u0435\u0442.\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e\u0439: \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0435\u0441\u0442\u044c \u0432 HTML, \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0432\u0435\u0440\u043d\u0451\u0442 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0432 3\u201310 \u0440\u0430\u0437 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0438 \u0441 \u0434\u0435\u0441\u044f\u0442\u0438\u043a\u0440\u0430\u0442\u043d\u044b\u043c \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u043c \u043f\u0430\u043c\u044f\u0442\u0438. \u041d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c. \u041d\u0430 \u0442\u044b\u0441\u044f\u0447\u0435 \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u0434\u0435\u043d\u044c\u0433\u0438 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u044b.\u0422\u0435\u0441\u0442 \u21162. JavaScript\u0422\u0435 \u0436\u0435 20 \u0442\u043e\u0432\u0430\u0440\u043e\u0432, \u043d\u043e \/spa \u043e\u0442\u0434\u0430\u0451\u0442 \u043f\u043e\u0447\u0442\u0438 \u043f\u0443\u0441\u0442\u043e\u0439 HTML, \u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0440\u0438\u0441\u0443\u0435\u0442 app.js \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a JSON API. \u0422\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 React \u0438 Vue \u0431\u0435\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.\u0427\u0442\u043e \u0432\u0438\u0434\u0438\u0442 requestsresp = requests.get(&#171;http:\/\/127.0.0.1:8000\/spa&#187;, timeout=10)soup = BeautifulSoup(resp.text, &#171;lxml&#187;)soup.select(&#171;article.product&#187;)   # []\u041f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437. \u0412\u0435\u0441\u044c \u043e\u0442\u0432\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430:&lt;body&gt;&lt;div id=&#8217;app&#8217;&gt;\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u2026&lt;\/div&gt;&lt;script&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-497367","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/497367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=497367"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/497367\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=497367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=497367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=497367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}