I was try to create a web screenshot with phantomjs,But alwaise it result a blank image.I am using Fedora OS.Here is my javascript.
screen.js
var WebPage = require('webpage');
page = WebPage.create();
page.open('http://google.com');
page.onLoadFinished = function() {
page.render('googleScreenShot' + '.png');
phantom.exit();}
And here is my php code
shot.php
$exec = '/var/www/html/test/bin/phantomjs /var/www/html/test/screen.js';
$escaped_command = escapeshellcmd($exec);
exec($escaped_command);
But the created image was blank.phantomjs have executre permission.Please help me
I am not sure but this may work,try it
var WebPage = require('webpage');
page = WebPage.create();
page.open('http://google.com');
page.onLoadFinished = function() {
window.setTimeout(function () {
page.render('googleScreenShot' + '.png');
phantom.exit();
}, 2000);
}
You have a problem because the time your code execute the next line of code is more faster than phantomjs logging that page.onLoadStarted is True.
easy and clean way to fix this is by adding a time interval of 100 ms between each function and make all your code in functions, check Vijay Boyapati method for more clarification : https://stackoverflow.com/a/9256079/1738230
In dealing with this problem I completed a code module, as follows:
link
You can download it locally, and then invoke it by command
phantomjs rasterize.js "http://www.google.com" 800px*800px > wait.html
Related
I am trying to program a Cron Job that fetches some data from multiple websites. The script uses phantomjs that runs a js file responsible for saving each website's content to a file locally.
My cron job command:
/usr/local/bin/php /home/user/public_html/fetch.php >> /home/user/public_html/fetch-log.txt
fetch.php
ini_set('max_execution_time', 300);
require_once 'Utils.php';
$sources = Utils::get_sources();
foreach ($sources as $source) {
$cmd = "/home/user/bin/phantomjs get-website.js '$source->url' $source->id";
exec($cmd);
}
echo date("Y-m-d H:i:s") . ">> Done fetching sources\n";
get-website.js
var system = require('system');
var webPage = require('webpage');
var fs = require('fs');
var page = webPage.create();
var url = system.args[1];
var file = system.args[2];
var requestsArray = [];
page.onResourceRequested = function (requestData, networkRequest) {
requestsArray.push(requestData.id);
};
page.onResourceReceived = function (response) {
var index = requestsArray.indexOf(response.id);
requestsArray.splice(index, 1);
};
page.open(url, function (status) {
var interval = setInterval(function () {
if (requestsArray.length === 0) {
clearInterval(interval);
try {
fs.write("/home/user/public_html/rss_contents/" + file + ".txt", page.content, 'w');
} catch (e) {
console.log(e);
}
phantom.exit();
}
}, 500);
});
The script works normally when running from browser, and the cron job also works normally when run with a simple echo("done"); php script, but when I try to run the cron job with the fetch.php script, the last line is echoed to the file, but nothing has happen.
I am using shared hosting.
EDIT:
When trying to run phantomjs from ssh console directly, I get this error
2019-06-27T11:34:12 [WARNING] QThread::start: Thread creation error:
Resource temporarily unavailable
And the console just hangs without any response.
I couldn't find any posts talking about this warning on Google.
I need to get the items(with selector a[id=test]) from the page that is loaded by ajax. For this I use phantomjs.
In PHP:
$phantom_path = '/usr/bin/phantomjs';
$names = shell_exec("$phantom_path model/phantomscript-names.js $url");
in phantomjs i received items:
var page = require('webpage').create(),
system = require('system'),
url = system.args[1];
page.open(url, function(status) {
page.injectJs('jquery-2.1.4.min.js');
var links = page.evaluate(function() {
return [].map.call(document.querySelectorAll('a[id=test]'), function(link) {
return link.innerText;
});
});
console.log(links.join('\n'));
phantom.exit();
});
the script runs for about a minute for each page.
whether it is possible to reduce this time using phantomjs or i need to use another tool for this?
On some sites I've found this benefits the load time on Phantom JS.
on other sites the images still come up and it makes no difference.
page.settings.loadImages = false;
I am a newbie to jQuery / javascript and I had this working without checking the window size first. Then messed around with it and can not get it to work. The redirect is supposed to replace mysite.com/index.php?querystring with mysite.com/mobile.php?querystring if screen size is less then 699. Please help. Thank You.
This function seems to work exaclty how I need it but need to have onload with if screen size is less then.
$('a').each(function(index, a) {
var href = $(a).attr('href');
$(a).attr('href', 'http://mysite.com/mobile.php?redirect=' + href;)
}
}
//below is not working
function checkWidth() {
var windowSize = $(window).width();
if (windowSize <= 699) {
window.onload = function() {
/* onload code */
// Execute on load
//checkWidth();{
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
anchors[i].href = "http://mysite.com/mobile.php?redirect=" + anchors[i].href
/* function checkWidth() {
var windowSize = $(window).width();*/
}
}
If you intend on using jQuery, this should work:
$(document).ready(function() {
var window_width = $(window).width();
if( window_width < 699 ) {
$('a').each(function(index, a) {
var href = $(a).attr('href');
$(a).attr('href', 'http://mysite.com/mobile.php?redirect=' + href;
});
}
});
This is really something you should be doing server-side. Because someone isn't exactly going to be switching the device over the course of the session, you should check the device when they first visit the site, and then create a session variable storing it. Then, on every new page have the server check the variable and use it to determine which links to put in. If you're content with doing it client-side, though, Ryan Pilbeam's answer should work.
I'm using jQuery + PHP on my website and I want to do something like this:
To simplify things I've got a page with 2 buttons () and according to which I click I want to start a script in background (php script) so I do a simple thing with jquery:
$("#button1").click(function(){
$.post("script.php", {val:"but1"}, function(result){
alert(result); // I want something with the result
});
});
$("#button2").click(function(){
$.post("script.php", {val:"but2"}, function(result){
alert(result);
});
});
and in the script.php I've got a simple if statement deciding what I should do.
In the php script I'm downloading a file and I want to create a progress bar of the file download. The php script would return me values (echo percentage; flush();) in some time interval.
And here comes the problem - when I echo those percentage values and flush it refreshes it "just in php" but the jquery waits until the script is finished anyway. Is there a way to get those values as they appear (after flush) or is there a completely other approach to this? I can't think of anything else right now, maybe I shouldn't be using jquery at all.
Thanks for the help.
You can store the progress in a text file or DB while running the script and then have another file get the result via AJAX calls.
JS/HTML
<script>
$(function() {
var id;
var timeoutLength = 1000;
$("#button1").click(function() {
$("#result").html("");
// Create unique identifier
id = (new Date().getTime()) + "-" + Math.floor(Math.random()*100);
$.get("script.php", {id: id}, function(result){
$("#result").html(result);
});
setTimeout(checkProgress, timeoutLength);
});
function checkProgress() {
$.get("script.php", {progress: true, id: id}, function(data) {
prog = parseInt(data);
// Display progress bar
if(prog < 100) {
$("#progress").css({ display: 'block', width: prog });
$("#progress").html(prog + "%");
setTimeout(checkProgress, timeoutLength);
} else {
$("#progress").css('display', 'none');
}
});
}
})
</script>
<button id="button1">Click</button>
<div id="progress" style="background: green"></div>
<div id="result"></div>
script.php
<?php
function getProgress($file) {
return (file_exists($file)) ? file_get_contents($file) : 0;
}
function setProgress($file, $progress) {
file_put_contents($file, $progress);
}
// Remove invalid characters
$id = str_replace('/[^a-zA-Z0-9\-_]/', '', $_GET['id']);
$file = "progress-" . $id . ".txt";
if(isset($_GET['progress'])) {
echo getProgress($file);
} else {
// Do something and update progress
for($i = 10; $i <= 100; $i += 10) {
// Do something
setProgress($file, $i);
sleep(1);
}
unlink($file);
echo "Result: " . rand(1, 100);
}
Edit:
Added support for multiple requests and simple progress bar.
i believe that what all you need is the pecl uploadprogress package
it is not very easy to install and its not sure it works, i have find hard to make it work under certain server configurations, but i think its a good shot
EDIT: sorry i didnt see you mention download so have a look here
Below script will work for the progress-bar.
But, what I would do is, trigger an AJAX call to start the download and trigger another AJAX call to start receiving the input (using How to show file download progress in PHP Shell Scripting?).
PHP:
<?php
echo "wget '$feedURL'\n";
$execute = "wget -O ".$filePath." '$feedURL'\n";
$systemOutput = shell_exec($execute);
$systemOutput = str_replace( "\n", "\n\t", $systemOutput);
echo "\t$systemOutput\n";
?>
GetProgress:
function getProgress(){
GDownloadUrl("getprogress.php?progress_key=<?php echo($unique_id)?>",
function(percent, responseCode) {
document.getElementById("progressinner").style.width = percent+"%";
if (percent < 100){
setTimeout("getProgress()", 100);
}
});
}
Here is nice implementation with the help PHP's APC to get a nice progress-bar during UPLOAD of a file - http://www.haughin.com/2007/10/23/php-upload-progress-with-php-52-apc/
Alternative solution:
You can store the progress of downloading file into $_SESSION array inside PHP.
Besides that, you can write a dedicated PHP to only retrieve this percentage from session. This PHP will be called from your client's AJAX. This way the proccess won't take so much resources from server to calculate or to echo the download's percentage.
Try to avoid I/O from files if you are going to handle high rates of reading/writing onto them. Session variables are less expensive to achieve this functionality.
Provided that your PHP has some way to know the progress percentage, you should do multiple requests for progress updates:
function receiveProgress(data) {
// update progres indicator here
if (parseFloat(data) < 100) {
setTimeout(checkProgress, 100);
} else {
pressedButton = '';
}
}
function checkProgress() {
$.post("script.php", {val:pressedButton}, receiveProgress);
}
var pressedButton = '';
$("#button1").click(function(){
pressedButton = 'but1';
checkProgress();
});
This will ask server for progress updates every 100ms
I have a flash movie that I need to read in a value from a PHP script in order to set which frame it starts from, I am using the following code:
if (loaded == total) {
var lvContent = new LoadVars();
lvContent.load("http://MY URL/Includes/getID.php");
trace("Who: " + lvContent.pageID);
lvContent.onLoad = function() {
if (lvContent.pageID != "29") { //If it's the home page then play the full animation. If not .. don't.
_root.gotoAndPlay(2);
}else{
_root.gotoAndPlay(90);
}
}
}
The problem is this is not working - it won't get into the load event. If I run the PHP manually I get "&pageID=29". If I debug this locally I get "Who: undefined" in the trace output window. From all the example I have read, I seem to be doing this correctly but it just doesn't seem to be working.
Flash: CS5 using Actionscript 2.0
Can someone take a look and let me know where I am going wrong please?
Thanks in advance.
You are defining the onLoad event after loading the contents. I don't think that can work.
Try
if (loaded == total) {
var lvContent = new LoadVars();
lvContent.onLoad = function() {
if (lvContent.pageID != "29") {
//If it's the home page then play the full animation. If not .. don't.
_root.gotoAndPlay(2);
}else{
_root.gotoAndPlay(90);
}
}
lvContent.load("http://MY URL/Includes/getID.php");
trace("Who: " + lvContent.pageID);
}
You're tracing pageID before it is loaded; try this
var lvContent = new LoadVars();
lvContent.onLoad = function(success:Boolean) {
if(!success) {
trace("Failed to load");
return;
}
trace("Who: " + lvContent.pageID);//trace from the onLoad handler
if (lvContent.pageID != "29")
_root.gotoAndPlay(2);
else
_root.gotoAndPlay(90);
}
lvContent.load("http://MY URL/Includes/getID.php");