Управление сессиями
SessionPool
- это класс в Crawlee, который позволяет управлять ротацией прокси IP-адресов вместе с cookies и другими пользовательскими настройками.
Основное преимущество использования SessionPool заключается в возможности фильтрации заблокированных или неработающих прокси. Это позволяет избежать повторных запросов через известные нерабочие прокси. Другое преимущество - возможность хранить информацию, тесно связанную с IP-адресом, такую как cookies, токены авторизации и специальные заголовки. Использование cookies и других идентификаторов только с определенным IP снижает вероятность блокировки. И последнее, но не менее важное преимущество - равномерная ротация IP-адресов. SessionPool выбирает сессии случайным образом, что помогает избежать перегрузки небольшого пула доступных IP.
Подробнее о предотвращении блокировки читайте в руководстве по обходу блокировок.
Давайте рассмотрим примеры использования SessionPool:
- с
BasicCrawler
; - с
HttpCrawler
; - с
CheerioCrawler
; - с
JSDOMCrawler
; - с
PlaywrightCrawler
; - с
PuppeteerCrawler
; - без краулера (автономное использование для ручного управления сессиями).
- BasicCrawler
- HttpCrawler
- CheerioCrawler
- JSDOMCrawler
- PlaywrightCrawler
- PuppeteerCrawler
- Standalone
import { BasicCrawler, ProxyConfiguration } from 'crawlee';
import { gotScraping } from 'got-scraping';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new BasicCrawler({
// Включает пул сессий (по умолчанию true).
useSessionPool: true,
// Переопределяет конфигурацию пула сессий по умолчанию.
sessionPoolOptions: { maxPoolSize: 100 },
async requestHandler({ request, session }) {
const { url } = request;
const requestOptions = {
url,
// Используем идентификатор сессии, чтобы иметь один и тот же proxyUrl
// для всех запросов, использующих одну и ту же сессию.
proxyUrl: await proxyConfiguration.newUrl(session.id),
throwHttpErrors: false,
headers: {
// Если вы хотите использовать cookieJar.
// Таким образом вы получаете строку Cookie-заголовков из сессии.
Cookie: session.getCookieString(url),
},
};
let response;
try {
response = await gotScraping(requestOptions);
} catch (e) {
if (e === 'SomeNetworkError') {
// Если возникает сетевая ошибка, такая как таймаут, разрыв соединения и т.д.
// Обычно это происходит из-за плохой удачи,
// и прокси-сервер может работать. Нет необходимости отбрасывать сессию.
session.markBad();
}
throw e;
}
// Автоматически отбрасывает сессию на основе HTTP-статус-кода ответа.
session.retireOnBlockedStatusCodes(response.statusCode);
if (response.body.blocked) {
// Вы уверены, что она заблокирована.
// Это отбросит сессию.
session.retire();
}
// Все в порядке, вы можете получить данные.
// Нет необходимости вызывать session.markGood -> BasicCrawler вызывает его для вас.
// Если вы хотите использовать CookieJar в сессии, вам нужно.
session.setCookiesFromResponse(response);
},
});
import { HttpCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new HttpCrawler({
// Чтобы использовать логику вращения IP-адресов в сессиях, вы должны включить использование прокси.
proxyConfiguration,
// Включает пул сессий (по умолчанию true).
useSessionPool: true,
// Переопределяет конфигурацию пула сессий по умолчанию.
sessionPoolOptions: { maxPoolSize: 100 },
// Установите в true, если вы хотите, чтобы краулер сохранял cookies на сессию,
// и автоматически устанавливал cookie-заголовок в запрос (по умолчанию true).
persistCookiesPerSession: true,
async requestHandler({ session, body }) {
const title = body.match(/<title(?:.*?)>(.*?)<\/title>/)?.[1];
if (title === 'Blocked') {
session.retire();
} else if (title === 'Not sure if blocked, might also be a connection error') {
session.markBad();
} else {
// session.markGood() - этот шаг выполняется автоматически в BasicCrawler.
}
},
});
import { CheerioCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new CheerioCrawler({
// Чтобы использовать логику вращения IP-адресов в сессиях, вы должны включить использование прокси.
proxyConfiguration,
// Включает пул сессий (по умолчанию true).
useSessionPool: true,
// Переопределяет конфигурацию пула сессий по умолчанию.
sessionPoolOptions: { maxPoolSize: 100 },
// Установите в true, если вы хотите, чтобы краулер сохранял cookies на сессию,
// и автоматически устанавливал cookie-заголовок в запрос (по умолчанию true).
persistCookiesPerSession: true,
async requestHandler({ session, $ }) {
const title = $('title').text();
if (title === 'Blocked') {
session.retire();
} else if (title === 'Not sure if blocked, might also be a connection error') {
session.markBad();
} else {
// session.markGood() - этот шаг выполняется автоматически в BasicCrawler.
}
},
});
import { JSDOMCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new JSDOMCrawler({
// Чтобы использовать логику вращения IP-адресов в сессиях, вы должны включить использование прокси.
proxyConfiguration,
// Включает пул сессий (по умолчанию true).
useSessionPool: true,
// Переопределяет конфигурацию пула сессий по умолчанию.
sessionPoolOptions: { maxPoolSize: 100 },
// Установите в true, если вы хотите, чтобы краулер сохранял cookies на сессию,
// и автоматически устанавливал cookie-заголовок в запрос (по умолчанию true).
persistCookiesPerSession: true,
async requestHandler({ session, window }) {
const title = window.document.title;
if (title === 'Blocked') {
session.retire();
} else if (title === 'Not sure if blocked, might also be a connection error') {
session.markBad();
} else {
// session.markGood() - этот шаг выполняется автоматически в BasicCrawler.
}
},
});
import { PlaywrightCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new PlaywrightCrawler({
// Чтобы использовать логику вращения IP-адресов в сессиях, вы должны включить использование прокси.
proxyConfiguration,
// Включает пул сессий (по умолчанию true).
useSessionPool: true,
// Переопределяет конфигурацию пула сессий по умолчанию
sessionPoolOptions: { maxPoolSize: 100 },
// Установите в true, если вы хотите, чтобы краулер сохранял cookies на сессию,
// и автоматически устанавливал cookie-заголовок в запрос (по умолчанию true).
persistCookiesPerSession: true,
async requestHandler({ page, session }) {
const title = await page.title();
if (title === 'Blocked') {
session.retire();
} else if (title === 'Not sure if blocked, might also be a connection error') {
session.markBad();
} else {
// session.markGood() - этот шаг выполняется автоматически в PlaywrightCrawler.
}
},
});
import { PuppeteerCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
/* opts */
});
const crawler = new PuppeteerCrawler({
// Чтобы использовать логику вращения IP-адресов в сессиях, вы должны включить использование прокси.
proxyConfiguration,
// Включает пул сессий (по умолчанию true).
useSessionPool: true,
// Переопределяет конфигурацию пула сессий по умолчанию
sessionPoolOptions: { maxPoolSize: 100 },
// Установите в true, если вы хотите, чтобы краулер сохранял cookies на сессию,
// и автоматически устанавливал cookie-заголовок в запрос (по умолчанию true).
persistCookiesPerSession: true,
async requestHandler({ page, session }) {
const title = await page.title();
if (title === 'Blocked') {
session.retire();
} else if (title === 'Not sure if blocked, might also be a connection error') {
session.markBad();
} else {
// session.markGood() - этот шаг выполняется автоматически в PuppeteerCrawler.
}
},
});
import { SessionPool } from 'crawlee';
// Переопределяет конфигурацию пула сессий по умолчанию.
const sessionPoolOptions = {
maxPoolSize: 100,
};
// Открывает пул сессий.
const sessionPool = await SessionPool.open(sessionPoolOptions);
// Получает сессию.
const session = await sessionPool.getSession();
// Увеличивает errorScore.
session.markBad();
// Отбрасывает сессию.
session.retire();
// Уменьшает errorScore и отмечает сессию как хорошую.
session.markGood();
Это основы настройки SessionPool. Важно помнить, что пулу сессий требуется время для поиска рабочих IP и формирования стабильного пула, поэтому на начальном этапе возможно большое количество ошибок, пока пул не стабилизируется.