Управление прокси
Блокировка IP-адресов - один из старейших и наиболее эффективных способов ограничения доступа к веб-сайту. Поэтому для качественной библиотеки веб-скрапинга крайне важно предоставлять простые в использовании, но мощные инструменты для обхода такой блокировки. Самым эффективным оружием в нашем арсенале против блокировки IP является прокси-сервер.
В Crawlee мы можем использовать как собственные прокси-серверы, так и прокси от сторонних провайдеров.
Подробнее об обходе блокировок читайте в руководстве по обходу блокировок.
Быстрый старт
Если у нас уже есть собственные прокси URL, мы можем начать использовать их сразу, написав всего несколько строк кода.
import { ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: [
'http://proxy-1.com',
'http://proxy-2.com',
]
});
const proxyUrl = await proxyConfiguration.newUrl();
Примеры использования наших прокси URL с краулерами показаны ниже в разделе Интеграция с краулером.
Настройка прокси
Все наши потребности в прокси управляются классом ProxyConfiguration
. Мы создаем экземпляр с помощью функции constructor
на основе предоставленных параметров. Все возможные параметры конструктора можно найти в ProxyConfigurationOptions
.
Статический список прокси
Вы можете предоставить статический список URL-адресов прокси через параметр proxyUrls
. ProxyConfiguration
будет поочередно использовать предоставленные прокси.
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: [
'http://proxy-1.com',
'http://proxy-2.com',
null // null означает, что прокси не используется
]
});
Это самый простой способ использования списка прокси. Crawlee будет перебирать список прокси по круговому принципу.
Пользовательская функция прокси
Класс ProxyConfiguration
позволяет предоставить собственную функцию для выбора URL прокси. Это полезно, когда вы хотите реализовать свою логику выбора прокси.
const proxyConfiguration = new ProxyConfiguration({
newUrlFunction: (sessionId, { request }) => {
if (request?.url.includes('crawlee.dev')) {
return null; // для crawlee.dev прокси не используем
}
return 'http://proxy-1.com'; // для всех остальных URL используем этот прокси
}
});
Функция newUrlFunction
принимает два параметра - sessionId
и options
- и возвращает строку, содержащую URL прокси.
Параметр sessionId
всегда предоставляется и позволяет различать разные сессии - например, когда Crawlee обнаруживает, что ваши краулеры блокируются, он автоматически создает новую сессию с другим идентификатором.
Параметр options
- это объект, содержащий Request
, который будет выполнен. Обратите внимание, что этот объект доступен не всегда, например, при прямом использовании функции newUrl
. Поэтому ваша пользовательская функция не должна полагаться на наличие объекта request
и должна предоставлять поведение по умолчанию, когда его нет.
Многоуровневые прокси
Вы также можете предоставить список уровней прокси для класса ProxyConfiguration
. Это полезно, когда вы хотите автоматически переключаться между разными прокси в зависимости от поведения блокировки веб-сайта.
Обратите внимание, что опция tieredProxyUrls
требует использования ProxyConfiguration
из экземпляра краулера (см. ниже).
Использование этой конфигурации через вызовы newUrl
не даст ожидаемых результатов.
const proxyConfiguration = new ProxyConfiguration({
tieredProxyUrls: [
[null], // Сначала пробуем подключиться без прокси
['http://okay-proxy.com'],
['http://slightly-better-proxy.com', 'http://slightly-better-proxy-2.com'],
['http://very-good-and-expensive-proxy.com'],
]
});
Эта конфигурация начнет работу без прокси, затем переключится на http://okay-proxy.com
, если Crawlee обнаружит, что целевой веб-сайт нас блокирует. Если этот прокси тоже заблокирован, мы переключимся на один из URL-адресов slightly-better-proxy
. Если и они заблокированы, мы переключимся на very-good-and-expensive-proxy.com
.
Crawlee также периодически проверяет прокси нижних уровней, чтобы узнать, не разблокированы ли они, и если да, то переключится обратно на них.
Интеграция с краулером
ProxyConfiguration
легко интегрируется с HttpCrawler
, CheerioCrawler
, JSDOMCrawler
, PlaywrightCrawler
и PuppeteerCrawler
.
- HttpCrawler
- CheerioCrawler
- JSDOMCrawler
- PlaywrightCrawler
- PuppeteerCrawler
import { HttpCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: ['http://proxy-1.com', 'http://proxy-2.com'],
});
const crawler = new HttpCrawler({
proxyConfiguration,
// ...
});
import { CheerioCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: ['http://proxy-1.com', 'http://proxy-2.com'],
});
const crawler = new CheerioCrawler({
proxyConfiguration,
// ...
});
import { JSDOMCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: ['http://proxy-1.com', 'http://proxy-2.com'],
});
const crawler = new JSDOMCrawler({
proxyConfiguration,
// ...
});
import { PlaywrightCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: ['http://proxy-1.com', 'http://proxy-2.com'],
});
const crawler = new PlaywrightCrawler({
proxyConfiguration,
// ...
});
import { PuppeteerCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: ['http://proxy-1.com', 'http://proxy-2.com'],
});
const crawler = new PuppeteerCrawler({
proxyConfiguration,
// ...
});
Теперь наши краулеры будут использовать выбранные прокси для всех соединений.
Ротация IP и управление сессиями
proxyConfiguration.newUrl()
позволяет передавать параметр sessionId
. Он будет использоваться для создания пары sessionId
-proxyUrl
, и последующие вызовы newUrl()
с тем же sessionId
всегда будут возвращать тот же proxyUrl
. Это крайне полезно при скрапинге, поскольку мы хотим создать впечатление реального пользователя. Подробнее о том, как поддержание реальной сессии помогает избежать блокировки, смотрите в руководстве по управлению сессиями и классе SessionPool
.
Когда sessionId
не указан, наши прокси URL чередуются по круговому принципу.
- HttpCrawler
- CheerioCrawler
- JSDOMCrawler
- PlaywrightCrawler
- PuppeteerCrawler
- Standalone
import { HttpCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new HttpCrawler({
useSessionPool: true,
persistCookiesPerSession: true,
proxyConfiguration,
// ...
});
import { CheerioCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new CheerioCrawler({
useSessionPool: true,
persistCookiesPerSession: true,
proxyConfiguration,
// ...
});
import { JSDOMCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new JSDOMCrawler({
useSessionPool: true,
persistCookiesPerSession: true,
proxyConfiguration,
// ...
});
import { PlaywrightCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new PlaywrightCrawler({
useSessionPool: true,
persistCookiesPerSession: true,
proxyConfiguration,
// ...
});
import { PuppeteerCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new PuppeteerCrawler({
useSessionPool: true,
persistCookiesPerSession: true,
proxyConfiguration,
// ...
});
import { ProxyConfiguration, SessionPool } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const sessionPool = await SessionPool.open({
/* opts */
});
const session = await sessionPool.getSession();
const proxyUrl = await proxyConfiguration.newUrl(session.id);
Проверка текущего прокси в краулерах
HttpCrawler
, CheerioCrawler
, JSDOMCrawler
, PlaywrightCrawler
и PuppeteerCrawler
предоставляют доступ к информации о текущем используемом прокси в их requestHandler
через объект proxyInfo
.
С помощью объекта proxyInfo
мы можем легко получить доступ к URL прокси.
- HttpCrawler
- CheerioCrawler
- JSDOMCrawler
- PlaywrightCrawler
- PuppeteerCrawler
import { HttpCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new HttpCrawler({
proxyConfiguration,
async requestHandler({ proxyInfo }) {
console.log(proxyInfo);
},
// ...
});
import { CheerioCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new CheerioCrawler({
proxyConfiguration,
async requestHandler({ proxyInfo }) {
console.log(proxyInfo);
},
// ...
});
import { JSDOMCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new JSDOMCrawler({
proxyConfiguration,
async requestHandler({ proxyInfo }) {
console.log(proxyInfo);
},
// ...
});
import { PlaywrightCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new PlaywrightCrawler({
proxyConfiguration,
async requestHandler({ proxyInfo }) {
console.log(proxyInfo);
},
// ...
});
import { PuppeteerCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new PuppeteerCrawler({
proxyConfiguration,
async requestHandler({ proxyInfo }) {
console.log(proxyInfo);
},
// ...
});