1 #!/usr/bin
/env phantomjs2
--ssl
-protocol
=any
--ignore
-ssl
-errors
=true --web
-security
=false
6 1 a web interaction step failed on user side
9 4 a web interaction step failed on navigator side
13 var llDebug
= 1, llVerbose
= 2, llError
= 3, llMsg
= 4;
15 var vlVerbose
= false;
18 var system
= require('system');
19 var stderr
= system
.stderr
;
20 var stdout
= system
.stdout
;
23 for(var i
=1; i
<system
.args
.length
; i
++)
25 if(system
.args
[i
] == '--debug') vlDebug
= true;
26 else if(system
.args
[i
] == '--verbose') vlVerbose
= true;
27 else if(system
.args
[i
].match(/^-/))
29 stderr
.write("Unknown option: "+system
.args
[i
]+"\n");
36 Glob
.telepules
= system
.args
[i
];
38 else if(!Glob
.date_from
)
40 Glob
.date_from
= system
.args
[i
];
42 else if(!Glob
.date_till
)
44 Glob
.date_till
= system
.args
[i
];
49 if(!Glob
.telepules
|| !Glob
.date_from
|| !Glob
.date_till
)
51 stderr
.write("Usage: nkm-aramszunet.js [--debug] [--verbose] <település> <dátum-tól> <dátum-ig>\n");
56 var url_form
= "https://www.mvmnext.hu/aram/pages/online/aramszunet.jsf";
57 var loadInProgress
= false;
59 var page
= new WebPage();
60 page
.settings
.userAgent
= "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.90 Safari/537.36 Vivaldi/1.91.867.38";
62 function log(level
, msg
)
64 if(level
== llDebug
&& vlDebug
||
65 level
== llVerbose
&& vlVerbose
||
66 level
== llError
&& vlError
||
67 level
== llMsg
&& vlMsg
)
69 stderr
.write(msg
+ "\n");
73 page
.onConsoleMessage = function(msg
)
75 if(msg
.match(/^\[DEBUG\]/))
77 else if(msg
.match(/^\[ERROR\]/))
80 log(llMsg
, ">>> " + msg
);
83 page
.onLoadStarted = function()
85 loadInProgress
= true;
86 log(llVerbose
, "load started [" + page
.url
+ "]");
89 page
.onLoadFinished = function()
91 loadInProgress
= false;
92 log(llVerbose
, "load finished <" + page
.evaluate(function(){return document
.title
;}) + "> [" + page
.url
+ "]");
95 page
.onError = function(msg
, stack
)
97 log(llError
, "ERROR: " + msg
+ "\nSTACK: " + JSON
.stringify(stack
));
100 page
.onResourceRequested = function(requestData
, networkRequest
)
102 /* allow only these domains, no trackers, no ads */
104 var g
= requestData
.url
.match(/^.+?:\/\/(.+?)(\/[^\?]*)/);
107 var hostpath
= host
+path
;
108 // google maps seem to needed for the page to work properly, but I worked it around
109 //if(hostpath == 'maps.google.com/maps/api/js') allow = true;
110 if(host
== 'www.mvmnext.hu') allow
= true;
113 log(llDebug
, "deny: " + requestData
.method
+ " " + requestData
.url
);
114 networkRequest
.abort();
117 if(requestData
.url
.match(/^https?:\/\/(maps\.google\.com)\//))
119 // mock out some base parts of gmaps lib
120 page
.evaluate(function(){
123 google
.maps
.MapTypeId
= {};
124 google
.maps
.MapTypeId
.ROADMAP
= {};
125 google
.maps
.LatLng = function(){ return {}; };
126 google
.maps
.InfoWindow = function(){ return {}; };
127 google
.maps
.Map = function(){ return {
128 'getBounds': function(){ return {}; },
130 google
.maps
.event
= { 'addListener': function(){ return {}; }, };
131 google
.maps
.Marker = function(){ return {
132 'setMap': function(){ return {}; },
134 console
.log("gmaps mocked.");
140 Glob
.inject
= 'function click(elem){'+
141 ' var ev = document.createEvent("MouseEvent");'+
142 ' ev.initMouseEvent("click", true /* bubble */, true /* cancelable */, window, null, 0, 0, 0, 0, /* coordinates */ false, false, false, false, /* modifier keys */ 0 /*left*/, null);'+
143 ' elem.dispatchEvent(ev);'+
145 'function grab_output(){'+
146 ' return document.querySelector(\'[id="aramszunetForm:aramszunetTable_data"]\').innerHTML;'+
148 'function grab_aramszunetTable(){'+
149 ' return document.querySelector(\'[id="aramszunetForm:aramszunetTable"]\').innerHTML;'+
154 page
.open(url_form
, function(status
)
156 if(status
!== 'success')
158 log(llError
, "ERROR " + status
);
167 /* Waiting page to load */
168 var input_telepules
= document
.querySelector('select[id="aramszunetForm:telepules_input"]');
171 //console.log(document.querySelectorAll('html')[0].outerHTML);
172 console
.log("Waiting for 'Település' field...");
179 // save the empty 'no results' table for comparasion later on
181 var noResults
= grab_aramszunetTable();
182 var rv
= {'result': {'aszt': noResults
}, 'jump': 1};
183 return JSON
.stringify(rv
);
187 console
.log("submitting form...");
188 var telepules_element
= document
.querySelector('li[data-label="' + param
.telepules
+ '"]');
189 if(!telepules_element
)
191 var msg
= "crawler: A település '" + param
.telepules
+ "' nincs a tervezett áramszünetek listájában."
193 var output
= "<tr><td>"+msg
+"</td></tr>";
194 return JSON
.stringify({'result': {'output': output
}, 'jump': 'end'});
197 /* Filling in form fields and submit */
198 click(telepules_element
);
199 document
.querySelector('input[id="aramszunetForm:startDate_input"]').value
= param
.date_from
;
200 document
.querySelector('input[id="aramszunetForm:endDate_input"]').value
= param
.date_till
;
202 // 3rd party components are celled via this method,
203 // ignore errors in 3rd parties (errors occur due to not loaded 3rd party scripts)
204 PrimeFaces
.ajax
.ResponseProcessor
.doEval = function(b
){
205 var a
= b
.textContent
|| b
.innerText
|| b
.text
;
206 try { $.globalEval(a
) }
207 catch(e
) { console
.log('Exception', e
); }
209 // the onClick event handler on the submit button looks like this:
210 //PrimeFaces.ab({s:"aramszunetForm:j_idt29",p:"aramszunetForm",u:"aramszunetForm:aramszunetTable aramszunetForm:filters"});
212 var submit_btn
= document
.querySelector('#aramszunetForm button');
218 // there were many trial-and-error here to find out how to set rows-per-page which PrimeFaces understands
219 console
.log("setting paginator rows per page to 1000...");
220 var rppdd
= document
.querySelector('select[name="aramszunetForm:aramszunetTable_rppDD"]');
221 var opt
= document
.createElement('option');
223 opt
.innerText
= "1000";
224 rppdd
.appendChild(opt
);
225 //rppdd.selectedIndex = rppdd.options.length - 1;
226 //opt.setAttribute('selected', 'selected');
227 rppdd
.value
= opt
.value
;
228 //rppdd.setAttribute('value', opt.value);
229 //$(rppdd).val(opt.value);
230 PrimeFaces
.widgets
.aramszunetTable
.paginator
.setRowsPerPage(opt
.value
);
231 //console.log("rppdd=", $(rppdd).val(), rppdd.value, rppdd.getAttribute('value'));
232 //opt.selected = true;
233 //$(rppdd).val(opt.value);$(rppdd).change();
235 //var ev = document.createEvent("HTMLEvents");
236 //ev.initEvent('change', true /* bubble */, true /* cancelable */);
237 //rppdd.dispatchEvent(ev);
243 console
.log("waiting 'aramszunetTable' to change...");
244 var aszt
= grab_aramszunetTable();
245 var rv
= {'result': {'aszt': aszt
}, 'jump': 0};
246 if(param
.aszt
!= rv
.result
.aszt
) {
249 return JSON
.stringify(rv
);
254 var rv
= {'result': {'output': grab_output()}, 'jump': 1};
255 return JSON
.stringify(rv
);
259 Glob
.total_steps
= steps
.length
;
266 /* Execute next step in navigator's context */
267 log(llDebug
, "step " + stepindex
);
268 var ret
= page
.evaluate(steps
[stepindex
], Glob
);
274 else if(ret
=== undefined || ret
=== null)
279 if(typeof ret
!= "number")
281 ret
= JSON
.parse(ret
);
282 for(var key
in ret
.result
)
284 Glob
[key
] = ret
.result
[key
];
289 log(llDebug
, "step " + stepindex
+ " jump " + ret
);
290 if(ret
== 'end') stepindex
= steps
.length
;
291 else stepindex
+= ret
;
293 if(stepindex
>= steps
.length
)
295 stdout
.write(Glob
.output
);
296 log(llDebug
, "completed");
301 setTimeout(worker
, timeout
);
303 setTimeout(worker
, timeout
);