抓取一个网页内容非常容易,常见的方式有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>/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>/s', $contents, $matches);//使用正则表达式处理内容 return $matches[1];//返回处理结果中的标题部分 } /** * 获取页面超链接 * @param $content * @return mixed */ protected function getLinks($content) { $pat = '/ (.*?)<\/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) \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( "'
2、执行后结果
3、执行完成,在文件所在目录下会有个metaCache
文件,用文本编辑器打开如下
在获取超链接以后,就可以再使用Web爬虫类对这些链接进行下一步的数据抓取。具体的实现代码可以使用无限循环来实现。
4、注意
- 上述例子暂时不能爬去https的网站,这个待去探索
上述例子如需要爬取像
http://news.163.com/17/1225/14/D6GQU683000189FH.html
这样的链接,还需要着手扩展下上述代码中socketOpen
函数(设置下请求头信息,详细情况见另一篇博文),
参考资料
- 1.[PHP实例精通 (编程实例大讲堂)] 宫垂刚
- 2.