
サイトを解析するためのツールとして、SlimerJSを使用します。
私は、できるだけ単純化された普遍的な形で可能な限り例を挙げようとしました。
エントリポイント:
このファイルの最初の部分は、SlimerJsの作業に関連する一般的なロジックです
script.js
var grab = require('./grab'); // grab.create().init('/catalog'); //
ここでは、パーサーモジュールが接続および初期化され、製品カタログページのURLがinit()メソッドに渡されます。リンクは相対的です。 メインサイトドメインはconfig.jsファイルで設定されます
すべてのパーサーロジックはgrab.jsファイルにあります 私はそれを2つの部分に分けました。最初の部分は、SlimerJSのオブジェクトラッパーで、ブラウザーの複数のコピーを同時に操作するためのものです。
コードの理解を簡単にするために、コードに関するすべてのコメントをリストに入れました。
grab.js
var file = require("./file").create(); // var config = require("./config").getConfig(); // /** * - */ function Grab() { this.page; // "webpage" this.current_url; // URL this.parentCategory; // /** * * @param url string ( /contacts ) * @param parent */ this.init = function(url, parent) { this.page = require("webpage").create(); // webpage this.callbackInit(); // callback webpage if(url) { // , config.host += url; } this.parentCategory = parent; this.open(config.host); // URL }; /** * URL * @param {string} url */ this.open = function(url) { /* * */ this.page.open(url); }; /** * */ this.close = function() { this.page.close() }; /** * callback */ this.callbackInit = function() { var self = this; /** * * @param {string} message error * @param {type} stack */ this.page.onError = function (message, stack) { console.log(message); }; /** * * @param {string} url URL */ this.page.onUrlChanged = function (url) { self.current_url = url; // URL }; /** * , webpage console.log() * @param {string} message * @param {type} line * @param {type} file */ this.page.onConsoleMessage = function (message, line, file) { console.log(message); // }; /** * * @param {string} status */ this.page.onLoadFinished = function(status) { if(status !== 'success') { console.log("Sorry, the page is not loaded"); self.close(); } self.route(); // }; }; }
ファイルの2番目の部分は動作を定義し、作成されたGrabオブジェクトを拡張します
Grab.prototype.route = function() { try { // if(this.isCategoryPage()) { var categories = this.getCategories(); // file.writeJson(config.result_file, categories, 'a'); // for (var i = 0; i < categories.length; i++) { // var url = categories[i].url_article; // URL new Grab().init(url, categories[i].title); // slimer.wait(3000); // 3 , } } else { // var content = this.getContent(); // file.writeJson(config.result_file, content, 'a'); // this.close(); // } this.close(); } catch(err) { console.log(err); this.close(); } }; /** * , * @returns {Object} */ Grab.prototype.getCategories = function() { return this.getContent('categories') }; /** * , * @returns {bool} */ Grab.prototype.isCategoryPage = function() { return this.page.evaluate(function() { // , , return !$(".catalog-list .item .price").length; }); }; /** * * @param {string} typeContent {categories|product} * @returns {Object} */ Grab.prototype.getContent = function(typeContent) { var result = this.page.evaluate(function(typeContent) { var result = []; // , ( ) $(".catalog-list .item").each(function(key, value) { var $link = $(value).find('a.name'); // var obj = { // 'type': 'category', 'title': $link.text().trim().toLowerCase(), // 'url_article': $link.attr('href'), // 'url_article_image': $(value).find('a.img > img').attr('src') }; // , if(typeContent !== 'categories') { obj.size = []; obj.type = 'product'; $('.razmers:first .pink').each(function(key, value) { // ||... obj.size.push($(value).text().trim()); }); obj.price = parseInt($(value).find('.price').text(), 10); // } result.push(obj); }); return result; }, typeContent); return result; }; exports.create = function() { return new Grab(); };
ファイルシステムとの便利な作業のために、SlimerJSはデータの読み取りと書き込みの両方を可能にするAPIを提供します
file.js
var fs = require('fs'); /** * */ function FileHelper() { /** * * @param {string} path_to_file * @returns array - */ this.read = function(path_to_file) { if(!fs.isFile(path_to_file)){ throw new Error('File ('+path_to_file+') not found'); } var content = fs.read(path_to_file); if(!content.length) { throw new Error('File ('+path_to_file+') empty'); } return content.split("\n"); }; /** * * @param {string} path_to_file * @param {string} content * @param {string} mode 'r', 'w', 'a/+', 'b' */ this.write = function(path_to_file, content, mode) { fs.write(path_to_file, content, mode); } /** * JSON * @param {string} path_to_file * @param {array} content * @param {string} mode 'r', 'w', 'a/+', 'b' */ this.writeJson = function(path_to_file, content, mode) { var result = ''; for(var i=0; i < content.length; i++) { result += JSON.stringify(content[i]) + "\n"; } this.write(path_to_file, result, mode); } } exports.create = function() { return new FileHelper(); };
最後のファイルは、システム全体に共通の変数を指定できる構成ファイルです
config.js
var Config = function() { this.host = 'http://example.ru'; this.log_path = 'logs\\error.txt'; this.result_file = 'result\\result.txt'; }; exports.getConfig = function() { return new Config(); };
作業の結果は、さらにデータをエクスポートするために処理できるファイルの形式になります。
スクリプトは、コンソールからのコマンドによって実行されます
slimerjs script.js
