2015-08-30 1 views
0

Я пытаюсь войти в Aliexpress через PhantomJS, но мой скрипт не работает, и я не могу понять, почему.Форма входа в iframe из Aliexpress не работает в PhantomJS

Я использую версию PhantomJS 2.0.0.

Форма входа находится внутри iframe, возможно, это проблема.

Это код:

var page = new WebPage(), step = 0, loadInProgress = false, timeOut = false; 
var url = 'https://login.aliexpress.com/buyer.htm?spm=2114.11040108.1000002.7.8yVuzJ&return=http%3A%2F%2Fcl.aliexpress.com%2F'; 

Функция заполнить и отправить форму внутри I-Frame.

var sendForm = function(){ 
    var iframeRef = function(frameRef) { 
     return frameRef.contentWindow 
      ? frameRef.contentWindow.document 
      : frameRef.contentDocument; 
    }; 

    var iframe = iframeRef(document.getElementById('alibaba-login-box')); 
    var arr = iframe.getElementById('login-form'); 
    arr.elements["fm-login-id"].value="my-email"; 
    arr.elements["fm-login-password"].value="my-password"; 
    iframe.getElementById('login-form').submit(); 
    console.log("Form submitted."); 
}; 

Эти шаги, которые следующим образом моя программа:

var onFinishedSteps = [ 
    //Opens the web to log-in. 
    function(){ 
     page.open(url); 
    }, 
    //Fills the form and submits it. 
    function(){ 
     page.render('0before fill.png'); 
     page.evaluate(sendForm); 
     page.render('1just after submit.png'); 
    }, 
    //Renders the web ~10 seconds after submitting. 
    function(){ 
     console.log("timeout setted"); 
     timeOut = true; 
     window.setTimeout(
      function() { 
       console.log("timeout function"); 
       page.render('2timeout.png'); 
       timeOut = false; 
      }, 
      10000 // wait 5,000ms (5s) 
     ); 
    } 
]; 

Первая веб-страница загружена, то форма заполняется и представляется (и услуг). Эти два шага работают нормально. Изображенные изображения отображают заполненные входы (адрес электронной почты и пароль) и содержимое i-кадра правильно.

Третий шаг должен предоставить программе достаточно времени для обработки формы и входа в систему, но отображаемое изображение по-прежнему показывает форму, на этот раз с пустым паролем и без сообщения (например, «неправильный пароль» или что-то в этом роде) ,

Это остальная часть программы:

page.onNavigationRequested = function(url, type, willNavigate, main) { 
    console.log('Trying to navigate to: ' + url); 
    console.log('Caused by: ' + type); 
    console.log('Will actually navigate: ' + willNavigate); 
    console.log('Sent from the page\'s main frame: ' + main); 
}; 

page.onLoadStarted = function() { 
    loadInProgress = true; 
}; 

page.onLoadFinished = function(status) { 
    loadInProgress = false; 
}; 

interval = setInterval(function() { 
    if (!loadInProgress && typeof onFinishedSteps[step] == "function") { 
     console.log("----------------------- Step " + (step + 1)); 
     onFinishedSteps[step](); 
     step++; 
    } 
    if (!loadInProgress && !timeOut && typeof onFinishedSteps[step] != "function") { 
     console.log("test complete!"); 
     phantom.exit(); 
    } 
}, 50); 

Вот ссылка с полным файлом, если вы хотите, чтобы проверить его. Github: https://github.com/xAlstrat/PhantomJsFunctions/blob/master/aliexlogin.js

+0

Вы действительно должны добавить '&&!timeOut' для обоих условий, а не только для одного из них. –

+0

Я использую версию 2.0.0. Я обновил код с этими событиями, но программа не обнаруживает ошибок. И вы правы с булевым состоянием, спасибо! Я добавил ссылку на весь код в описании вопроса. – Alstrat

ответ

1

Я думаю, проблема в том, что вы не можете вызвать функцию на элементе в другом кадре (iframe). Есть несколько вещей, которые вы можете попробовать.

  • Run PhantomJS с опцией --web-security=false командной строки:

    phantomjs --web-security=false script.js 
    
  • Изменение в контексте кадров, прежде чем пытаться сделать что-то в нем. Вы можете использовать page.switchToFrame() или другие подобные функции для изменения контекста кадра по имени или индексу кадра. Например:

    page.switchToFrame(1); // Try this out 
    page.evaluate(function(){ 
        var arr = document.getElementById('login-form'); 
        arr.elements["fm-login-id"].value="my-email"; 
        arr.elements["fm-login-password"].value="my-password"; 
        document.getElementById('login-form').submit(); 
        console.log("Form submitted."); 
    }); 
    

    Это производит синтетическое событие отправки.

  • Вы можете вызвать собственное событие отправки, инициировав нажатие клавиши ввода с помощью функции page.sendEvent(). Например, как это с предыдущим предложением:

    page.switchToFrame(1); // Try this out 
    page.evaluate(function(){ 
        var arr = document.getElementById('login-form'); 
        arr.elements["fm-login-id"].value="my-email"; 
        arr.elements["fm-login-password"].value="my-password"; 
        arr.elements["fm-login-password"].focus(); 
    }); 
    page.sendEvent("keypress", page.event.key.Enter); 
    
  • Может быть, вам даже нужно «типа» как имя пользователя и пароль, как родные события в поле, потому что просто установка значения полей не вызывает каких-либо событий, которые могли бы быть зарегистрированным на этих элементах. Что может вызвать проверки, которые могут быть необходимы, исчерпал до формы могут быть представлены:

    page.switchToFrame(1); // Try this out 
    
    page.evaluate(function(){ 
        document.getElementById("fm-login-id").focus(); 
    }); 
    page.sendEvent("keypress", "my-email"); 
    
    page.evaluate(function(){ 
        document.getElementById("fm-login-password").focus(); 
    }); 
    page.sendEvent("keypress", "my-password"); 
    
    page.evaluate(function(){ 
        document.getElementById("fm-login-password").focus(); 
    }); 
    page.sendEvent("keypress", page.event.key.Enter); // or page.event.key.Return 
    
+0

Привет! Я пробовал все эти вещи, но все равно он работает неправильно, просто немного отличается. Использование события 'Return' вместо 'click()' или 'submit()' кажется, работает лучше. Теперь после события возврата после ввода пароля появляется надпись. Я думаю, что это своего рода система безопасности, потому что я не получаю никакого кода с помощью обычного браузера, такого как хром. – Alstrat

+0

CAPTCHA специально предназначен для предотвращения того, что вы пытаетесь сделать. Существует действительно ничего простого, что вы можете сделать, чтобы решить эту проблему, показывая CAPTCHA пользователю как-то и позволить им решить эту проблему. –

+0

Большое спасибо за вашу помощь. Проблема была решена с помощью события return, но мне придется использовать другой подход для этой проблемы. – Alstrat