1. 程式人生 > >SOCKET簡單爬蟲實現代碼和使用方法

SOCKET簡單爬蟲實現代碼和使用方法

apple 頭信息 cti 實例 組元 目錄 agent uniq nec

抓取一個網頁內容非常容易,常見的方式有curl、file_get_contents、socket以及文件操作函數file、fopen等。

下面使用SOCKET下的fsockopen()函數訪問Web服務器最常用的80端口,通過獲取80端口的數據,並進行分析,來模擬網絡爬蟲的工作方法。

1、實現SOCKET模擬網絡爬蟲主要包括以下幾個部分:

  • 使用SOCKET獲取指定頁的內容。
  • 使用get_meta_tags()函數分析網頁的META、TITLE等標簽內容。
  • 解析TITLE、鏈接或網頁內容,可以使用正則表達式來取得需要的內容。

SOCKET爬蟲實現代碼,完整代碼如下:

簡單爬蟲實現代碼和使用方法


class Spider
{
    private $_url = "";//定義用於保存URL的變量
    private $_sites = "";//定義用於保存網站相關內容的變量

    /**
     * 構造函數,用於初始化變量
     * @param $url
     */
    public function __construct($url)
    {
        $this->_url = $url;
    }

    /**
     * 開始爬頁面
     */
    public function start()
{ $content = $this->socketOpen($this->_url);//使用socketOpen()方法鏈接指定的服務器 $this->_sites["meta"] = $this->getMeta($content);//使用getMeta()方法獲取meta信息 $this->_sites["title"] = $this->getTitle($content);//使用getTitle()方法獲取title信息 $this->_sites[
"detail"] = $this->getDetail($content);//使用getDetail()方法獲取內容信息 $this->_sites["links"] = $this->getLinks($content);//使用getLinks()方法獲取內容鏈接信息 } /** * 獲取網頁meta * @param $content * @return array */ protected function getMeta($content) { $file = "metaCache";//向於保存緩存文件的名稱 file_put_contents($file, $content);//將緩存保存到緩存文件中 $meta = get_meta_tags($file);//使用get_meta_tags()取得內容的meta信息 return $meta;//返回meta信息 } /** * 獲取body內容 * @param $contents * @return string */ protected function getDetail($contents) { preg_match('/<body(.*?)>(.+)<\/body>/s', $contents, $matches);//使用正則表達式處理內容 //var_dump($matches);die; $body = $this->StripHTML($matches[2]);//去掉特殊HTML字符 $body = strip_tags($body);//清除內容中的特殊標簽 return mb_substr($body, 0, 400);//返回內容的前400個字符 } /** * 獲取網頁標題 * @param $contents * @return mixed */ protected function getTitle($contents) { preg_match('/<title>(.+)<\/title>/s', $contents, $matches);//使用正則表達式處理內容 return $matches[1];//返回處理結果中的標題部分 } /** * 獲取頁面超鏈接 * @param $content * @return mixed */ protected function getLinks($content) { $pat = '/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/i';//處理鏈接的正則表達式 preg_match_all($pat, $content, $m);//使用正則表達式處理鏈接 return $m; } /** * 抓取頁面內容 * @param $url * @return bool|string */ protected function socketOpen($url) { $fp = fsockopen($url, 80, $errno, $errstr, 30);//使用fsockopen()建立SOCKET鏈接 if($fp === false){ echo "連接遠程服務器失敗:$errstr($errno)<br/>\n"; return false; }else{ $out = "GET / HTTP/1.1\r\n";//創建要發送的頭文件信息 $out .= "Host: ".$url."\r\n";//指定頭文件信息中的主機內容 $out .= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36\r\n"; $out .= "Connection: keep-alive\r\n\r\n"; fwrite($fp, $out);//使用fwrite()函數發送請求 $contents = ""; while(!feof($fp)){//使用while循環讀取返回的數據 $contents .= fgets($fp, 1024); } fclose($fp);//關閉句柄 return $contents;//返回獲取的內容 } } /** * 去掉HTML中不相關的代碼 * @param $string * @return mixed */ protected function StripHTML($string) { $pattern=array( "'<script[^>]*?>.*?</script>'si", "'<style[^>]*?>.*?</style>'si" );//建立正則表達式 $replace=array( "", "" );//建立替換字符數組 return preg_replace($pattern, $replace, $string);//替換內容中HTML並返回替換後的內容 } /** * 打印出抓取到的數據 */ public function show() { echo "<pre>"; print_r($this->_sites);//顯示保存到$_sites公共變量中的內容 echo "</pre>"; } /** * 過濾分析數據中的超鏈接 */ public function filterLinks() { $realLinks = ""; $links = $this->_sites["links"][2];//獲取保存鏈接的數組元素 //遍歷數組,清除不規範鏈接 foreach($links as $v){//遍歷鏈接數據 //只保存鏈接 if(preg_match('/^http:\/\//', $v) || preg_match('/^https:\/\//', $v)){ $realLinks[] = $v; } } //去除重復的鏈接 $realLinks = array_unique($realLinks); echo "<pre>"; print_r($realLinks);//顯示過濾後的鏈接 echo "</pre>"; } } //域名 $domainName = 'www.163.com'; //使用Web爬蟲的方法 $spider = new Spider($domainName);//實例化spider類,並設置需要抓取的網站 $spider->start();//開始抓取數據 //$spider->show();//顯示抓取的內容 $spider->filterLinks();

2、執行後結果

技術分享圖片

3、執行完成,在文件所在目錄下會有個metaCache文件,用文本編輯器打開如下

技術分享圖片

  • 在獲取超鏈接以後,就可以再使用Web爬蟲類對這些鏈接進行下一步的數據抓取。具體的實現代碼可以使用無限循環來實現。

    4、註意

  • 上述例子暫時不能爬去https的網站,這個待去探索
  • 上述例子如需要爬取像http://news.163.com/17/1225/14/D6GQU683000189FH.html這樣的鏈接,還需要著手擴展下上述代碼中socketOpen函數(設置下請求頭信息,詳細情況見另一篇博文使用SOCKET獲取網頁的內容),

參考資料

  • 1.[PHP實例精通 (編程實例大講堂)] 宮垂剛
  • 2.PHP: fsockopen - Manual

SOCKET簡單爬蟲實現代碼和使用方法