2014-10-22 19 views
23

Mở trang web và chụp ảnh màn hình.Chụp ảnh màn hình đáng tin cậy của các trang web? Phantomjs và Casperjs đều trả lại ảnh chụp màn hình trống trên một số trang web

Sử dụng phantomjs CHỈ: (đây là một kịch bản đơn giản, trên thực tế nó là ví dụ kịch bản sử dụng trong tài liệu của họ http://phantomjs.org/screen-capture.html

var page = require('webpage').create(); 
page.open('http://github.com/', function() { 
    page.render('github.png'); 
    phantom.exit(); 
}); 

Vấn đề là đối với một số trang web (như github) hài hước đủ được bằng cách nào đó phát hiện. .. và không phục vụ phantomjs và không có gì đã được trả lại kết quả là github.png là một file png trắng trống

Thay github với nói: "google.com" và bạn nhận được một đẹp (thích hợp) ảnh chụp màn hình như là để dành

.

Lúc đầu, tôi nghĩ rằng đây là một vấn đề Phantomjs vì vậy tôi cố gắng chạy nó thông qua Casperjs với:

casper.start('http://www.github.com/', function() { 
    this.captureSelector('github.png', 'body'); 
}); 

casper.run(); 

Nhưng tôi nhận được hành vi tương tự như với Phantomjs.

Vì vậy, tôi cho rằng đây có thể là vấn đề của tác nhân người dùng. Như trong: Github ngửi ra Phantomjs và quyết định không hiển thị trang. Vì vậy, tôi đặt tác nhân người dùng như bên dưới nhưng điều đó vẫn không hoạt động.

var page = require('webpage').create(); 
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'; 
page.open('http://github.com/', function() { 
    page.render('github.png'); 
    phantom.exit(); 
}); 

Vì vậy, sau đó tôi đã cố gắng để phân tích trang và dường như một số trang web (một lần nữa như github) dường như không được gửi bất cứ điều gì xuống dây.

Sử dụng casperjs Tôi đã cố gắng in tiêu đề. Và đối với google.com tôi đã quay lại Google nhưng đối với github.com tôi đã nhận lại bupkis. Mã ví dụ:

var casper = require('casper').create(); 

casper.start('http://github.com/', function() { 
    this.echo(this.getTitle()); 
}); 

casper.run(); 

Tương tự như trên cũng tạo ra kết quả tương tự trong các ma hoàn toàn.

Cập nhật:

Đây có phải là vấn đề về thời gian không? Là github chỉ siêu chậm? Tôi nghi ngờ nó nhưng cho phép kiểm tra anyway ..

var page = require('webpage').create(); 
page.open('http://github.com', function (status) { 
    /* irrelevant */ 
    window.setTimeout(function() { 
      page.render('github.png'); 
      phantom.exit(); 
     }, 3000); 
}); 

Và kết quả vẫn là bupkis. Vì vậy, nó không phải là một vấn đề thời gian.

  1. Làm cách nào để một số trang web như hình ảnh chặn github?
  2. Làm cách nào để chúng tôi có thể chụp ảnh màn hình TẤT CẢ các trang web một cách đáng tin cậy? Yêu cầu phải nhanh và không đầu.
+0

Các đáng tin cậy nhất có lẽ sẽ là một không đầu firefox giải pháp (watir/webdriver?) – pguardiario

+0

@pguardiario, nhờ ive thấy bài viết của mình. Trình điều khiển web Watir đã làm việc tốt cho tôi trong quá khứ, nhưng thường ở phía chậm hơn. Tôi đã sử dụng nó cho các bài kiểm tra và các công việc cào nhỏ ... Là cách dễ dàng để triển khai watir trên heroku hoặc ec2 trên một ứng dụng sản xuất? – fyz

+0

Tôi đã sử dụng watir-webdriver trên các phiên bản ec2 ubuntu và nó đã luôn luôn trở nên khó khăn. – pguardiario

Trả lời

26

Sau khi nảy ra xung quanh một thời gian, tôi đã có thể thu hẹp sự cố.Rõ ràng PhantomJS sử dụng ssl mặc định của sslv3 gây github từ chối kết nối do một cái bắt tay ssl xấu

phantomjs --debug=true github.js 

Hiển thị đầu ra của:

. . . 
2014-10-22T19:48:31 [DEBUG] WebPage - updateLoadingProgress: 10 
2014-10-22T19:48:32 [DEBUG] Network - Resource request error: 6 ("SSL handshake failed") URL: "https://github.com/" 
2014-10-22T19:48:32 [DEBUG] WebPage - updateLoadingProgress: 100 

Vì vậy, từ nay chúng ta có thể kết luận rằng không có màn hình đã được chụp bởi vì github đã từ chối kết nối. Tuyệt vời mà làm cho cảm giác hoàn hảo. Vì vậy, hãy thiết lập cờ SSL để --ssl-protocol=any và cho phép cũng bỏ qua ssl-lỗi với --ignore-ssl-errors=true

phantomjs --ignore-ssl-errors=true --ssl-protocol=any --debug=true github.js 

vĩ đại thành công! Một ảnh chụp màn hình hiện đang được trả lại và lưu đúng nhưng chương trình gỡ rối được cho chúng ta thấy một Lỗi Loại:

TypeError: 'undefined' is not a function (evaluating 'Array.prototype.forEach.call.bind(Array.prototype.forEach)') 

    https://assets-cdn.github.com/assets/frameworks-dabc650f8a51dffd1d4376a3522cbda5536e4807e01d2a86ff7e60d8d6ee3029.js:29 
    https://assets-cdn.github.com/assets/frameworks-dabc650f8a51dffd1d4376a3522cbda5536e4807e01d2a86ff7e60d8d6ee3029.js:29 
2014-10-22T19:52:32 [DEBUG] WebPage - updateLoadingProgress: 72 
2014-10-22T19:52:32 [DEBUG] WebPage - updateLoadingProgress: 88 
ReferenceError: Can't find variable: $ 

    https://assets-cdn.github.com/assets/github-fa2f009761e3bc4750ed00845b9717b09646361cbbc3fa473ad64de9ca6ccf5b.js:1 
    https://assets-cdn.github.com/assets/github-fa2f009761e3bc4750ed00845b9717b09646361cbbc3fa473ad64de9ca6ccf5b.js:1 

Tôi đã kiểm tra trang chủ github bằng tay chỉ để xem nếu một TypeError tồn tại và nó không.

Dự đoán tiếp theo của tôi là nội dung không tải đủ nhanh .. Phantomjs nhanh hơn một viên đạn tăng tốc!

Vì vậy, cho phép cố gắng làm chậm nó xuống nhân tạo và xem liệu chúng ta có thể thoát khỏi TypeError rằng ...

var page = require('webpage').create(); 
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'; 
page.open('http://github.com', function (status) { 
    window.setTimeout(function() { 
      page.render('github.png'); 
      phantom.exit(); 
     }, 3000); 
}); 

Đó không làm việc ... Sau khi kiểm tra chặt chẽ hơn của hình ảnh - nó rõ ràng là một số yếu tố bị thiếu. Chủ yếu là một số biểu tượng và logo.

Thành công? Một phần vì chúng tôi hiện đang ít nhất có được ảnh chụp màn hình ở nơi trước đó, chúng tôi đã không nhận được một điều gì.

Công việc đã hoàn thành? Không chính xác. Cần xác định nguyên nhân gây ra lỗi TypeError đó vì nó ngăn cản một số nội dung tải và bóp méo hình ảnh.

bổ sung

Đã cố gắng để tái tạo với CasperJS --debug là rất xấu xí và khó để làm theo so với PhantomJS:

casper.start(); 
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)'); 
casper.thenOpen('https://www.github.com/', function() { 
    this.captureSelector('github.png', 'body'); 
}); 

casper.run(); 

console:

casperjs test --ssl-protocol=any --debug=true github.js 

Tiếp tục hình ảnh thiếu các biểu tượng giống nhau nhưng cũng bị méo mó. Là CasperJs dựa vào Phantomjs, tôi không thấy giá trị trong việc sử dụng nó cho nhiệm vụ cụ thể này.

Nếu bạn muốn thêm vào câu trả lời của tôi, vui lòng chia sẻ phát hiện của bạn. Rất quan tâm đến một giải pháp hoàn hảo PhantomJS

Update # 1: Loại bỏ các @ArtjomB TypeError

chỉ ra rằng Phantomjs không hỗ trợ js bind trong đó là phiên bản hiện tại của bản cập nhật này (1.9.7).Vì lý do này, ông giải thích: ArtjomB: PhantomJs Bind Issue Answer

The TypeError: 'undefined' is not a function refers to bind, because PhantomJS 1.x doesn't support it. PhantomJS 1.x uses an old fork of QtWebkit which is comparable to Chrome 13 or Safari 5. The newer PhantomJS 2 will use a newer engine which will support bind. For now you need to add a shim inside of the page.onInitialized event handler:

Ok lớn, vì vậy đoạn mã sau sẽ chăm sóc TypeError của chúng tôi từ trên cao. (Nhưng không đầy đủ chức năng, xem dưới đây để biết chi tiết)

var page = require('webpage').create(); 
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'; 
page.open('http://github.com', function (status) { 
    window.setTimeout(function() { 
      page.render('github.png'); 
      phantom.exit(); 
     }, 5000); 
}); 
page.onInitialized = function(){ 
    page.evaluate(function(){ 
     var isFunction = function(o) { 
      return typeof o == 'function'; 
     }; 

     var bind, 
      slice = [].slice, 
      proto = Function.prototype, 
      featureMap; 

     featureMap = { 
      'function-bind': 'bind' 
     }; 

     function has(feature) { 
      var prop = featureMap[feature]; 
      return isFunction(proto[prop]); 
     } 

     // check for missing features 
     if (!has('function-bind')) { 
      // adapted from Mozilla Developer Network example at 
      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind 
      bind = function bind(obj) { 
      var args = slice.call(arguments, 1), 
       self = this, 
       nop = function() { 
       }, 
       bound = function() { 
       return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments))); 
       }; 
      nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined 
      bound.prototype = new nop(); 
      return bound; 
      }; 
      proto.bind = bind; 
     } 
    }); 
} 

Bây giờ các mã trên sẽ được chúng tôi ảnh chụp giống như chúng tôi đã nhận được trước khi VÀ debug sẽ không hiển thị một TypeError để khỏi bề mặt, mọi thứ dường như làm việc. Tiến độ đã được thực hiện.

Thật không may, tất cả biểu tượng hình ảnh [logo, v.v] vẫn không tải chính xác. Chúng tôi thấy một số loại biểu tượng 3W không chắc chắn nơi từ đó.

Thanks for the help @ArtjomB

enter image description here

+0

Bạn cũng có một vấn đề liên kết. Dưới đây là các giải pháp giảm cho [Casper] (http://stackoverflow.com/questions/25359247/casperjs-bind-issue/25359714#25359714) và cho [PhantomJS] (http://stackoverflow.com/questions/26382041/phantomjs-page-content-isnt-retrieving-the-page-content/26383058 # 26383058). –

+0

Xin cảm ơn, tôi nghi ngờ vấn đề liên kết là https có liên quan. Thử nghiệm với SetTimeout đến 10 giây với cùng một kết quả ... – fyz

+0

Mã bên trong 'page.onInitialized' thêm' bind' shim để bạn sẽ không nhận được TypeError trên trang và trang JS hoạt động đúng (nếu bạn tiếp tục cần phải làm gì đó trên trang). –

Các vấn đề liên quan