Использование Perl Selenium :: Remote :: Driver для Javascript, который загружает страницу позже - PullRequest
1 голос
/ 01 ноября 2019

Я пытаюсь автоматизировать вход в систему https://strade.sharekhan.com

my $driver = Selenium::Remote::Driver->new;
$driver->get("https://strade.sharekhan.com/");

Я могу успешно открыть браузер Firefox и получить страницу. Но элементы ввода не видны.

my $page_source = $driver->get_page_source();

$driver->find_element('emailLoginId')->send_keys("abcdefg");

Кажется, что секция входа в систему находится внутри отдельного элемента класса, источник html которого появляется в отладчике браузера, но при попытке с помощью selenium элемент класса пуст,Я знаю только базовый Javascript / jQuery ... пожалуйста, помогите мне, что я пропускаю

my $login_element = $driver->find_element_by_class('loginresponsive');

Ответы [ 2 ]

1 голос
/ 02 ноября 2019

Вы всегда можете дождаться его появления.

Для Selenium :: Chrome написано следующее, но он демонстрирует переносимый принцип.

use constant POLL_INTERVAL => 0.1;

use Time::HiRes qw( sleep time );

sub wait_for {
   my ($xpath, $max_wait) = @_;
   my $wait_until = time() + $max_wait;
   while (1) {
      if ( my $nodes = nf_find_elements($xpath) ) {
         return wantarray ? @$nodes : $nodes->[0];
      }

      my $time_left = $wait_until -  time();
      return () if $time_left <= 0;

      sleep(min($time_left, POLL_INTERVAL));
   }
}


# Version of `find_elements` that doesn't die (non-fatal) when the element isn't found.
sub nf_find_elements {
   my $nodes;
   if (!eval {
      $nodes = $web_driver->find_elements(@_);
      return 1;  # No exception.
   }) {
      return undef if $@ =~ /Unable to locate element|An element could not be located on the page using the given search parameters/;
      die($@);
   }

   return wantarray ? @$nodes : $nodes;
}

Пример использования:

my $node = wait_for('//some/path', 4.0)   # Wait up to 4s
   or die("Login was unsuccessful.\n");

Time :: HiRes sleep не прерывается сигналами, поэтому я использовал следующее, чтобы сделать мой обработчик Ctrl-C отзывчивым:

use Time::HiRes qw( );

use constant SLEEP_INTERVAL => 0.1;

# Hi-res sleep that gives signal handlers a chance to run.
use subs qw( sleep );
sub sleep {
   if (!$_[0]) {
      Time::HiRes::sleep(SLEEP_INTERVAL) while 1;
      return;  # Never reached.
   }

   my $sleep_until = time() + $_[0];
   while (1) {
      my $time_left = $sleep_until - Time::HiRes::time();
      return if $time_left <= 0;

      Time::HiRes::sleep(min($time_left, SLEEP_INTERVAL));
   }
}

Убедитесь, чтоне импортировать sleep из Time :: HiRes.

0 голосов
/ 01 ноября 2019

Я проверил это с помощью Selenium :: Chrome , и, похоже, он работает нормально:

use strict;
use warnings;
use Selenium::Chrome;
# Enter your driver path here. See https://sites.google.com/a/chromium.org/chromedriver/
#  for download instructions
my $driver_path = '/home/hakon/chromedriver/chromedriver';
my $driver = Selenium::Chrome->new( binary => $driver_path );
$driver->get("https://strade.sharekhan.com/");
$driver->find_element_by_name('emailLoginId')->send_keys("abcdefg");
sleep 45;

Снимок экрана, снятый во время сна (см. Последнюю строку кода выше):

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...