#javascript #web-scraping #web-crawler #puppeteer #apify
Вопрос:
Фон
Я пытаюсь извлечь некоторый контент из prycd.com . Но перед этим мне нужно войти в мой prycd.com учетная запись, и тогда только я смогу получить доступ к этой странице. Для того же я использовал Apify с Puppeteer Crawler для автоматизации задачи.
Окружающая среда
- узел (v14.17.4)
- apify-cli (версия 0.6.2)
Пожалуйста, обратите внимание, что моим локальным компьютером является Macbook, но такая же проблема наблюдается и при запуске в Apify cloud.
Проблема
После того, как я запустил apify actor с помощью команды apify run -p
на моем локальном компьютере, кукловод пытается загрузить URL (https://www.prycd.com/comp-report ), которые я указал в начальных URL-адресах. Для загрузки этого URL-адреса пользователю необходимо войти в систему, чтобы в браузере было открыто наложение входа. Это наложение входа имеет 3 варианта аутентификации: аутентификация Google, аутентификация Facebook и собственная аутентификация.
Однако, когда я запускаю apify actor для загрузки этой страницы, кнопка аутентификации Facebook не загружается и выдает ошибку в консоли, показанной на рисунке ниже. Мне требуется только собственный логин для моей задачи, но поскольку кнопка аутентификации Facebook не загружается, я также не могу использовать собственный логин. Я попытался погуглить, чтобы узнать, сталкивались ли другие с подобной проблемой, но ничего не смог найти.
Ошибка, отображаемая в консоли
Испробованные подходы
Я пробовал различные подходы, с которыми я знаком, чтобы исправить эту проблему, но, похоже, ни один из них не работает. Вот некоторые операции, которые я пробовал:
- Методы защиты от соскабливания (снятие отпечатков пальцев в браузере, проверка наличия трекера и т. Д.)
- Прямой вызов API входа для получения токена сеанса.
- Пытался отключить загрузку кнопки социальной аутентификации (это не удалось сделать)
- Поиграл с заголовками запросов и CORS.
Пример фрагмента кода
/* eslint-disable indent */
const Apify = require('apify');
const { utils: { log, puppeteer } } = Apify;
Apify.main(async () => {
const { startUrls, email, password } = await Apify.getInput();
const requestList = await Apify.openRequestList('start-urls', startUrls);
const handlePageTimeoutSecs = 180; // 3 minutes;
// const proxyConfiguration = await Apify.createProxyConfiguration();
const width = 1280;
const height = 800;
const crawler = new Apify.PuppeteerCrawler({
requestList,
handlePageTimeoutSecs,
// proxyConfiguration,
useSessionPool: true,
persistCookiesPerSession: true,
launchContext: {
useChrome: true,
stealth: true,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
launchOptions: {
args: [
`--window-size=${width},${height}`,
],
},
},
preNavigationHooks: [
async (crawlingContext) => {
const { page, request } = crawlingContext;
const blockedUrlPatterns = [
'.jpg', '.jpeg', '.png', '.svg', '.gif', '.webp', '.webm', '.ico', '.woff', '.eot',
'.tff', '.woff2',
];
await puppeteer.blockRequests(page, {
urlPatterns: blockedUrlPatterns,
extraUrlPatterns: [],
});
},
],
handlePageFunction: async (context) => {
const { request: { url }, page } = context;
log.info('Processing:', { url });
// Wait for LOG IN form to show up
await page.waitForSelector('#switchToEmailLink_SM_ROOT_COMP1', {
visible: true,
timeout: 10000,
});
await Promise.all([
page.click('#switchToEmailLink_SM_ROOT_COMP1', { delay: 100 }),
]);
log.info('Signing in to prycd.com');
// Fill in email and password
await page.evaluate((a, b) => {
document.querySelector('#input_input_emailInput_SM_ROOT_COMP1').value = a;
document.querySelector('#input_input_passwordInput_SM_ROOT_COMP1').value = b;
}, email, password);
// Click LOG IN button
await Promise.all([
page.click('div#okButton_SM_ROOT_COMP1 > button', { delay: 100 }),
page.waitForNavigation(),
]);
},
handleFailedRequestFunction: async ({ request }) => {
log.warning(`Request ${request.url} failed too many times`);
},
postNavigationHooks: [
async (crawlingContext) => {
const { request, response, session } = crawlingContext;
// eslint-disable-next-line no-underscore-dangle
if (session.retireOnBlockedStatusCodes(response._status)) {
log.error(`Page didn't load for ${request.url}`);
}
},
],
});
log.info('Starting the crawl.');
await crawler.run();
log.info('Crawl finished.');
});
Любая помощь приветствуется.
Комментарии:
1. вы пробовали удалить
puppeteer.blockRequests
? возможно, какой-то gif-маяк, который может потребоваться для работы страницы. также вы, похоже, не используетеheadless: false
. старайтесь не жестко кодировать свой пользовательский агент, если это действительно необходимо2. @pocesar, я пробовал оба, т.Е. Удаление
blockRequests
изpreNavigationHooks
и также прошлоheadless: false
, но оба не сработали. Кроме того, причина, по которой я жесткоuser-agent
запрограммировал, заключалась в том, чтобы попробовать, была ли это проблема с отпечатками пальцев в браузере, но до этого я не использовал ее, но все равно не работал в обоих случаях.