Кнопка аутентификации Facebook не загружается в браузере Chromium, созданном Apify PuppeteerCrawler

#javascript #web-scraping #web-crawler #puppeteer #apify

Вопрос:

Фон

Я пытаюсь извлечь некоторый контент из prycd.com . Но перед этим мне нужно войти в мой prycd.com учетная запись, и тогда только я смогу получить доступ к этой странице. Для того же я использовал Apify с Puppeteer Crawler для автоматизации задачи.

Окружающая среда

  1. узел (v14.17.4)
  2. 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 и собственная аутентификация.

Экран входа в prycd.com

Однако, когда я запускаю apify actor для загрузки этой страницы, кнопка аутентификации Facebook не загружается и выдает ошибку в консоли, показанной на рисунке ниже. Мне требуется только собственный логин для моей задачи, но поскольку кнопка аутентификации Facebook не загружается, я также не могу использовать собственный логин. Я попытался погуглить, чтобы узнать, сталкивались ли другие с подобной проблемой, но ничего не смог найти.

Ошибка, отображаемая в консоли

Испробованные подходы

Я пробовал различные подходы, с которыми я знаком, чтобы исправить эту проблему, но, похоже, ни один из них не работает. Вот некоторые операции, которые я пробовал:

  1. Методы защиты от соскабливания (снятие отпечатков пальцев в браузере, проверка наличия трекера и т. Д.)
  2. Прямой вызов API входа для получения токена сеанса.
  3. Пытался отключить загрузку кнопки социальной аутентификации (это не удалось сделать)
  4. Поиграл с заголовками запросов и 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 запрограммировал, заключалась в том, чтобы попробовать, была ли это проблема с отпечатками пальцев в браузере, но до этого я не использовал ее, но все равно не работал в обоих случаях.