發展一個爬蟲,首先你要知道你的這個爬蟲是要用來做什麼的。我是要用來去不同網站找特定關鍵字的文章,並獲取它的鏈接,以便我快速閱讀。
依照個人習慣,我首先要寫一個介面,並釐清下思路。
1、去不同網站。那我們需要一個url輸入框。
2、找特定關鍵字的文章。那我們就需要一個文章標題輸入框。
3、取得文章連結。那我們需要一個搜尋結果的顯示容器。
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 | <div class = "jumbotron" id= "mainJumbotron" >
<div class = "panel panel-default" >
<div class = "panel-heading" >文章URL抓取</div>
<div class = "panel-body" >
<div class = "form-group" >
<label for = "article_title" >文章标题</label>
<input type= "text" class = "form-control" id= "article_title" placeholder= "文章标题" >
</div>
<div class = "form-group" >
<label for = "website_url" >网站URL</label>
<input type= "text" class = "form-control" id= "website_url" placeholder= "网站URL" >
</div>
<button type= "submit" class = "btn btn-default" >抓取</button>
</div>
</div>
<div class = "panel panel-default" >
<div class = "panel-heading" >文章URL</div>
<div class = "panel-body" >
<h3></h3>
</div>
</div>
</div>
|
登入後複製
直接上程式碼,然後加上自己的一些樣式調整,介面就完成啦:

那麼接下來就是功能的實現了,我用PHP來寫,首先第一步就是取得網站的html程式碼,取得html程式碼的方式也有很多,我就不一一介紹了,這裡用了curl來獲取,傳入網站url就能得到html代碼啦:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | private function get_html( $url ){
$ch = curl_init();
$timeout = 10;
curl_setopt( $ch , CURLOPT_URL, $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_ENCODING, 'gzip');
curl_setopt( $ch , CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36');
curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT, $timeout );
$html = curl_exec( $ch );
return $html ;
}
|
登入後複製
雖然得到了html代碼,但是很快你會遇到一個問題,那就是編碼問題,這可能會讓你下一步的匹配無功而返,我們在這裡統一把得到的html內容轉為utf8編碼:
1 2 3 4 5 | $coding = mb_detect_encoding( $html );
if ( $coding != "UTF-8" || !mb_check_encoding( $html , "UTF-8" ))
$html = mb_convert_encoding( $html , 'utf-8', 'GBK,UTF-8,ASCII');
|
登入後複製
得到網站的html,要獲取文章的url,那麼下一步就是要匹配該網頁下的所有a標籤,需要用到正規表達式,經過多次測試,最終得到一個比較可靠的正則表達式,不管a標籤下結構多複雜,只要是a標籤的都不放過:(最關鍵的一步)
1 2 3 | $pattern = '|<a[^>]*>(.*)</a>|isU';
preg_match_all( $pattern , $html , $matches );
|
登入後複製
匹配的結果在$matches中,它大概是這樣的一個多維素組:
1 2 3 4 5 6 7 8 9 10 11 12 13 | array (2) {
[0]=>
array (*) {
[0]=>
string(*) "完整的a标签" .
.
.
}
[1]=>
array (*) {
[0]=>
string(*) "与上面下标相对应的a标签中的内容" }
}
|
登入後複製
只要能得到這個數據,其他就完全可以操作啦,你可以遍歷這個素組,找到你想要a標籤,然後獲取a標籤相應的屬性,想怎麼操作就怎麼操作啦,下面推荐一個類,讓你更方便操作a標籤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $dom = new DOMDocument();
@ $dom ->loadHTML( $a );
$url = new DOMXPath( $dom );
$hrefs = $url ->evaluate('
for ( $i = 0; $i < $hrefs ->length; $i ++) {
$href = $hrefs ->item( $i );
$url = $href ->getAttribute('href');
}
|
登入後複製
當然,這只是一種方式,你也可以透過正規表示式來搭配你想要的訊息,把資料玩出新花樣。
得到並匹配得出你想要的結果,下一步當然就是傳回前端將他們顯示出來啦,把接口寫好,然後前端用js獲取數據,用jquery動態添加內容顯示出來:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var website_url = '你的接口地址';
$.getJSON(website_url, function (data){
if (data){
if (data.text == ''){
$('#article_url').html('<div><p>暂无该文章链接</p></div>');
return ;
}
var string = '';
var list = data.text;
for ( var j in list) {
var content = list[j].url_content;
for ( var i in content) {
if (content[i].title != '') {
string += '<div class = "item" >' +
'<em>[<a href= "http://' + list[j].website.web_url + '" target= "_blank" >' + list[j].website.web_name + '</a>]</em>' +
'<a href= " ' + content[i].url + '" target= "_blank" class = "web_url" >' + content[i].title + '</a>' +
'</div>';
}
}
}
$('#article_url').html(string);
});
|
登入後複製
上最終效果圖:

