2016-09-12 2 views
0

Я пытаюсь реализовать шаблон стратегии у моего искателя, я думаю, что было бы аккуратно использовать разные стратегии для обхода разных сайтов. Поэтому я хочу, чтобы внутри page.evaluate отличалось в зависимости от того, какой веб-сайт работает в данный момент. Прокомментированный код внутри page.evaluate работает, но есть ли способ извлечь это в функцию? Я попытался запустить this.findJobs() без успеха.Использование шаблона стратегии в phantomjs

"use strict"; 

var Crawler = function() { 
    this.page = require('webpage').create(); 
    this.website = ""; 
    this.jobs_list = []; 

}; 

Crawler.prototype.setStrategy = function(company) { 
    this.website = company; 
}; 

Crawler.prototype.findJobData = function() { 
    return this.website.findJobData(); 
}; 

Crawler.prototype.collectJobData = function() { 
    var page = require('webpage').create(); 
    page.onConsoleMessage = function(msg) { console.log(msg) }; 

    page.open('URL', function (status) { 
     page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js", function() { 
      var temp_jobs = page.evaluate(this.findJobs()); 

       /* 
       var jobs = []; 
       var job; 
        $('ul.job-list').each(function(){ 
        $(this).find('li').each(function(){ 
         var job_link = $(this).find('a'); 
         var url = "URL" + job_link.attr("href"); 
         var location = $(this).find('span').text(); 

         job = {title: job_link.text(), url: url, location: location, description: ""} 
         jobs.push(job); 
         console.log(job.title, job.url, job.location); 
        }) 
       }); 
       return jobs;*/ 
      console.log(temp_jobs[0].title) 

      phantom.exit(0); 
     }); 
    }); 

}; 

var strategy_a = function() { 

    this.findJobs = function() { 
      var jobs = []; 
      var job; 
      $('ul.job-list').each(function(){ 
       $(this).find('li').each(function(){ 
        var job_link = $(this).find('a'); 
        var url = "URL" + job_link.attr("href"); 
        var location = $(this).find('span').text(); 

        job = {title : job_link.text(), url : url, location : location, description : ""}; 
        jobs.push(job); 
        console.log(job.title, job.url, job.location); 
       }) 
      }); 
      return jobs; 
    }; 
}; 


var strategy_a = new strategy_a(); 
var crawler = new Crawler(); 

crawler.setStrategy(strategy_a); 
crawler.collectJobData(); 

ответ

1

У вас есть две проблемы:

  • Вы имели в виду использовать page.evaluate(this.findJobs); вместо page.evaluate(this.findJobs()); и

  • this внутри page.includeJs обратного вызова не является ссылкой на Crawler инстанции.

Это должно работать:

Crawler.prototype.collectJobData = function() { 
    var page = this.page; 
    var self = this; 
    page.onConsoleMessage = function(msg) { console.log(msg) }; 

    page.open('URL', function (status) { 
     page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js", function() { 
      var temp_jobs = page.evaluate(self.website.findJobs); 
      console.log(temp_jobs[0].title) 

      phantom.exit(0); 
     }); 
    }); 
}; 

Обратите внимание, что вы сгенерировали несколько страниц без использования всех из них, так что я удалил второй require('webpage').create().

+0

я получаю следующее сообщение об ошибке при выполнении кода:/TypeError: не определен не является объект (оценка 'this.website.findJobs') неопределенной: 2 : 3 – Pierre

+1

Вашей 'функции Crawler.prototype.findJobData' бесполезно, потому что определенная функция 'findJobs' должна быть настроена для непосредственного использования в контексте страницы. Вы не можете использовать 'findJobData' для прокси-сервера для' findJobs', потому что 'page.evaluate' изолирован и не разрешает ссылки за пределами контекста страницы. Во всяком случае, я исправил свой ответ. –

+0

Спасибо за разъяснение. – Pierre

Смежные вопросы