PhantomJS kullanarak form gönderme


161

Ben phantomJS (ne harika bir araç btw!) İçin giriş kimlik bilgileri olan bir sayfa için bir form göndermek ve sonra stdout hedef sayfanın içeriğini çıktı kullanmaya çalışıyorum. Forma erişebiliyorum ve fantom kullanarak değerlerini başarıyla ayarlayabiliyorum, ancak formu göndermek ve sonraki sayfanın içeriğini çıkarmak için doğru sözdiziminin ne olduğundan emin değilim. Şimdiye kadar sahip olduğum şey:

var page = new WebPage();
var url = phantom.args[0];

page.open(url, function (status) {

  if (status !== 'success') {
      console.log('Unable to access network');
  } else {

    console.log(page.evaluate(function () {

      var arr = document.getElementsByClassName("login-form");
      var i;

      for (i=0; i < arr.length; i++) {

        if (arr[i].getAttribute('method') == "POST") {
          arr[i].elements["email"].value="mylogin@somedomain.com";
          arr[i].elements["password"].value="mypassword";

          // This part doesn't seem to work. It returns the content
          // of the current page, not the content of the page after 
          // the submit has been executed. Am I correctly instrumenting
          // the submit in Phantom?
          arr[i].submit();
          return document.querySelectorAll('html')[0].outerHTML;
        }

      }

      return "failed :-(";

    }));
  }

  phantom.exit();
}

Yanıtlar:


228

Bunu anladım. Temelde bu zaman uyumsuz bir konudur. Bir sonraki sayfayı hemen gönderemez ve oluşturmayı bekleyemezsiniz. Bir sonraki sayfa için onLoad olayının tetiklenmesini beklemeniz gerekir. Kodum aşağıda:

var page = new WebPage(), testindex = 0, loadInProgress = false;

page.onConsoleMessage = function(msg) {
  console.log(msg);
};

page.onLoadStarted = function() {
  loadInProgress = true;
  console.log("load started");
};

page.onLoadFinished = function() {
  loadInProgress = false;
  console.log("load finished");
};

var steps = [
  function() {
    //Load Login Page
    page.open("https://website.com/theformpage/");
  },
  function() {
    //Enter Credentials
    page.evaluate(function() {

      var arr = document.getElementsByClassName("login-form");
      var i;

      for (i=0; i < arr.length; i++) { 
        if (arr[i].getAttribute('method') == "POST") {

          arr[i].elements["email"].value="mylogin";
          arr[i].elements["password"].value="mypassword";
          return;
        }
      }
    });
  }, 
  function() {
    //Login
    page.evaluate(function() {
      var arr = document.getElementsByClassName("login-form");
      var i;

      for (i=0; i < arr.length; i++) {
        if (arr[i].getAttribute('method') == "POST") {
          arr[i].submit();
          return;
        }
      }

    });
  }, 
  function() {
    // Output content of page to stdout after form has been submitted
    page.evaluate(function() {
      console.log(document.querySelectorAll('html')[0].outerHTML);
    });
  }
];


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

3
bu harika bir şablon. İşte eklediğim birkaç şey: iç setIntervalkullanım var func = steps[testindex], sonra console.log("step " + (testindex + 1) + ": " + funcName(func)). Bu, gerçekleştirilen adımlara açıklama eklemenizi sağlar.
Jonno

bakınız burada için funcName. Ayrıca, bir dizi web sayfası üzerinden geçerken ve farklı teknikler denerken son sayfayı kullanarak işlemeyi daha kolay buldum page.render("output.png");.
Jonno

2
Bu gerçekten yararlı bir gönderi. Yine de bir soru. POST kullanarak form gönderdiğinizde, veriler sunucuya gönderilir ve sunucu yanıt verir. Bu yanıtı ele aldığınız kod nerede veya otomatik olarak phantomjs tarafından mı yapılıyor? Ayrıca, form gönderdikten sonra bir sunucu geri dönebilir COOKIEve sorum şu: * phantom.cookiessunucu yanıt verdiğinde bu çerez nesnede kullanılabilir mi?
MrD

Kullanım CasperJS onun PhantomJS daha iyi, onun karmaşık kodlama olmadan formlara gönderme yetkisine
waza123

Lütfen bunu da kontrol edebilir misiniz stackoverflow.com/questions/44624964/phantom-js-on-web-project
Manik

62

Ayrıca, CasperJS, PhantomJS'de gezinme için bağlantılara tıklamak ve formları doldurmak da dahil olmak üzere güzel bir üst düzey arayüz sağlar.

CasperJS

PhantomJS ve CasperJS'yi karşılaştıran 28 Temmuz 2015 makalesini eklemek için güncellendi .

(Yorumcu Bay M'ye teşekkürler!)


1
Casper benim için çalışmadı çünkü sadece isim kullanarak bir form girişi doldurabiliyordun. Kimlik kullanmam gerekiyordu.
user984003

4
@ user984003 Seçicinizi #someidbir kimliğe göre dolduracak şekilde ayarlayabilmeniz gerekir .
arboc7

2
CasperJS bir nimettir! ASPX sayfalarını kazıma işlemini kolaylaştırır. Teşekkür ederim!
Tobia

@ user984003 Eski bir sürüm kullanıp kullanmadığınızı bilmiyorum, ancak geçerli sürümde herhangi bir seçici kullanarak form alanlarını doldurmak için bir fillSelectors () var.
Tobia

3
PhantomJS kullanan herkes CasperJS kullanmaya başlamalıdır. Nedenini açıklayan yazı: code-epicenter.com/why-is-casperjs-better-than-phantomjs
MrD

19

Ham POST istekleri göndermek bazen daha uygun olabilir. Aşağıda PhantomJS'den post.js orijinal örneğini görebilirsiniz

// Example using HTTP POST operation

var page = require('webpage').create(),
    server = 'http://posttestserver.com/post.php?dump',
    data = 'universe=expanding&answer=42';

page.open(server, 'post', data, function (status) {
    if (status !== 'success') {
        console.log('Unable to post!');
    } else {
        console.log(page.content);
    }
    phantom.exit();
});

6
Okuyucular, GETistekleri benzer şekilde gerçekleştirmenin (benzeri bir şey yaparak page.open(server, 'get', data, ...) işe yaramayacağını unutmayın.
zbr

7

Yukarıda belirtildiği gibi, CasperJS formları doldurmak ve göndermek için en iyi araçtır. Fill () işlevini kullanarak formu doldurma ve gönderme ile ilgili en basit örnek :

casper.start("http://example.com/login", function() {
//searches and fills the form with id="loginForm"
  this.fill('form#loginForm', {
    'login':    'admin',
    'password':    '12345678'
   }, true);
  this.evaluate(function(){
    //trigger click event on submit button
    document.querySelector('input[type="submit"]').click();
  });
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.