При прямом доступе в Интернет сайты могут легко отслеживать ваши запросы по IP-адресу. Такое раскрытие IP-адреса может привести к показу целевой рекламы и отслеживанию ваших действий в Интернете, а также поставить под угрозу вашу цифровую личность.
Вот тут-то и пригодятся прокси-серверы. Они выступают в роли посредников между вашим компьютером и Интернетом и помогают защитить вашу цифровую личность. Когда вы применяете прокси-сервер, он отправляет запросы веб-сайтам от вашего имени, используя собственный IP-адрес.
При веб-парсинге прокси-серверы помогают обойти баны IP-адресов, избежать геоблокировки и защитить вашу личность. Из этой статьи вы узнаете, как внедрить прокси-серверы в C# для всех ваших проектов по веб-парсингу.
Предварительные условия
Прежде чем приступить к изучению этого руководства, убедитесь, что у вас есть следующее:
- Visual Studio 2022 или Visual Studio Code;
- .NET 7 или более новая версия;
- Пакет HtmlAgilityPack NuGet.
В примерах в этой статье используется отдельное консольное приложение .NET. При создании подобного приложения можно воспользоваться одним из следующих руководств:
- «Создание консольного приложения .NET с помощью Visual Studio Code»;
- «Создание консольного приложения .NET с помощью Visual Studio».
Для начала вам необходимо создать два консольных приложения: WebScrapApp
и WebScrapBrightData
:
Для веб-парсинга, особенно если вы имеете дело с HTML-контентом, вам нужны специальные инструменты, такие как HtmlAgilityPack. Эта библиотека облегчает синтаксический анализ и обработку HTML, упрощая извлечение данных из веб-страниц.
В обоих проектах (т.е. WebScrapApp
и WebScrapBrightData
) добавьте пакет HtmlAgilityPack от NuGet, щелкнув правой кнопкой мыши по папке NuGet, а затем по «Управление пакетами NuGet». Когда появится всплывающее окно, найдите HtmlAgilityPack и установите его для обоих проектов:
Чтобы запустить любой из следующих проектов, необходимо перейти в каталог проекта в командной строке и использовать cd путь к\вашему\проекту
, а затем dotnet run
. Кроме того, можно нажать F5, чтобы создать и запустить проект в Visual Studio. Оба метода компилируют и запускают приложение, отображая соответствующий результат.
Примечание. Если у вас нет Visual Studio 2022, вы можете использовать любую альтернативную IDE, поддерживающую .NET 7. Просто имейте в виду, что некоторые шаги могут отличаться от шагов в этом руководстве.
Как настроить локальный прокси-сервер
Первое, что вам нужно сделать при веб-парсинге, — это задействовать прокси-сервер. В этом руководстве используется прокси-сервер с открытым исходным кодом mitmproxy.
Для начала перейдите в mitmproxy downloads, загрузите версию 10.1.6 и выберите правильную версию для своей операционной системы. Для получения дополнительной помощи ознакомьтесь с официальным руководством по установке mitmproxy.
После установки mitmproxy откройте терминал и запустите mitmproxy следующей командой:
mitmproxy
В оболочке или терминале должно появиться окно следующего вида:
Чтобы протестировать прокси-сервер, откройте другой терминал или оболочку и выполните следующий запрос curl:
curl --proxy http://localhost:8080 "http://wttr.in/Dunedin?0"
Выводимый результат должен выглядеть следующим образом:
Weather report: Dunedin
Cloudy
.--. +11(9) °C
.-( ). ↙ 15 km/h
(___.__)__) 10 km
0.0 mm
В окне mitmproxy вы должны увидеть, что он перехватил вызов через локальный прокси-сервер:
Веб-парсинг в C#
В следующем разделе вы настроите консольное приложение C# WebScrapApp
для веб-парсинга. Это приложение использует прокси-сервер и поддерживает ротацию прокси-серверов для повышения эффективности.
Создайте HttpClient
Класс ProxyHttpClient
предназначен для настройки инстанса HttpClient
с целью маршрутизации запросов через указанный прокси-сервер.
В своем проекте WebScrapApp
создайте новый файл класса с именем ProxyHttpClient.cs
и добавьте следующий код:
namespace WebScrapApp
{
public class ProxyHttpClient
{
public static HttpClient CreateClient(string proxyUrl)
{
var httpClientHandler = new HttpClientHandler()
{
Proxy = new WebProxy(proxyUrl),
UseProxy = true
};
return new HttpClient(httpClientHandler);
}
}
}
Реализация ротации прокси-серверов
Чтобы реализовать ротацию прокси-серверов, создайте файл класса ProxyRotator.cs
в своем решении WebScrapApp
:
namespace WebScrapApp
{
public class ProxyRotator
{
private List<string> _validProxies = new List<string>();
private readonly Random _random = new();
public ProxyRotator(string[] proxies, bool isLocal)
{
if (isLocal)
{
_validProxies.Add("http://localhost:8080/");
}
else
{
_validProxies = ProxyChecker.GetWorkingProxies(proxies.ToList()).Result;
}
if (_validProxies.Count == 0)
throw new InvalidOperationException();
}
public HttpClient ScrapeDataWithRandomProxy(string url)
{
if (_validProxies.Count == 0)
throw new InvalidOperationException();
var proxyUrl = _validProxies[_random.Next(_validProxies.Count)];
return ProxyHttpClient.CreateClient(proxyUrl);
}
}
}
Этот класс управляет списком прокси-серверов, предоставляя метод случайного выбора прокси-сервера для каждого веб-запроса. Такая рандомизация играет ключевую роль в снижении риска обнаружения и потенциальных банов IP-адресов во время веб-парсинга.
Если для isLocal
установлено значение True
(«Истина»), используется локальный прокси-сервер из mitmproxy. Если установлено значение False
(«Ложь»), применяются общедоступные IP-адреса прокси-серверов.
ProxyChecker
необходим для проверки списка прокси-серверов.
Затем создайте новый файл класса с именем ProxyChecker.cs
и добавьте следующий код:
using WebScrapApp;
namespace WebScrapApp
{
public class ProxyChecker
{
private static SemaphoreSlim consoleSemaphore = new SemaphoreSlim(1, 1);
private static int currentProxyNumber = 0;
public static async Task<List<string>> GetWorkingProxies(List<string> proxies)
{
var tasks = new List<Task<Tuple<string, bool>>>();
foreach (var proxyUrl in proxies)
{
tasks.Add(CheckProxy(proxyUrl, proxies.Count));
}
var results = await Task.WhenAll(tasks);
var workingProxies = new List<string>();
foreach (var result in results)
{
if (result.Item2)
{
workingProxies.Add(result.Item1);
}
}
return workingProxies;
}
private static async Task<Tuple<string, bool>> CheckProxy(string proxyUrl, int totalProxies)
{
var client = ProxyHttpClient.CreateClient(proxyUrl);
bool isWorking = await IsProxyWorking(client);
await consoleSemaphore.WaitAsync();
try
{
currentProxyNumber++;
Console.WriteLine($"Proxy: {currentProxyNumber} de {totalProxies}");
}
finally
{
consoleSemaphore.Release();
}
return new Tuple<string, bool>(proxyUrl, isWorking);
}
private static async Task<bool> IsProxyWorking(HttpClient client)
{
try
{
var testUrl = "http://www.google.com";
var response = await client.GetAsync(testUrl);
return response.IsSuccessStatusCode;
}
catch
{
return false;
}
}
}
}
Этот код определяет ProxyChecker
в качестве средства проверки списка прокси-серверов. При использовании метода GetWorkingProxies
со списком URL-адресов прокси-серверов он проверяет состояние каждого прокси-сервера асинхронно с помощью метода CheckProxy
, добавляя работоспособные прокси-серверы в список workingProxies
. В CheckProxy
вы задаете HttpClient
с URL-адресом прокси-сервера, делаете тестовый запрос на http://www.google.comи безопасно записываете прогресс с помощью семафора.
Метод IsProxyWorking
подтверждает работоспособность прокси-сервера, исследуя код состояния ответа и возвращая true
(«истина») в отношении работающих прокси-серверов. Этот класс помогает найти работоспособные прокси-серверы в заданном списке.
Выполнение веб-парсинга
Для парсинга данных создайте новый файл класса WebScraper.cs
в своем решении WebScrapApp
и добавьте следующий код:
using HtmlAgilityPack;
namespace WebScrapApp
{
public class WebScraper
{
public static async Task ScrapeData(ProxyRotator proxyRotator, string url)
{
try
{
var client = proxyRotator.ScrapeDataWithRandomProxy(url);
// Use HttpClient to make an asynchronous GET request
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
// Load the HTML content into an HtmlDocument
HtmlDocument doc = new();
doc.LoadHtml(content);
// Use XPath to find all <a> tags that are direct children of <li>, <p>, or <td>
var nodes = doc.DocumentNode.SelectNodes("//li/a[@href] | //p/a[@href] | //td/a[@href]");
if (nodes != null)
{
foreach (var node in nodes)
{
string hrefValue = node.GetAttributeValue("href", string.Empty);
string title = node.InnerText; // This gets the text content of the <a> tag, which is usually the title
// Since Wikipedia URLs are relative, we need to convert them to absolute
Uri baseUri = new(url);
Uri fullUri = new(baseUri, hrefValue);
Console.WriteLine($"Title: {title}, Link: {fullUri.AbsoluteUri}");
// You can process each title and link as required
}
}
else
{
Console.WriteLine("No article links found on the page.");
}
// Add additional logic for other data extraction as needed
}
catch (Exception ex)
{
throw ex;
}
}
}
}
В этом коде вы определяете WebScraper
, который включает в себя функцию веб-парсинга. При вызове метода ScrapeData
вы указываете ему инстанс ProxyRotator
и целевой URL-адрес. В этом методе вы используете HttpClient
для асинхронного запроса GET к URL-адресу, извлечения содержимого HTML и его анализа с помощью библиотеки HtmlAgilityPack. Затем вы используете запросы XPath для поиска и извлечения ссылок и соответствующих заголовков из определенных HTML-элементов. Если ссылки на статьи найдены, выводятся их заголовки и абсолютные URL-адреса. В противном случае отображается сообщение о том, что ссылки не найдены.
После настройки механизма ротации прокси-серверов и реализации функции веб-парсинга необходимо без проблем интегрировать эти компоненты в основную точку входа приложения, которая обычно находится в Program.cs
. Эта интеграция позволяет приложению выполнять задачи по веб-парсингу с помощью ротируемых прокси-серверов с особым акцентом на парсинг данных с главной страницы «Википедии»:
namespace WebScrapApp {
public class Program
{
static async Task Main(string[] args)
{
string[] proxies = {
"http://162.223.89.84:80",
"http://203.80.189.33:8080",
"http://94.45.74.60:8080",
"http://162.248.225.8:80",
"http://167.71.5.83:3128"
};
var proxyRotator = new ProxyRotator(proxies, false);
string urlToScrape = "https://www.wikipedia.org/";
await WebScraper.ScrapeData(proxyRotator, urlToScrape);
}
}
}
В этом коде приложение инициализирует список URL-адресов прокси-серверов, создает инстанс ProxyRotator
, указывает целевой URL-адрес для парсинга (в данном случае https://www.wikipedia.org/
) и вызывает метод WebScraper.ScrapeData
для запуска процесса веб-парсинга.
Приложение использует список IP-адресов бесплатных прокси-серверов, указанных в массиве proxies, для маршрутизации запросов на веб-парсинг, маскировки под надежный источник и минимизации риска блокировки сервером «Википедии». Метод ScrapeData
предназначен для парсинга главной страницы «Википедии» с целью извлечения и отображения заголовков статей и ссылок в консоли. Класс ProxyRotator
обрабатывает ротацию этих прокси, повышая дискретность очистки.
Запуск WebScrapApp
Чтобы запустить WebScrapApp
, откройте новый терминал или оболочку в корневом каталоге вашего приложения WebScrapApp
и выполните следующие команды:
dotnet build
dotnet run
Выводимый результат должен выглядеть следующим образом:
…output omitted…
Title: Latina, Link: https://la.wikipedia.org/
Title: Latviešu, Link: https://lv.wikipedia.org/
Title: Lietuvių, Link: https://lt.wikipedia.org/
Title: Magyar, Link: https://hu.wikipedia.org/
Title: Македонски, Link: https://mk.wikipedia.org/
Title: Bahasa Melayu, Link: https://ms.wikipedia.org/
Title: Bahaso Minangkabau, Link: https://min.wikipedia.org/
Title: bokmål, Link: https://no.wikipedia.org/
Title: nynorsk, Link: https://nn.wikipedia.org/
Title: Oʻzbekcha / Ўзбекча, Link: https://uz.wikipedia.org/
Title: Қазақша / Qazaqşa / قازاقشا, Link: https://kk.wikipedia.org/
Title: Română, Link: https://ro.wikipedia.org/
Title: Simple English, Link: https://simple.wikipedia.org/
Title: Slovenčina, Link: https://sk.wikipedia.org/
Title: Slovenščina, Link: https://sl.wikipedia.org/
Title: Српски / Srpski, Link: https://sr.wikipedia.org/
Title: Srpskohrvatski / Српскохрватски, Link: https://sh.wikipedia.org/
Title: Suomi, Link: https://fi.wikipedia.org/
Title: தமிழ், Link: https://ta.wikipedia.org/
…output omitted…
При вызове метода ScrapeData
класса WebScraper
выполняется извлечение данных из «Википедии», в результате чего в консоли отображаются заголовки статей и соответствующие ссылки. В этом коде используются общедоступные прокси-серверы, и всякий раз, когда вы запускаете приложение, оно выбирает один из перечисленных IP-адресов в качестве прокси-сервера.
Для тестирования на локальном прокси-сервере от mitmproxy обновите метод ProxyRotator
в файле Program
следующим образом:
var proxyRotator = new ProxyRotator(proxies, true)
string urlToScrape = "http://toscrape.com/";
Если задать значение true
(«истина»), используется локальный прокси-сервер, работающий на вашем порту localhost 8080 (т.е. сервер mitmproxy).
Чтобы упростить процесс настройки сертификата на компьютере, измените URL-адрес на http://toscrape.com/
.
Убедитесь, что сервер mitmproxy запущен, а затем снова выполните те же команды:
dotnet build
dotnet run
Выводимый результат должен выглядеть следующим образом:
…output omitted…
Title: fictional bookstore, Link: http://books.toscrape.com/
Title: books.toscrape.com, Link: http://books.toscrape.com/
Title: A website, Link: http://quotes.toscrape.com/
Title: Default, Link: http://quotes.toscrape.com/
Title: Scroll, Link: http://quotes.toscrape.com/scroll
Title: JavaScript, Link: http://quotes.toscrape.com/js
Title: Delayed, Link: http://quotes.toscrape.com/js-delayed
Title: Tableful, Link: http://quotes.toscrape.com/tableful
Title: Login, Link: http://quotes.toscrape.com/login
Title: ViewState, Link: http://quotes.toscrape.com/search.aspx
Title: Random, Link: http://quotes.toscrape.com/random
…output omitted…
В окне mitmproxy в терминале или оболочке вы увидите, что прокси-сервер перехватил вызов:
Как видите, настройка локального прокси-сервера или переключение между различными прокси-серверами может быть сложной и трудоемкой задачей. К счастью, в этом могут помочь такие инструменты, как Bright Data. Из следующего раздела вы узнаете, как использовать прокси-сервер Bright Data для упрощения процесса парсинга.
Прокси-сервер Bright Data
Bright Data предлагает сеть прокси-сервисов, доступную в 195 местах. В эту сеть интегрирована функция ротации прокси-серверов Bright Data, которая систематически чередует серверы для повышения эффективности и безопасности веб-парсинга.
Использование этой системы ротируемых прокси-серверов снижает риск банов IP-адресов и блокировок, часто встречающихся при веб-парсинге. При каждом запросе выполняется смена прокси-сервера, что позволяет скрыть личность того, кто выполняет парсинг, и затрудняет сайтам обнаружение парсера и ограничение доступа для него. Такой подход повышает надежность сбора данных, обеспечивая повышенную анонимность и безопасность.
Платформа Bright Data разработана с учетом соображений простоты использования и настройки, поэтому она идеально подходит для проектов по веб-парсингу на C#, о которых вы узнаете из следующего раздела.
Создание резидентного прокси-сервера
Прежде чем использовать прокси-сервер Bright Data в своем проекте, необходимо создать аккаунт. Для этого посетите сайт Bright Data и оформите подписку на бесплатную пробную версию.
После настройки аккаунта войдите в него и нажмите на значок местоположения слева, чтобы перейти в раздел «Прокси-серверы и инфраструктура парсинга». Затем нажмите «Добавить» и выберите «Резидентные прокси-серверы»:
Оставьте имена по умолчанию и снова нажмите «Добавить» , чтобы создать резидентный прокси-сервер:
После создания прокси-сервера вы должны увидеть учетные данные, включая хост, порт, имя пользователя и пароль. Сохраните эти учетные данные в надежном месте, так как они понадобятся вам позже:
Перейдите к проекту WebScrapingBrightData в IDE, терминале или оболочке. Затем создайте файл класса BrightDataProxyConfigurator.cs
и добавьте следующий код:
using System.Net;
namespace WebScrapBrightData
{
public class BrightDataProxyConfigurator
{
public static HttpClient ConfigureHttpClient(string proxyHost, string proxyUsername, string proxyPassword)
{
var proxy = new WebProxy(proxyHost) {
Credentials = new NetworkCredential(proxyUsername, proxyPassword)
};
var httpClientHandler = new HttpClientHandler() {
Proxy = proxy,
UseProxy = true
};
var client = new HttpClient(httpClientHandler);
client.DefaultRequestHeaders.Add("User-Agent", "YourUserAgent");
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.TryAddWithoutValidation("Proxy-Authorization", Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes($"{proxyUsername}:{proxyPassword}")));
return client;
}
}
}
В этом коде вы определяете класс BrightDataProxyConfigurator
, который включает метод ConfigureHttpClient
. При вызове этот метод настраивает и возвращает HttpClient
, настроенный на использование прокси-сервера. Для этого необходимо создать URL-адрес прокси-сервера, используя предоставленное имя пользователя
, пароль
, хост
и порт
, а затем настроить на этом прокси-сервере HttpClientHandler
. В конечном итоге метод возвращает инстанс HttpClient
, который направляет все запросы через указанный прокси-сервер.
Затем создайте файл класса WebContentScraper.cs
в проекте WebScrapingBrightData
и добавьте следующий код:
using HtmlAgilityPack;
namespace WebScrapBrightData
{
public class WebContentScraper
{
public static async Task ScrapeContent(string url, HttpClient client)
{
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
HtmlDocument doc = new();
doc.LoadHtml(content);
var nodes = doc.DocumentNode.SelectNodes("//li/a[@href] | //p/a[@href] | //td/a[@href]");
if (nodes != null)
{
foreach (var node in nodes)
{
string hrefValue = node.GetAttributeValue("href", string.Empty);
string title = node.InnerText;
Uri baseUri = new(url);
Uri fullUri = new(baseUri, hrefValue);
Console.WriteLine($"Title: {title}, Link: {fullUri.AbsoluteUri}");
}
}
else
{
Console.WriteLine("No article links found on the page.");
}
}
}
}
Этот код определяет класс WebContentScraper
со статическим асинхронным методом ScrapeContent
. Данный метод получает URL-адрес и HttpClient, извлекает содержимое веб-страницы, анализирует его как HTML и извлекает ссылки из определенных элементов HTML (элементов списка, абзацев и ячеек таблицы). Затем заголовки и абсолютные URI этих ссылок выводятся в консоли.
Класс программы
Теперь снова выполните парсинг «Википедии» и узнайте, как Bright Data улучшает доступ и анонимность.
Обновите файл класса Program.cs
, добавив следующий код:
namespace WebScrapBrightData
{
public class Program
{
public static async Task Main(string[] args)
{
// Bright Data Proxy Configuration
string host = "your_brightdata_proxy_host";
string username = "your_brightdata_proxy_username";
string password = "your_brightdata_proxy_password";
var client = BrightDataProxyConfigurator.ConfigureHttpClient(host, username, password);
// Scrape content from the target URL
string urlToScrape = "https://www.wikipedia.org/";
await WebContentScraper.ScrapeContent(urlToScrape, client);
}
}
}
Примечание. Обязательно замените учетные данные прокси-сервера Bright Data на те, которые вы сохранили ранее.
Затем, чтобы протестировать и запустить приложение, откройте оболочку или терминал из корневого каталога проекта WebScrapBrightData
и выполните следующую команду:
dotnet build
dotnet run
При использовании публичных прокси-серверов вы должны получить тот же результат, что и раньше:
…output omitted…
Title: Latina, Link: https://la.wikipedia.org/
Title: Latviešu, Link: https://lv.wikipedia.org/
Title: Lietuvių, Link: https://lt.wikipedia.org/
Title: Magyar, Link: https://hu.wikipedia.org/
Title: Македонски, Link: https://mk.wikipedia.org/
Title: Bahasa Melayu, Link: https://ms.wikipedia.org/
Title: Bahaso Minangkabau, Link: https://min.wikipedia.org/
Title: bokmål, Link: https://no.wikipedia.org/
Title: nynorsk, Link: https://nn.wikipedia.org/
Title: Oʻzbekcha / Ўзбекча, Link: https://uz.wikipedia.org/
Title: Қазақша / Qazaqşa / قازاقشا, Link: https://kk.wikipedia.org/
Title: Română, Link: https://ro.wikipedia.org/
Title: Simple English, Link: https://simple.wikipedia.org/
Title: Slovenčina, Link: https://sk.wikipedia.org/
Title: Slovenščina, Link: https://sl.wikipedia.org/
Title: Српски / Srpski, Link: https://sr.wikipedia.org/
Title: Srpskohrvatski / Српскохрватски, Link: https://sh.wikipedia.org/
Title: Suomi, Link: https://fi.wikipedia.org/
Title: தமிழ், Link: https://ta.wikipedia.org/
…output omitted…
Программа использует прокси-сервер Bright Data для парсинга главной страницы «Википедии» и отображения извлеченных заголовков и ссылок в консоли. Это демонстрирует эффективность и простоту интеграции прокси-сервера Bright Data в проект по веб-парсингу на C# для конфиденциального и надежного извлечения данных.
Если вы хотите визуализировать эффект использования прокси-сервера Bright Data, попробуйте отправить запрос GET по адресу http://lumtest.com/myip.json. Этот веб-сайт вернет местоположение и другие сетевые данные клиента, который в настоящее время пытается получить доступ к веб-сайту. Если вы хотите попробовать это сами, откройте ссылку в новой вкладке браузера. Вы должны увидеть общедоступные сведения о вашей сети.
Чтобы попробовать использовать прокси-сервер Bright Data, обновите код в WebContentScraper.cs
по следующему образцу:
using HtmlAgilityPack;
public class WebContentScraper
{
public static async Task ScrapeContent(string url, HttpClient client)
{
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
HtmlDocument doc = new();
doc.LoadHtml(content);
Console.Write(content);
}
}
Затем обновите переменную urlToScrape
в файле Program.cs
для выполнения парсинга сайта:
string urlToScrape = "http://lumtest.com/myip.json";
Теперь попробуйте снова запустить приложение. В вашем терминале должно отобразиться следующее:
{"ip":"79.221.123.68","country":"DE","asn":{"asnum":3320,"org_name":"Deutsche Telekom AG"},"geo":{"city":"Koenigs Wusterhausen","region":"BB","region_name":"Brandenburg","postal_code":"15711","latitude":52.3014,"longitude":13.633,"tz":"Europe/Berlin","lum_city":"koenigswusterhausen","lum_region":"bb"}}
Это подтверждает, что запрос теперь передается через один из прокси-серверов Bright Data.
Заключение
Из этой статьи вы узнали, как использовать прокси-серверы вместе с C# для веб-парсинга.
Хотя локальные прокси-серверы могут быть полезны в некоторых сценариях, они часто не позволяют реализовать все возможности проектов веб-парсинга из-за присущих таким серверам ограничений. К счастью, тут могут помочь иные прокси-серверы. Благодаря обширной глобальной сети и разнообразным вариантам прокси-серверов, включая резидентные прокси-серверы, прокси-серверы интернет-провайдеров, прокси-серверы центров обработки данных и мобильные прокси-серверы, Bright Data гарантирует высокую степень гибкости и надежности. Примечательно, что функция ротации прокси-серверов исключительно полезна при выполнении крупномасштабных задач по парсингу, поскольку она помогает сохранить анонимность и снизить риск банов IP-адресов.
При дальнейшем освоении веб-парсинга рассмотрите возможность использования решений Bright Data в качестве мощного и масштабируемого способа эффективного сбора данных при использовании передовых методик веб-парсинга.
Весь код из этого руководства доступен в этом репозитории GitHub.
Кредитная карта не требуется