对于我的新应用程序,我想提供网站的截图。我有一个超过一百万个域名的列表。
现在我创建了一个小php脚本,并从命令行在屏幕上运行它。它工作得很好,但脚本有时会挂起,因为进程被冻结(由于某些原因不能截图?)
我可以尝试不停止我的脚本,直到我自己重新启动它什么样的解决方案?
我在Windows上遇到过这个问题。这是我的解决方案。
我在windows上使用killProcess
$cmd="$path/CutyCapt.exe --js-can-open-windows=off --max-wait=60000 --url="http://$url" --out="$fname"";
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w", "a") // stderr is a file to write to
);
$process = proc_open($cmd,$descriptorspec,$pipes);
if(!is_resource($process)) {
throw new Exception('Exec could not be started.');
}
//we wwait upto 1 min
$sec=0;
while(1)
{
sleep(1);
$status = proc_get_status($process);
if(!$status["running"])
break;
echo $sec++.' ';flush();
if($sec>60)
break;
}
if($status["running"])
{
system("KillProcess.exe CutyCapt.exe");
}
proc_close($process);
if($status["running"])
{
echo ("CutyCapt can't save image!");
@unlink($fname);
return false;
}
首先,您需要运行另一个线程以确保它将杀死cutycapt本身。定时器在这种情况下不工作,因为它是由QT的事件循环已满引起的。
class ThreadTimer : public QThread
{
Q_OBJECT
public:
protected:
private:
void run();
};
void ThreadTimer::run()
{
QThread::currentThread()->setPriority(QThread::HighPriority);
int timeout = 180;//how many seconds you want to time out
while(timeout > 0){
sleep(10);
timeout = timeout - 10;
}
qCritical() << "WARNING:Force quit by timer!";
qint64 pid = QCoreApplication::applicationPid();
QProcess::startDetached("kill -9 " + QString::number(pid));
}
我也推荐这个。我们已经测试了150万个网站,一切正常。你需要自己获取一个API密钥。
<?php
$apikey = "854412b0648e9338";
$api_url = "http://api.page2images.com/restfullink";
function call_p2i()
{
global $apikey, $api_url;
// URL can be those formats: http://www.google.com https://google.com google.com and www.google.com
$url = "http://www.google.com";
$device = 0; // 0 - iPhone4, 1 - iPhone5, 2 - Android, 3 - WinPhone, 4 - iPad, 5 - Android Pad, 6 - Desktop
$loop_flag = TRUE;
$timeout = 120; // timeout after 120 seconds
set_time_limit($timeout+10);
$start_time = time();
$timeout_flag = false;
while ($loop_flag) {
// We need call the API until we get the screenshot or error message
try {
$para = array(
"p2i_url" => $url,
"p2i_key" => $apikey,
"p2i_device" => $device
);
// connect page2images server
$response = connect($api_url, $para);
if (empty($response)) {
$loop_flag = FALSE;
// something error
echo "something error";
break;
} else {
$json_data = json_decode($response);
if (empty($json_data->status)) {
$loop_flag = FALSE;
// api error
break;
}
}
switch ($json_data->status) {
case "error":
// do something to handle error
$loop_flag = FALSE;
echo $json_data->errno . " " . $json_data->msg;
break;
case "finished":
// do something with finished. For example, show this image
echo "<img src='$json_data->image_url'>";
// Or you can download the image from our server
$loop_flag = FALSE;
break;
case "processing":
default:
if ((time() - $start_time) > $timeout) {
$loop_flag = false;
$timeout_flag = true; // set the timeout flag. You can handle it later.
} else {
sleep(3); // This only work on windows.
}
break;
}
} catch (Exception $e) {
// Do whatever you think is right to handle the exception.
$loop_flag = FALSE;
echo 'Caught exception: ', $e->getMessage(), "n";
}
}
if ($timeout_flag) {
// handle the timeout event here
echo "Error: Timeout after $timeout seconds.";
}
}
// curl to connect server
function connect($url, $para)
{
if (empty($para)) {
return false;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($para));
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function call_p2i_with_callback()
{
global $apikey, $api_url;
// URL can be those formats: http://www.google.com https://google.com google.com and www.google.com
$url = "http://www.google.com";
// 0 - iPhone4, 1 - iPhone5, 2 - Android, 3 - WinPhone, 4 - iPad, 5 - Android Pad, 6 - Desktop
$device = 0;
// you can pass us any parameters you like. We will pass it back.
// Please make sure http://your_server_domain/api_callback can handle our call
$callback_url = "http://your_server_domain/api_callback?image_id=your_unique_image_id_here";
$para = array(
"p2i_url" => $url,
"p2i_key" => $apikey,
"p2i_device" => $device
);
$response = connect($api_url, $para);
if (empty($response)) {
// Do whatever you think is right to handle the exception.
} else {
$json_data = json_decode($response);
if (empty($json_data->status)) {
// api error do something
echo "api error";
}else
{
//do anything
echo $json_data->status;
}
}
}
// This function demo how to handle the callback request
function api_callback()
{
if (! empty($_REQUEST["image_id"])) {
// do anything you want about the unique image id. We suggest to use it to identify which url you send to us since you can send 1,000 at one time.
}
if (! empty($_POST["result"])) {
$post_data = $_POST["result"];
$json_data = json_decode($post_data);
switch ($json_data->status) {
case "error":
// do something with error
echo $json_data->errno . " " . $json_data->msg;
break;
case "finished":
// do something with finished
echo $json_data->image_url;
// Or you can download the image from our server
break;
default:
break;
}
} else {
// Do whatever you think is right to handle the exception.
echo "Error: Empty";
}
}