PhantomJS: 프로그램 이 반응 하지 않 는 검사 과정 을 실행 합 니 다.

15411 단어 phantomjs자바 script
배경
최근 PhantomJS 를 접 하 게 되 었 습 니 다. 이 도 구 는 WebKit 기반 서버 엔 드 JavaScript API 라 고 들 었 습 니 다. 대부분의 브 라 우 저 를 실행 할 수 있 습 니 다. 잠시 도 지체 하지 않 고 연습 하고 싶 습 니 다. 그래서 프로그램 을 간단하게 썼 습 니 다. 간단하게 소개 하 겠 습 니 다.
  :   phantomJS         ,             ,  
  :
    1.   onResourceRequested,        t1,      ID,        
    2.   onResourceReceived         t2,           
    2. t2 - t1   ,             
    3.    ID     ,              url   

프로그램 소스 코드
test. js 내용 은 다음 과 같 습 니 다.
//    
var page = require('webpage').create();
var system = require('system');
var req = {};  //       
var res = {};  //       
var num = 0;   //        
var address = 'http://www.yaochufa.com';

//   onResourceRequested       
page.onResourceRequested = function(request){
    num++;   
    req[request.id] = {'url': request.url, 'time': request.time};
};

//   onResourceReceived       
page.onResourceReceived = function(response){
    res[response.id] = {'url': response.url, 'time': response.time};
};


//     
page.open(address, function(status){
    
    if(status !== 'success')
    {
        //       ,   
        console.log(status);
        phantom.exit(); 
    }
    else{
        console.log('      ');
    }
    //              ,             
    for(i=1;i<=num;i++)
    {
        //              ,        
        var req_time = new Date(req[i]['time']).getTime();

        //              ,        
        var res_time = new Date(res[i]['time']).getTime();
        
        //          
        var diff = res_time - req_time;
        console.log('ID:s',i, 'Loadtime:', diff, 'ms');

        //     ID url
        console.log(res[i]['url']);
    }
    phantom.exit();

});

문제 가 재현 되다
phantomjs test.js

#     :
ReferenceError: Can't find variable: sfCode

  http://qiniu-cdn7.jinxidao.com/assets/js/index.js?v=201704201643:1
      
ID:s 1 Loadtime: 73 ms
http://www.yaochufa.com/
ID:s 2 Loadtime: 50 ms
http://qiniu-cdn7.jinxidao.com/assets/css/common.css?v=201704201643
ID:s 3 Loadtime: 54 ms
http://qiniu-cdn7.jinxidao.com/assets/css/index.css?v=201704201643
ID:s 4 Loadtime: 80 ms
http://qiniu-cdn7.jinxidao.com/assets/js/jquery.js
ID:s 5 Loadtime: 78 ms
http://qiniu-cdn7.jinxidao.com/assets/js/lazyload.js
ID:s 6 Loadtime: 78 ms
http://qiniu-cdn7.jinxidao.com/assets/js/common.js?v=201704201643
ID:s 7 Loadtime: 150 ms
http://qiniu-cdn7.jinxidao.com/assets/js/index.js?v=201704201643
ID:s 8 Loadtime: 79 ms
http://qiniu-cdn7.jinxidao.com/js/user_analytics_pc.js?v=201704201643
ID:s 9 Loadtime: 154 ms
http://qiniu-cdn7.jinxidao.com/js/zhugeio_config.js?v=201704201643
ID:s 10 Loadtime: 106 ms
http://cdn7.jinxidao.com/images/icon.png?v=1.3
ID:s 11 Loadtime: 104 ms
http://cdn.jinxidao.com/images/icon/photo-app.png
ID:s 12 Loadtime: 100 ms
http://static.anquan.org/static/outer/image/hy_124x47.png
ID:s 13 Loadtime: 91 ms
http://cdn7.jinxidao.com/www/images/loading.gif
ID:s 14 Loadtime: 91 ms
http://cdn7.jinxidao.com/images/logo.png
ID:s 15 Loadtime: 94 ms
http://cdn7.jinxidao.com/www/images/weixin_code.png
ID:s 16 Loadtime: 92 ms
http://cdn7.jinxidao.com/www/images/footer-links.png
ID:s 17 Loadtime: 94 ms
http://cdn7.jinxidao.com/www/images/weixin_code.png?v=1.0
ID:s 18 Loadtime: 91 ms
http://cdn7.jinxidao.com/www/images/web-trust/alipay.png
ID:s 19 Loadtime: 91 ms
http://cdn7.jinxidao.com/www/images/web-trust/zhizhao.jpg
ID:s 20 Loadtime: 93 ms
http://cdn7.jinxidao.com/www/images/web-trust/chengxin.jpg
ID:s 21 Loadtime: 94 ms
http://cdn7.jinxidao.com/www/images/web-trust/kexin.jpg
ID:s 22 Loadtime: 87 ms
http://cdn.jinxidao.com/images/white_bg.png
ID:s 23 Loadtime: 91 ms
http://cdn.jinxidao.com/detail/appCode.png
ID:s 24 Loadtime: 94 ms
http://cdn.jinxidao.com/detail/appCode.png?v=3
ID:s 25 Loadtime: 64 ms
http://www.yaochufa.com/ajax/checkcity?v=1493041417771&callback=jQuery1113015539110638201237_1493041417766&_=1493041417767
ID:s 26 Loadtime: 64 ms
http://tj.yaochufa.com/kafkahttp/kafka/log?callback=jQuery1113015539110638201237_1493041417768&event_content=http%3A%2F%2Fwww.yaochufa.com%2F&log_id=1&app_id=4&longitude=&latitude=&user_id=&current_citycode=&upload_time=2017-04-24+21%3A43%3A37&event_time=1493041418&session_id=1493041418&current_url=http%3A%2F%2Fwww.yaochufa.com%2F&from_url=&use_agent=Mozilla%2F5.0+(Unknown%3B+Linux+x86_64)+AppleWebKit%2F538.1+(KHTML%2C+like+Gecko)+PhantomJS%2F2.1.1+Safari%2F538.1&visit_ip=114.55.70.153&cookie=38e73c28-09f1-2945-47d8-cbd70f3d72ff&arg2=&event_id=700000&_=1493041417769
ID:s 27 Loadtime: 73 ms
http://sdk.zhugeio.com/zhuge-lastest.min.js?v=2017324
ID:s 28 Loadtime: 136 ms
http://hm.baidu.com/hm.js?84c5b2688d39b4e3c23d132b53b4e79b
ID:s 29 Loadtime: 151 ms
https://apipool.zhugeio.com/web_event/?method=web_event_srv.upload&event=%7B%22type%22%3A%20%22statis%22%2C%22sdk%22%3A%20%22web%22%2C%22sdkv%22%3A%20%221.3.0%22%2C%22cn%22%3A%20%22web%22%2C%22vn%22%3A%20%221.0%22%2C%22ak%22%3A%20%22b744d4b142c942c09cdc5095ba060824%22%2C%22did%22%3A%20%2215ba0340eac38a-04e727ec2-273f781b-c0000-15ba0340ead40b%22%2C%22ts%22%3A%201493041417.903%2C%22debug%22%3A%201%2C%22data%22%3A%20%5B%0A%20%20%20%20%7B%22et%22%3A%20%22ss%22%2C%22sid%22%3A%201493041417.902%2C%22cn%22%3A%20%22web%22%2C%22vn%22%3A%20%221.0%22%2C%22pr%22%3A%20%7B%22os%22%3A%20%22Linux%22%2C%22br%22%3A%20%22Safari%22%2C%22rs%22%3A%20%221024*768%22%2C%22url%22%3A%20%22http%3A%2F%2Fwww.yaochufa.com%2F%22%7D%7D%0A%5D%7D&_=1493041417904
  ...

    앞의 출력, 우 리 는 이미 우리 의 요구 에 따라 자원 ID, 자원 로드 시간, 자원 URL 을 얻 은 것 을 보 았 습 니 다. 그런데 이상 한 일이 있 습 니 다. 약 30 이 되 었 을 때 멈 췄 습 니 다. 여 기 는 프로그램 이 끝 난 것 이 아 닙 니 다. 프로그램 끝 에 종료 가 있 기 때문에 정상적으로 끝나 면 종료 해 야 합 니 다. 그래서 저 는 이것 이 뭔 가 잘못 되 었 다 고 생각 합 니 다!이것 도 저 로 하여 금 phantomJS 가 매우 좋 지 않다 고 생각 하 게 하 는 부분 입 니 다. 잘못 보고 해도 뚜렷 한 오류 힌트 를 주지 않 고 어디 에 있 는 지 꼼 짝 도 하지 않 습 니 다.브 라 우 저 는 그 링크 를 전혀 열 수 없 기 때문에 계속 돌아 가 고 있 습 니 다. 무슨 이유 인지 모 르 겠 습 니 다. 그래서 우 리 는 console. log 로 잘못 배열 할 수 밖 에 없습니다!    출력 코드 가 맨 뒤에 있 기 때문에 앞의 이벤트 가 정확하게 실행 되 었 음 을 증명 할 수 있 습 니 다. 만약 에 앞의 이벤트 가 실패 하면 전체 프로그램 이 인쇄 되 지 않 고 반대로 앞 에 멈 춰 서 걸 립 니 다. 이 점 을 증명 하기 위해 우 리 는 for 순환 을 제거 하고 소스 코드 가 중복 되 지 않 으 며 결 과 를 직접 붙 입 니 다.
[root@iZ23pynfq19Z phantomjs-2.1.1-linux-x86_64]# ./bin/phantomjs 4.js 
ReferenceError: Can't find variable: sfCode

  http://qiniu-cdn7.jinxidao.com/assets/js/index.js?v=201704201643:1
      

씽 소 리 를 내 며 끝 났 습 니 다. 이것 은 우리 의 추측 을 검 증 했 습 니 다. 잘못된 코드 는 for 의 인쇄 안에 있어 야 합 니 다. 대략적인 방문 을 알 았 으 니 우리 for 안의 모든 코드 는 주석 을 달 고 한 마디 한 마디 씩 단독 적 으로 실 행 됩 니 다. for 순환 체 코드 는 다음 과 같 습 니 다.
    for(i=1;i<=num;i++)
    {
        //              ,        
        var req_time = new Date(req[i]['time']).getTime();  
    }
    phantom.exit();

----   1  :           ----

    for(i=1;i<=num;i++)
    {
        //              ,        
        var res_time = new Date(res[i]['time']).getTime();
    }
    phantom.exit();  
    
----   2  :      !!  ----

이 를 통 해 알 수 있 듯 이 문 제 는 두 번 째 문장 에서 시간 을 얻 는 곳 에 나타 나 야 하지만 여 기 는 문제 가 없 을 것 입 니 다. 실험 할 때 다른 시간 이 순조롭게 바 뀌 기 때 문 입 니 다!하지만 어 쩔 수 없어. 실험 만 이 증 거 를 제시 할 수 있어!우 리 는 이 말 을 두 마디 로 나 누 어 운행 한다.
    for(i=1;i<=num;i++)
    {
        //              ,        
        var res_time = new Date(res[i]['time'])
        console.log(res_time);
        console.log(res_time.getTime());
    }
    phantom.exit();
    
##     :
...
Mon Apr 24 2017 22:18:58 GMT+0800 (CST)
1493043538945
Mon Apr 24 2017 22:18:58 GMT+0800 (CST)
1493043538932
Mon Apr 24 2017 22:18:58 GMT+0800 (CST)
1493043538946
Mon Apr 24 2017 22:18:59 GMT+0800 (CST)
1493043539087
   ...

문제 가 정말 이 문제 에 나타 난 것 같 습 니 다. 그러나 이렇게 하면 문 제 를 볼 수 없습니다. 변수 가 정상적으로 출력 되 었 기 때 문 입 니 다!아무리 생각해 도 문 제 를 찾 을 수 없다 고 생각 하여 계속 위로 뜯 을 수 밖 에 없습니다. 이것 은 i 를 통 해 관련 배열 에서 대상 을 꺼 내 는 것 입 니 다. 그래서 우 리 는 위 에 인쇄 대상 을 추가 합 니 다.
    for(i=1;i<=num;i++)
    {
        //              ,        
        console.log(res[i]['time']);
        var res_time = new Date(res[i]['time'])
        console.log(res_time);
        console.log(res_time.getTime());
    }
    phantom.exit();
    
##     :
...
Mon Apr 24 2017 22:26:21 GMT+0800 (CST)
1493043981129
{"url":"https://apipool.zhugeio.com/web_event/?method=web_event_srv.upload&event=%7B%22type%22%3A%20%22statis%22%2C%22sdk%22%3A%20%22web%22%2C%22sdkv%22%3A%20%221.3.0%22%2C%22cn%22%3A%20%22web%22%2C%22vn%22%3A%20%221.0%22%2C%22ak%22%3A%20%22b744d4b142c942c09cdc5095ba060824%22%2C%22did%22%3A%20%2215ba05b2b444b7-0c599ec6d-273f781b-c0000-15ba05b2b454b1%22%2C%22ts%22%3A%201493043981.128%2C%22debug%22%3A%201%2C%22data%22%3A%20%5B%0A%20%20%20%20%7B%22et%22%3A%20%22ss%22%2C%22sid%22%3A%201493043981.126%2C%22cn%22%3A%20%22web%22%2C%22vn%22%3A%20%221.0%22%2C%22pr%22%3A%20%7B%22os%22%3A%20%22Linux%22%2C%22br%22%3A%20%22Safari%22%2C%22rs%22%3A%20%221024*768%22%2C%22url%22%3A%20%22http%3A%2F%2Fwww.yaochufa.com%2F%22%7D%7D%0A%5D%7D&_=1493043981128","time":"2017-04-24T14:26:21.273Z"}
Mon Apr 24 2017 22:26:21 GMT+0800 (CST)
1493043981273
Mon Apr 24 2017 22:26:21 GMT+0800 (CST)
1493043981132
undefined
    ..

원인 을 찾아내다
깜짝 발견 undefined, 응!undefined 에 getTime 방법 이 없어 서 프로그램 이 잘못 되 었 을 것 입 니 다. 해당 하 는 자원 ID 는 30 이 고 해당 하 는 url 은:https://apipool.zhugeio.com그런데 왜 이 대상 은 undefined 입 니까?그리고 자원 을 요청 하 는 것 은 확실히 있 습 니 다. 구 글 은 이것 이 자원 모니터링 사이트 라 는 것 을 발 견 했 습 니 다. 즉, 다른 사람 을 도와 자원 로드 속 도 를 테스트 하 는 것 과 비슷 합 니 다. 이 요 구 는 돌아 오지 않 았 습 니까?우선, 그것 이 undefined 인 이상 판단 을 통 해 걸 러 냅 시다.
    for(i=1;i<=num;i++)
    {
        //              ,        
        var req_time = new Date(req[i]['time']).getTime();
        //   undefned
        if(res[i])
        {
            //              ,        
            var res_time = new Date(res[i]['time']).getTime();
            //          
            var diff = res_time - req_time;
            console.log('ID: ',i, 'Loadtime:', diff, 'ms');
            //     ID url
            console.log(res[i]['url']);
        }
        else
        {
            console.log('ID: ' + i + ' no response');
        }

    } 
---      ---
.....
ID: 30 no response
ID:  31 Loadtime: 148 ms
https://apipool.zhugeio.com/web_event/?method=web_event_srv.upload&event=%7B%22type%22%3A%20%22statis%22%2C%22sdk%22%3A%20%22web%22%2C%22sdkv%22%3A%20%221.3.0%22%2C%22cn%22%3A%20%22web%22%2C%22vn%22%3A%20%221.0%22%2C%22ak%22%3A%20%22b744d4b142c942c09cdc5095ba060824%22%2C%22did%22%3A%20%2215ba0698d3a9f4-0797b7d87-273f781b-c0000-15ba0698d3b4b2%22%2C%22ts%22%3A%201493044923.712%2C%22debug%22%3A%201%2C%22data%22%3A%20%5B%0A%20%20%20%20%7B%22et%22%3A%20%22info%22%2C%22pr%22%3A%20%7B%22os%22%3A%20%22Linux%22%2C%22br%22%3A%20%22Safari%22%2C%22rs%22%3A%20%221024*768%22%2C%22url%22%3A%20%22http%3A%2F%2Fwww.yaochufa.com%2F%22%2C%22cn%22%3A%20%22web%22%2C%22vn%22%3A%20%221.0%22%7D%7D%0A%5D%7D&_=1493044923712
ID:  32 Loadtime: 37 ms
.....

이 스 크 립 트 는 정상적으로 실 행 될 수 있 습 니 다.뒤의 테스트 에서 나 는 만약 에 우리 가 onResource Received 에서 자원 ID 와 대상 을 인쇄 할 때 우리 가 앞에서 잃 어 버 린 30 번 대상 도 출력 이 있다 는 것 을 알 게 될 것 이다. 우리 가 한번 해 보 자.
page.onResourceReceived = function(response){
    console.log('ID: ' + response.id);
    //       JSON   
    console.log(JSON.stringify(response));
    res[response.id] = {'url': response.url, 'time': response.time};
};
---      ---
....(      )

//     
ID: 30
{"contentType":null,"headers":[],"id":30,"redirectURL":null,"stage":"end","status":null,"statusText":null,"time":"2017-04-24T14:52:08.402Z","url":"https://api.zhugeio.com/v1/events/codeless/appkey/b744d4b142c942c09cdc5095ba060824/platform/3?event_url=%2F"}

...

이 를 통 해 알 수 있 듯 이 자원 ID: 30 은 응답 이 있 습 니 다. 응답 이 비교적 느 릴 뿐 입 니 다. 순환 체 를 실행 하기 시 작 했 을 때 아직 쓰 기 를 완성 하지 못 했 습 니 다. JS 는 모두 가 알 고 있 는 비동기 프로 그래 밍 이기 때문에 우리 일반 프로그램 처럼 순서대로 실행 하지 않 고 리 셋 방식 으로 임 무 를 완성 합 니 다.
코드 소 최적화
    그것 도 호응 이 있다 는 것 을 알 았 으 니 우 리 는 그것 을 버 릴 수 없다!그것 도 우리 몫 이 니까!근 데 우리 어떻게 해 야 되 지?어 쩔 수 없 이 PhantomJS 홈 페이지 를 내 려 가 보 니 시범 사례 에 사 용 된 사건 이 있 습 니 다. onLoad Finished 는 불 러 오 는 것 을 완 료 했 을 때 이것 이 우리 가 찾 아야 할 것 같 습 니 다. 만약 에 페이지 로 딩 이 완료 되면 자원 에 있어 서 이미 다 받 았 을 것 입 니 다. 그러면 우 리 는 아까 스 크 립 트 를 개조 하고 스 크 립 트 의 for 를 분리 하기 시 작 했 습 니 다.onLoadFinished 이벤트 에 넣 으 면 코드 는 다음 과 같 습 니 다.
page.onLoadFinished = function(status){
    console.log('    ,   : ' + status);
    for(var i=1;i<=num;i++)
    {

        var req_time = new Date(result[i].time).getTime();
        if (rest[i])
        {
            var rest_time = new Date(rest[i].time).getTime();
            var diff = rest_time - req_time;
            console.log('ID:s',i, 'Loadtime:', diff, 'ms');
        }
        else
            //     
            console.log('\033[31mNo such response!\033[0m');
        console.log(result[i].url);
    }

};

위의 개 조 를 통 해 스 크 립 트 는 로 딩 시간 을 비교적 잘 계산 할 수 있 습 니 다. 그러나 우 리 는 최적화 해 야 할 부분 이 있 습 니 다. 그것 은 바로 주 소 를 입력 하 는 것 입 니 다. 주 소 는 죽은 것 이기 때문에 우리 가 다른 사 이 트 를 테스트 할 때 코드 를 수정 해 야 합 니 다. 이것 은 정말 큰 오류 입 니 다!그래서 시스템 라 이브 러 리 가 필요 해!전체 코드 는 다음 과 같 습 니 다:
//    
var page = require('webpage').create();
var system = require('system');
var req = {};  //       
var res = {};  //       
var num = 0;   //        
var args = system.args;
if (args.length !== 2)
{
    console.log('\033[31mUsage: Url ( http://www.baidu.com )\033[0m');
    phantom.exit();
}
var address = args[1];

//   onResourceRequested       
page.onResourceRequested = function(request){
    num++;
    req[request.id] = {'url': request.url, 'time': request.time};
};

//   onResourceReceived       
page.onResourceReceived = function(response){
    res[response.id] = {'url': response.url, 'time': response.time};
};

page.onLoadFinished = function(status){
    console.log('    ,   : ' + status);
    //              ,             
    for(var i=1;i<=num;i++)
    {
     var req_time = new Date(req[i].time).getTime();
        if (res[i])
        {
            var rest_time = new Date(res[i].time).getTime();
            var diff = rest_time - req_time;
            console.log('ID:s',i, 'Loadtime:', diff, 'ms');
        }
        else
            console.log('\033[31mNo such response! ID: ' + i + '\033[0m');
        console.log(req[i].url);
    }

};

//     
page.open(address, function(status){

    if(status !== 'success')
    {
        //       ,   
        console.log(status);
        phantom.exit();
    }
    else{
        console.log('      ');
    phantom.exit();
    }

});

그러나 가끔 은 느 린 요청 에 응답 하지 못 하고 실현 하 는 방향 을 바 꾸 거나 더욱 가 까 운 사건 이 발생 할 수 있 습 니 다. 그러나 이것 은 연습 하 는 데 정말 느낌 이 듭 니 다. 예전 에 PhantomJS 카드 가 죽 었 다 고 생각 했 습 니 다. 사실은 절차 가 잘못 되 었 을 뿐 입 니 다. 이번 에는 PhantomJS 에 대해 변 경 했 습 니 다. 이것 은 좋 은 도구 입 니 다. 앞으로 계속 깊이 공부 하 겠 습 니 다!여러분 의 큰 신의 조언 교 류 를 환영 합 니 다. 전 재 는 출처 를 밝 혀 주 십시오.https://segmentfault.com/a/11...

좋은 웹페이지 즐겨찾기