Chrome Headless
什么是Chrome Headless
Headless Chrome 是 Chrome 瀏覽器的無界面形態,可以在不打開瀏覽器的前提下,使用所有 Chrome 支持的特性運行你的程序,簡而言之,除了沒有圖形界面,headless chrome具有所有現代瀏覽器的特性,可以像在其他現代瀏覽器里一樣渲染目標網頁,并能進行網頁截圖,獲取cookie,獲取html等操作。 而對于寫爬蟲的同學,很多都會面臨都一個問題,那就是數據都是通過動態渲染,甚至是加密得到的,普通的分析接口模式早已無法滿足需求,因此我們引入Chrome Headless 來解決數據渲染問題。
部署 Chrome Headless
因為環境部署不是本文的重點,因此我們直接推薦docker。
docker pull alpeware/chrome-headless-trunk
docker run -d -p 9222:9222 alpeware/chrome-headless-trunk
訪問debug 地址即可得到接口信息
curl http://{HOST}:9222/json
以下例子中,{HOST}定義的IP主機響
驅動Chrome Headless
Chrome Headless 可以通過websocket協議進行遠程驅動debug。首先我們引入easyswoole的websocket客戶端。
composer require easyswoole/http-client
我們以網站 https://datacenter.jin10.com/price 為例子,我們打開可以發現,里面的數據都是通過websocket實時刷新的,這個時候,通過傳統手段抓接口的手段,是很難實現的。模擬實現如下:
use EasySwoole\HttpClient\HttpClient;
use EasySwoole\Spl\SplBean;
use Swoole\WebSocket\Frame;
static $i = 0;
//定義命令bean,具體協議格式可以看 Chrome Headless 文檔
class Command extends SplBean{
protected $method;
protected $id;
protected $params;
protected function initialize(): void
{
if(empty($this->id)){
global $i;
$i++;
$this->id = $i;
}
}
}
//用websocket協議去驅動Chrome Headless
go(function (){
$targetUrl = 'https://datacenter.jin10.com/price';
$ch = curl_init('http://{HOST}:9222/json');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$data = json_decode( curl_exec($ch) ,true);
$client = new HttpClient($data[0]['webSocketDebuggerUrl']);
if($client->upgrade()){
//打開URL
$command = new Command([
'method'=>'Page.navigate',
'params'=>[
'url'=>$targetUrl
]
]);
$client->getClient()->push($command->__toString());
$client->recv(1);
//模擬等待渲染
\co::sleep(2);
//實現 js 語句
$command = new Command([
'method'=>'Runtime.evaluate',
'params'=>[
'expression'=>"var p = document.querySelector('#J_pricewall > div:nth-child(1) > ul > li:nth-child(1)').innerHTML;p;"
]
]);
$client->getClient()->push($command->__toString());
//此處就可以得到渲染后的數據了
$data = json_decode($client->recv()->data,true)['result']['result']['value'];
var_dump($data);
}else{
var_dump('handshake fail');
}
});
以上教程僅供學習之用,請勿用于非法用途