PHP, Python, Node.js 哪個比較適合寫爬蟲?
PHP, Python, Node.js 哪個比較適合寫爬蟲?就PHP而言,經驗之一是如下所述
這不是一個小眾的場景,所以無論是哪個語言,都有很多相應的生態庫。這裡介紹一下PHP的方案以及程式碼量:對頁面的解析能力PHP的官方擴充套件中有Dom擴充套件,但是我建議使用electrolinux/phpquery這個庫,他相當於一個PHP版的JQ。算上載入檔案,只要三行就能獲取title標籤內容。
作者:PHP武器庫
鏈接:https://www.zhihu.com/question/23643061/answer/2375718466
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
對頁面的解析能力
PHP的官方擴充套件中有Dom擴充套件,但是我建議使用electrolinux/phpquery這個庫,他相當於一個PHP版的JQ。
算上載入檔案,只要三行就能獲取title標籤內容。
<?php
include 'phpQuery-onefile.php';
$file = 'test.html'; // 需要載入的HTML
// 載入檔案
phpQuery::newDocumentFileHTML($file);
// 載入完成後,只要像JQ那樣操作即可
$titleElement = pq('title');
// 也可以使用對象的寫法
$title = $titleElement->html();
對資料庫的操作能力
PHP對資料庫的能力無庸置疑,原生擴充套件中支援PDO,這裡可以嘗試ThinkPHP的think-orm。
簡簡單單一學就會。
<?php
use think\facade\Db;
// 數據庫配置資訊設定(全域性有效)
Db::setConfig([
// 預設數據連線標識
'default' => 'mysql',
// 數據庫連線資訊
'connections' => [
'mysql' => [
// 數據庫型別
'type' => 'mysql',
// 主機地址
'hostname' => '127.0.0.1',
// 使用者名稱
'username' => 'root',
// 數據庫名
'database' => 'demo',
// 數據庫編碼預設採用utf8
'charset'=> 'utf8',
// 數據庫表字首
'prefix' => 'think_',
// 數據庫除錯模式
'debug' => true,
],
],
]);
// 查詢
Db::name('user')->where('id', 1)->find();
// 新增
$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data);
//更新
Db::name('user')
->update(['id' => 1, 'name' => 'thinkphp']);
// 刪除
Db::table('think_user')->where('id', 1)->delete();
爬蟲效率
PHP對於效能的優化有很多很深的解決方案,包括使用協程等,這裡只介紹最簡單的的一種方式,使用guzzle這個庫(他使用curl 的並行載入特性).
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client(['base_uri' => 'http://httpbin.org/']);
// 發起不阻塞的請求
$promises = [
'image' => $client->getAsync('/image'),
'png' => $client->getAsync('/image/png'),
'jpeg'=> $client->getAsync('/image/jpeg'),
'webp'=> $client->getAsync('/image/webp')
];
// 等待所有請求完成
$responses = Promise\Utils::settle($promises)->wait();
程式碼量
如上面例子所示,程式碼量並不多,去掉配置檔案,只有十幾行程式碼,最關鍵的是我們需要的特性並沒有削弱.
比如:
[*]極簡的DOM解析
[*]健壯的SQL操作
[*]發起並行請求
解析JS
有時候我們要抓取的頁面是依賴JS執行的,這是需要一個無頭瀏覽器,此時介紹這樣一個庫,他能夠很簡單的完成對phantomjs的操作.
PHP PhantomJS 是一個靈活的 PHP 庫,讓PHP通過很簡單的程式碼來操作 PhantomJS 無頭瀏覽器載入頁面。 讓PHP載入的網頁地址執行JS/頁面截圖/導出PDF.
他可以非常方便的實現這些功能:
[*]使用無頭瀏覽器PhantomJS載入請求
[*]檢視詳細的響應數據,包括頁面內容、標題、狀態 程式碼等
[*]處理重定向
[*]檢視JS控制檯輸出報錯
[*]檢視詳細的PhantomJS除錯資訊
[*]儲存頁面的截圖
[*]將頁面導出為PDF
[*]設定瀏覽視窗大小
[*]為PDF導出設定頁首頁尾
[*]指定截圖位置x,y和寬高
[*]延遲頁面渲染(等待頁面載入完成)
[*]輕鬆構建和執行PhantomJS指令碼
PHP PhantomJS 只要求 PHP 5.4.0 或以上即可。
PhantomJS 基本用法
使用phantomjs發起一個請求非常簡單:
<?php
use JonnyW\PhantomJs\Client;
$client = Client::getInstance();
/**
* @see JonnyW\PhantomJs\Http\Request
**/
$request = $client->getMessageFactory()->createRequest('http://phpreturn.com', 'GET');
/**
* @see JonnyW\PhantomJs\Http\Response
**/
$response = $client->getMessageFactory()->createResponse();
// Send the request
$client->send($request, $response);
if($response->getStatus() === 200) {
// Dump the requested page content
echo $response->getContent();
}
將頁面截圖並儲存:
<?php
use JonnyW\PhantomJs\Client;
$client = Client::getInstance();
$width= 800;
$height = 600;
$top = 0;
$left = 0;
/**
* @see JonnyW\PhantomJs\Http\CaptureRequest
**/
$request = $client->getMessageFactory()->createCaptureRequest('http://phpreturn.com', 'GET');
$request->setOutputFile('/path/to/save/capture/file.jpg');
$request->setViewportSize($width, $height);
$request->setCaptureDimensions($width, $height, $top, $left);
/**
* @see JonnyW\PhantomJs\Http\Response
**/
$response = $client->getMessageFactory()->createResponse();
// Send the request
$client->send($request, $response);
將頁面導出為PDF:
<?php
use JonnyW\PhantomJs\Client;
$client = Client::getInstance();
/**
* @see JonnyW\PhantomJs\Http\PdfRequest
**/
$request = $client->getMessageFactory()->createPdfRequest('http://phpreturn.com', 'GET');
$request->setOutputFile('/path/to/save/pdf/document.pdf');
$request->setFormat('A4');
$request->setOrientation('landscape');
$request->setMargin('1cm');
/**
* @see JonnyW\PhantomJs\Http\Response
**/
$response = $client->getMessageFactory()->createResponse();
// Send the request
$client->send($request, $response);
自定義一個超時時間:
預設情況下每個請求超時時間為5秒,我們可以自定義一個超時時間.
<?php
...
$timeout = 10000; // 10 秒
$request = $client->getMessageFactory()->createRequest('http://phpreturn.com');
$request->setTimeout($timeout);
...
定義延遲渲染
有時候我們希望等到頁面載入完才進行其他操作,此時只要簡單地設定一個延遲時間即可.
<?php
...
$delay = 5; // 5 seconds
$request = $client->getMessageFactory()->createCaptureRequest('http://phpreturn.com');
$request->setDelay($delay);
...
設定等待所有請求載入完成才進行操作:
<?php
...
use JonnyW\PhantomJs\Client;
$client = Client::getInstance();
$client->isLazy(); // 設定所有請求完成才渲染頁面
$request= $client->getMessageFactory()->createRequest();
$request->setTimeout(5000); // 設定一個超時時間
...
並且提供了一個簡單地設定方法,支援phantomjs所有的配置項:
$client = Client::getInstance();
$client->getEngine()->addOption('--config=/path/to/config.json');
其實主要看你對那個語言使用的更趁手,如果你不瞭解相應的生態,那麼無論選擇什麼樣的語言,都只能事倍功半.
作者:PHP武器庫
鏈接:https://www.zhihu.com/question/23643061/answer/2375718466
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
頁:
[1]