第一篇文章介紹了使用原生的PHP和PHP的擴展庫實現了爬蟲技術。本文嘗試使用PHP爬蟲框架來寫,首先對三種爬蟲技術phpQuery,PHPcrawer, snoopy進行對比,然後分析模擬瀏覽器行爲的方式,重點介紹下snoopy
所有代碼掛在我的github上
1.幾種常用的PHP爬蟲框架對比
1.1 phpQuery
優勢:類似jquery的強大搜索DOM的能力。
pq()是一個功能強大的搜索DOM的方法,跟jQuery的$()如出一轍,jQuery的選擇器基本上都能使用在phpQuery上,只要把“.”變成“->”,Demo如下(對應我的github的Demo5)
<?php
require('phpQuery/phpQuery.php');
phpQuery::newDocumentFile('http://www.baidu.com/');
$menu_a = pq("a");
foreach($menu_a as $a){
echo pq($a)->html()."<br>";
}
foreach($menu_a as $a){
echo pq($a)->attr("href")."<br>";
}
?>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
1.2 PHPcrawer
優勢:過濾能力比較強。
官方給的Demo如下(我的github中對應demo4):
<?php
include("PHPCrawl/libs/PHPCrawler.class.php");
class MyCrawler extends PHPCrawler
{
function handleDocumentInfo(PHPCrawlerDocumentInfo $PageInfo)
{ // As example we just print out the URL of the document
echo $PageInfo->url."<br>";
}
}
$crawler = new MyCrawler();
$crawler->setURL("www.baidu.com");
$crawler->addURLFilterRule("#\.(jpg|gif)$# i");
//過濾到含有這些圖片格式的URL
$crawler->go();
?>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
1.3 snoopy
優勢:提交表單,設置代理等
Snoopy是一個php類,用來模擬瀏覽器的功能,可以獲取網頁內容,發送表單,
demo如下(對應github中的demo3):
include 'Snoopy/Snoopy.class.php';
$snoopy = new Snoopy();
$url = "http://www.baidu.com";
// $snoopy->fetch($url);
// $snoopy->fetchtext($url);//去除HTML標籤和其他的無關數據
$snoopy->fetchform($url);//只獲取表單
//只返回網頁中鏈接 默認情況下,相對鏈接將自動補全,轉換成完整的URL。
// $snoopy->fetchlinks($url);
var_dump($snoopy->results);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
1.4 phpspider
優勢:安裝配置到數據庫
提供了安裝配置,能夠直接連接mysql數據庫,使用也是比較廣泛,這裏我們暫時不單獨介紹。
2.模擬用戶行爲
2.1 file_get_contents
<?php
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
/* Sends an http request to www.example.com
with additional headers shown above */
$fp = fopen('http://www.example.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
2.2 curl
$ch=curl_init(); //初始化一個cURL會話
curl_setopt($ch,CURLOPT_URL,$url);//設置需要獲取的 URL 地址
// 設置瀏覽器的特定header
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Host: www.baidu.com",
"Connection: keep-alive",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Upgrade-Insecure-Requests: 1",
"DNT:1",
"Accept-Language: zh-CN,zh;q=0.8,en-GB;q=0.6,en;q=0.4,en-US;q=0.2",
"Cookie:_za=4540d427-eee1-435a-a533-66ecd8676d7d;"
));
$result=curl_exec($ch);//執行一個cURL會話
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2.3 snoopy
- 表單提交
我們的一個例子
form-demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>form-demo</title>
</head>
<body>
<form action="./form-demo.php" method="post">
用戶名:<input type="text" name="userName"><br>
密 碼:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
form-demo.php
<?php
$userName = $_POST['userName'];
$password = $_POST['password'];
if($userName==="admin"&&$password==="admin"){
echo "hello admin";
}else{
echo "login error";
}
?>
```
提交表單
```php
<?php
include 'Snoopy/Snoopy.class.php';
$snoopy = new Snoopy();
$formvars["userName"] = "admin";
//userName 與服務器端/表單的name屬性一致
$formvars["password"] = "admin";
$action = "http://localhost:8000/spider/demo3/form-demo.php";//表單提交地址
$snoopy->submit($action,$formvars);
echo $snoopy->results;
?>
<div class="se-preview-section-delimiter"></div>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
問題1:openssl extension required for HTTPS 增加對https的支持
php.in ==> ;extension=php_openssl.dll 去除註釋
<div class="se-preview-section-delimiter"></div>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
問題2:405 Not Allowed增加
$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)"; //僞裝瀏覽器
$snoopy->referer = "http://www.icultivator.com"; //僞裝來源頁地址 http_referer
$snoopy->rawheaders["Pragma"] = "no-cache"; //cache 的http頭信息
$snoopy->rawheaders["X_FORWARDED_FOR"] = "122.0.74.166"; //僞裝ip
<div class="se-preview-section-delimiter"></div>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
問題3 : snoopy使用代理
$snoopy->proxy_host = "http://www.icultivator.com";
// HTTPS connections over proxy are currently not supported
$snoopy->proxy_port = "8080"; //使用代理
$snoopy->maxredirs = 2; //重定向次數
$snoopy->expandlinks = true; //是否補全鏈接 在採集的時候經常用到
$snoopy->maxframes = 5; //允許的最大框架數
- 1
- 2
- 3
- 4
- 5
- 6
問題:
其實嘗試了網站進行提交表單是有問題的。這樣簡單的處理是不能提交表單的,使用代理也是有問題
的。snoopy框架確實會有很多問題,後面有解決思路了再說。
參考閱讀:
- cURL、file_get_contents、snoopy.class.php 優缺點
- 開源中國-PHP爬蟲框架列表
- phpQuery
- Snoopy下載地址
- Snoopy —— 強大的PHP採集類使用詳解及示例:採集、模擬登錄及僞裝瀏覽器
- 開源中國-snoopy博客列表