2013-04-06 14 views
7

Tôi gặp sự cố khi chạy jQuery trong PhantomJS. Tôi đã tìm thấy câu trả lời this, mà nói về không có biến có sẵn bên trong chức năng đánh giá nhưng câu hỏi là về một mô-đun nút và trên ví dụ của tôi, tôi chỉ gọi console.log bên trong chức năng đánh giá. Tôi đã đặt câu hỏi này trên GitHub too.Trên PhantomJS Tôi không thể bao gồm jQuery và không có jQuery Tôi không thể đăng dữ liệu biểu mẫu

Trước đây, đối với một số trang, mã evaluate sau đây đã không thực thi. Bây giờ mà @ b1f56gd4 đã cung cấp một số trợ giúp, nó bây giờ in tin nhắn; Tôi không thể thực hiện được nhưng bây giờ tôi có thể thấy điều này:

Trang tại https://login.yahoo.com/ chạy nội dung không an toàn từ http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js.

Tôi không thể tải jQuery từ tên miền khác và các tùy chọn --local-to-remote-url-access=true hoặc --web-security=false không có sự khác biệt.

Tôi sẽ thử tải jQuery cục bộ. Đây là mã:

console.log('Loading a web page'); 
var url = 'https://login.yahoo.com/'; 
var page = require('webpage').create(); 
console.log('Setting error handling'); 
page.onConsoleMessage = function (msg) { 
    console.log(msg); 
}; 
page.onError = function (msg, trace) { 
    console.log(msg); 
    trace.forEach(function(item) { 
     console.log(' ', item.file, ':', item.line); 
    }) 
    phantom.exit(); 
} 
console.log('Error handling is set'); 
console.log('Opening page'); 
page.open(url, function (status) { 
    if (status != 'success') { 
     console.log('F-' + status); 
    } else { 
     console.log('S-' + status); 
     //-------------------------------------------------  
     var jsLoc = ''; 
     jsLoc = 'jquery.min.js'; // to load local 
     //jsLoc = 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'; // to load remote 
     var func = function(pg){ 
      console.log('Function called'); 
      console.log('Page evaluating'); 
      console.log(pg); 
      pg.evaluate(function() { 
       console.log('Page evaluate started');    
       //--- 
       var loginVar = '[email protected]'; 
       var pwdVar = 'itsmypass_445f4hd564hd56f46s'; 
       //--- 
       $("#login_form #username").value = loginVar; 
       $("#login_form #passwd").value = pwdVar; 
       //--- 
      }); 
      console.log('Rendering'); 
      pg.render('ystsA.png'); 
      console.log('Rendered'); 
     } 
     if (typeof jQuery == 'undefined') { 
      console.log('JQuery Loading'); // <<<<==== Execute only until here 
      console.log('Source:['+jsLoc+']'); 
      var rs = page.includeJs(jsLoc, function() // <<<<===== Fail here, jsLoc was changed to load locally and after tried remotely, i tried use page.injectJs but fail too 
      { 
       console.log('JQuery Loaded'); // <<<< ===== Never reach here, no matter if loading local or remote script in include above 
       func(page); 
      }); 
      page.render('ystsB.png'); 
     } else { 
      console.log('JQuery Already Loaded'); 
      func(page); 
      page.render('ystsC.png'); 
     } 
     //------------------------------------------------- 
    } 
    phantom.exit(); 
}); 

Sau khi đọc @ g4d564w56 câu trả lời tôi đã làm tất cả mà không có JQuery thì tôi có thể điền vào hộp văn bản nhưng không thể nhấp vào nút để đăng trên biểu mẫu đăng nhập.
Xem mã mới:

console.log('Loading a web page'); 
var url = 'https://login.yahoo.com/'; 
var page = require('webpage').create(); 
console.log('Setting error handling'); 
page.onConsoleMessage = function (msg) { 
    console.log(msg); 
}; 
page.onError = function (msg, trace) { 
    console.log(msg); 
    trace.forEach(function(item) { 
     console.log(' ', item.file, ':', item.line); 
    }) 
    phantom.exit(); 
} 
console.log('Error handling is set'); 
console.log('Opening page'); 
page.open(url, function (status) { 
    if (status != 'success') { 
     console.log('F-' + status); 
    } else { 
     console.log('S-' + status); 
     //-------------------------------------------------  
     var jsLoc = ''; 
     jsLoc = 'jquery.min.js'; // to load local 
     //jsLoc = 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'; // to load remote  
     var act01 = function(pg){ 
      console.log('Function called'); 
      console.log('Page evaluating'); 
      console.log(pg); 
      pg.evaluate(function() { 
       var getElmById = function(id){ 
        return document.getElementById(id); 
       }   
       console.log('Page evaluate started');    
       //--- 
       var loginVar = '[email protected]'; 
       var pwdVar = 'itsmypass_445f4hd564hd56f46s'; 
       //--- 
       getElmById("username").value = loginVar; 
       getElmById("passwd").value = pwdVar; 
       getElmById("login_form").submit(); /// <<<<==== now its dont work !!! 
       //--- 
      }); 
      console.log('Rendering'); 
      pg.render('ystsA.png'); 
      console.log('Rendered'); 
     } 
     act01(page); 
     //------------------------------------------------- 
    } 
    phantom.exit(); 
}); 
+0

Giải pháp ở đây: http://stackoverflow.com/questions/11121734/evaluate-doesnt-work/11121792#11121792 –

+0

@ b1f56gd4 Cảm ơn rất nhiều b1f56gd4. Vấn đề là phantmJs không thực thi console.log bên trong khối đánh giá theo mặc định, trang ở trên hiển thị mẹo lừa. Bây giờ tôi có thể nhìn thấy rất nhiều "Trang tại nội dung không an toàn chạy từ" và "JavaScript không an toàn để truy cập khung bằng URL từ khung với Tên miền URL, giao thức và cổng phải khớp.". Cảm ơn bây giờ tôi có thể xem và gỡ lỗi. – newway

+0

Tôi biết câu hỏi này là một năm cũ, nhưng đối với những người tìm kiếm câu hỏi này bằng cách tìm kiếm từ google vấn đề trong trường hợp cụ thể này là một tài nguyên http đang được sử dụng trong một trang https. Để tải jquery tất cả những gì bạn phải làm là sử dụng url https. – derickito

Trả lời

5

Tôi biết câu hỏi này đã được trả lời khoảng một năm trước, nhưng câu trả lời không thực sự giải quyết được vấn đề. Lý do cho sự lỗi dưới đây:

"Trang tại https://login.yahoo.com/ chạy nội dung không an toàn từ http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js."

Đó có phải là trang đăng nhập là trang https và bạn đang cố gắng tải một tài nguyên http. Nếu bạn thay đổi url thành https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js, lỗi này sẽ biến mất. Mất một lúc để tìm ra điều đó.

+1

Điều này đã giúp tôi loại bỏ lỗi "nội dung không an toàn chạy". Cảm ơn đống! – pauloz1890

1

Có một cũng biết lỗi PhantomJS tải không thể JQuery, sẽ khó có thể gửi một số dữ liệu mẫu đến máy chủ nhưng bạn có thể chọn các yếu tố duy nhất sử dụng querySelectorAll như ví dụ sau: how to scrape links with phantomjs

+0

Cảm ơn thông tin này, trên tìm kiếm của tôi không bao giờ tìm thấy thông tin này về lỗi này, không bao giờ tưởng tượng PhantomJS không thể tải JQuery vì nó là một trình duyệt không có đầu. Suy nghĩ về việc trở lại với HtmlUnit – newway

+5

Điều này là không đúng; PhantomJS có thể tải jQuery tốt, theo các ví dụ tại https://github.com/ariya/phantomjs/blob/master/examples/phantomwebintro.js và http://phantomjs.org/page-automation.html. Đôi khi 'page.includeJs (url_to_jquery, function() {...}' không hoạt động đối với tôi, và vì vậy tôi sử dụng 'page.injectJs (" ./ jquery.min.js ")' thay vì :-). – elimisteve

+0

@elimisteve Nếu tôi sao chép một dán mẫu tự động hóa trang vào một tệp và chạy '$ phantomjs sample.phantomjs'. Tôi nhận được thông báo "Truy cập JavaScript không an toàn với URL về: trống từ khung có URL". Cảm ơn bạn đã đề xuất về 'page.injectJs'. – Tobias

2

Hãy thử mã tiếp theo từ http://snippets.aktagon.com/snippets/534-How-to-scrape-web-pages-with-PhantomJS-and-jQuery. Nó tải một bản sao cục bộ của jQuery, nhưng cũng có thể sử dụng cá thể jQuery được tải bởi trang được yêu cầu.

var page = new WebPage(), 
    url = 'http://localhost/a-search-form', 
    stepIndex = 0; 

/** 
    * From PhantomJS documentation: 
    * This callback is invoked when there is a JavaScript console. The callback may accept up to three arguments: 
    * the string for the message, the line number, and the source identifier. 
    */ 
page.onConsoleMessage = function (msg, line, source) { 
    console.log('console> ' + msg); 
}; 

/** 
    * From PhantomJS documentation: 
    * This callback is invoked when there is a JavaScript alert. The only argument passed to the callback is the string for the message. 
    */ 
page.onAlert = function (msg) { 
    console.log('alert!!> ' + msg); 
}; 

// Callback is executed each time a page is loaded... 
page.open(url, function (status) { 
    if (status === 'success') { 
    // State is initially empty. State is persisted between page loads and can be used for identifying which page we're on. 
    console.log('============================================'); 
    console.log('Step "' + stepIndex + '"'); 
    console.log('============================================'); 

    // Inject jQuery for scraping (you need to save jquery-1.6.1.min.js in the same folder as this file) 
    page.injectJs('jquery-1.6.1.min.js'); 

    // Our "event loop" 
    if(!phantom.state){ 
     initialize(); 
    } else { 
     phantom.state(); 
    } 

    // Save screenshot for debugging purposes 
    page.render("step" + stepIndex++ + ".png"); 
    } 
}); 

// Step 1 
function initialize() { 
    page.evaluate(function() { 
    $('form#search input.query').val('Jebus saves'); 
    $('form#search').submit(); 
    console.log('Searching...'); 
    }); 
    // Phantom state doesn't change between page reloads 
    // We use the state to store the search result handler, ie. the next step 
    phantom.state = parseResults; 
} 

// Step 2 
function parseResults() { 
    page.evaluate(function() { 
    $('#search-result a').each(function(index, link) { 
     console.log($(link).attr('href')); 
    }) 
    console.log('Parsed results'); 
    }); 
    // If there was a 3rd step we could point to another function 
    // but we would have to reload the page for the callback to be called again 
    phantom.exit(); 
} 
+0

Cảm ơn bạn rất nhiều vì đã dành thời gian và giúp đỡ. Tôi đã thực hiện những thay đổi tối thiểu để làm cho nó thực thi trên một trang web thực sự, có thể tôi phá vỡ nó, nhưng khi tôi chạy mã nó không trả lại, ở lại giờ và không trở lại, chỉ có một ảnh chụp màn hình (đầu tiên) được thực hiện. dù sao cảm ơn rất nhiều. – newway

1

@lmeurs câu trả lời là rất tốt nhưng không hoạt động.
Tôi đã sử dụng câu trả lời để tạo nội dung nào đó cho bạn :).

var page = new WebPage(); 
var url = 'http://br.search.yahoo.com'; 
var stepIndex = 0; 

page.onConsoleMessage = function (msg, line, source) { console.log('console> ' + msg); }; 

page.onAlert = function (msg) { console.log('alert!!> ' + msg); }; 

function takeShot(){ 
    console.log("TakingShot"); 
    page.render("step" + stepIndex + ".png"); 
    console.log("ShotTake");  
} 

function step0() { 
    console.log("step 00 enter"); 
    page.evaluate(function() { 
     $("form [type='text']").val('its now sunday searching it'); 
     $("form [type='submit']").submit();  
    }); 
    console.log("step 00 exit"); 
} 

function step1() { 
    console.log("step 01 enter"); 
    page.evaluate(function() { 
     $('#search-result a').each(function(index, link) { 
      console.log($(link).attr('href')); 
     }) 
    }); 
    console.log("step 01 exit"); 
    phantom.exit(); 
} 

page.open(url, function (status) { 
    console.log("[- STARTING -]"); 
    if (status === 'success') { 
     var cmd = "" 
     page.injectJs('jquery-1.6.1.min.js'); 
     while(true) 
     { 
      console.log("Step["+stepIndex+"] starting on ["+new Date()+"]"); 
      //cmd = "var x = step"+stepIndex+";" 
      //console.log(cmd); 
      //eval(cmd); 
      switch(stepIndex){ 
       case 0: 
        step0(); 
        break; 
       case 1: 
        step1(); 
        break;     
      } 
      takeShot(); 
      stepIndex++; 
     }  
    } 
}); 
+0

Cảm ơn bạn rất nhiều vì đã dành thời gian và giúp đỡ. Tôi chạy mã của bạn như là, tôi không thay đổi không có gì, điều duy nhất tôi đã làm được đặt [jquery-1.6.1.min.js] tập tin trên cùng một thư mục của kịch bản của bạn. Nó chạy ok và quay trở lại, nó chụp màn hình tìm kiếm yahoo ở nhà như mong đợi ở bước 1 nhưng không in danh sách liên kết kết quả mong đợi từ bước 2, trên bước 2 của ảnh chụp màn hình trang chủ yahoo của nó một lần nữa, nó trông giống như không đăng đối số tìm kiếm trên yahoo hình thức. dù sao cảm ơn rất nhiều – newway

4

Phiên bản đang hoạt động bằng tìm kiếm google.

var page, doSearch, displayResults; 
page = require('webpage').create(); 

doSearch = function() { 
    console.log('Searching...'); 
    page.evaluate(function() { 
     $("input[name=q]").val('what is phantomjs'); 
     $("form").trigger('submit'); 
     return true; 
    }); 
    page.render('phantomjs-searching.png'); 
}; 

displayResults = function() { 
    console.log('Results...'); 
    page.evaluate(function() { 
     $('h3 a').each(function(i) { 
      console.log([i + 1, $(this).text(), ' // ' + $(this).attr('href')].join(': ')); 
     }); 
     return true; 
    }); 
    page.render('phantomjs-results.png'); 
}; 

page.onLoadFinished = function(status) { 
    if (status === 'success') { 
     page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', function() { 
      if (!phantom.state) { 
       doSearch(); 
       phantom.state = 'results'; 
      } else { 
       displayResults(); 
       phantom.exit(); 
      } 
     }); 
    } else { 
     console.log('Connection failed.'); 
     phantom.exit(); 
    } 
}; 

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

page.open('http://google.com');