Обход блокировки при парсинге
У меня есть довольно простой код на puppeteer:
const BookAppointment = async () => {
puppeteer.use(pluginStealth())
const proxy = await getProxy()
const {cookies, userAgent} = await setupProxy(proxy)
const browser = await puppeteer.launch({
slowMo: 10,
headless: false,
args: [
`--start-maximized`,
`--proxy-server=${proxy}`,
],
})
const page = await browser.newPage();
await page.setCookie(...cookies)
await page.setExtraHTTPHeaders({
"User-Agent": userAgent,
})
await page.goto(`https://icp.administracionelectronica.gob.es/icpplus/index.html`, { waitUntil: 'networkidle2' })
await page.waitForSelector("#form")
await page.waitForTimeout(2200)
await page.select("#form", "/icpplus/citar?p=2&locale=es")
await page.waitForTimeout(2200)
await Promise.all([page.click("#btnAceptar"), page.waitForNavigation({waitUntil:'networkidle2'})])
await page.waitForSelector("#sede")
await page.waitForTimeout(2200)
await Promise.all([page.select("#sede", "2"), page.waitForNavigation({waitUntil:'networkidle2'})])
await page.waitForSelector(".mf-input__l")
await page.waitForSelector("#btnAceptar")
await page.select(".mf-input__l", "4112")
await page.waitForTimeout(2200)
await Promise.all([page.click("#btnAceptar"), page.waitForNavigation({waitUntil:'networkidle2'})])
await page.waitForSelector("#btnEntrar")
await page.waitForTimeout(2200)
await page.click("#btnEntrar")
await page.waitForSelector("#txtIdCitado")
await page.waitForSelector("#txtDesCitado")
await page.waitForSelector("#btnEnviar")
await page.type("#txtIdCitado", "Z0563935A")
await page.waitForTimeout(2200)
await page.type("#txtDesCitado", "KATERINA SOLODA" )
await page.waitForTimeout(2200)
await Promise.all([page.click("#btnEnviar"), page.waitForNavigation({waitUntil:'networkidle2'})])
await page.waitForSelector("#btnEnviar")
await page.waitForTimeout(2200)
await Promise.all([page.click("#btnEnviar"), page.waitForNavigation({waitUntil:'networkidle2'})])
await page.waitForSelector("#txtTelefonoCitado")
await page.waitForTimeout(2200)
await page.type("#txtTelefonoCitado", "653615024")
await page.type("#emailUNO", "[email protected]")
await page.type("#emailDOS", "[email protected]")
await page.waitForTimeout(2200)
await Promise.all([page.click("#btnSiguiente"), page.waitForNavigation({waitUntil:'domcontentloaded'})])
await page.waitForSelector("#btnSiguiente")
await page.waitForSelector("#cita1")
try {
const element = await page.waitForSelector(".img-thumbnail", {timeout: 5000})
await page.waitForTimeout(randomTimeout())
await element.screenshot({
path: `post_image_1.jpg`
})
const key = await solveCaptcha(`post_image_1.jpg`)
await page.type("#captcha", key)
} catch(e) {
console.log(e)
}
await page.click("#cita1")
await page.click("#btnSiguiente")
await page.waitForTimeout(2000)
await page.waitForSelector(".btn")
await page.click(".btn")
await page.waitForTimeout(10000)
await Promise.all([page.goto("https://icp.administracionelectronica.gob.es/icpplus/index.html"), page.waitForNavigation({waitUntil:'domcontentloaded'})])
const pageCookies = await page.cookies()
writeProxyCookies(pageCookies, proxy)
}
Эта функция запускается множество раз, при этом сохраняя куки страницы на локалку. Иногда сервер вообще не блокирует запросы, но чаще всего он кидает вот такое:
The requested URL was rejected. Please consult with your administrador.
Your support ID is: < 2580972395890823306>
[Go Back]
после двух-трех запросов. Сервер дропает запросы в простом браузере только в том случае, если удалить все куки, и сделать несколько запросов(и даже так количество запросов после удаления кук может варьироваться от 1 до 20). Сервер использует JSESSIONID для идентификации пользователя. Но как только я пробую зайти на сайт из под puppeteer, сразу начинается жуть. Я сравнивал хедеры запроса из простого хрома и puppeteer, отличаются только 2 хедера: Pragma и Cache-Control. В простом браузере они установлены в no-cache, а в puppeteer Cache-Control: max-age=0, а Pragma вообще нет.. Если я добавляю эти хедеры в puppeteer, то сервер моментально дропает все запросы.
Я так же пытался избежать паттернизации трафика, путем отправления рандомных запросов между этапами парсинга, но это ничего не меняет. Есть подозрение, что сервер использует какой-то WAF.
Я бы хотел получить какие-то рекомендации, советы или ресурсы, на которых есть информации про обходы подобных систем безопасности, ибо прошерстил кучу статей, и везде пишут только про сохранение кук между сессиями, изменение хедеров запросов, использование прокси и избежание паттернизации.
Весь код находится в репо: https://github.com/pauf419/SedeAutomateTest Сервер пропускает трафик только из Дании, Франции, Чехии, Испании и Эстонии.
Заранее спасибо за предоставленную помощь