博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SOCKET简单爬虫实现代码和使用方法
阅读量:6433 次
发布时间:2019-06-23

本文共 4699 字,大约阅读时间需要 15 分钟。

抓取一个网页内容非常容易,常见的方式有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( "'
]*?>.*?'si", "'
]*?>.*?'si" );//建立正则表达式 $replace=array( "", "" );//建立替换字符数组 return preg_replace($pattern, $replace, $string);//替换内容中HTML并返回替换后的内容 } /** * 打印出抓取到的数据 */ public function show() { echo "
";        print_r($this->_sites);//显示保存到$_sites公共变量中的内容        echo "
"; } /** * 过滤分析数据中的超链接 */ 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 "
";        print_r($realLinks);//显示过滤后的链接        echo "
"; }}//域名$domainName = 'www.163.com';//使用Web爬虫的方法$spider = new Spider($domainName);//实例化spider类,并设置需要抓取的网站$spider->start();//开始抓取数据//$spider->show();//显示抓取的内容$spider->filterLinks();

2、执行后结果

640833-20171225174254900-1230181591.png

3、执行完成,在文件所在目录下会有个metaCache文件,用文本编辑器打开如下

640833-20171225174449275-905265628.png

  • 在获取超链接以后,就可以再使用Web爬虫类对这些链接进行下一步的数据抓取。具体的实现代码可以使用无限循环来实现。

    4、注意

  • 上述例子暂时不能爬去https的网站,这个待去探索
  • 上述例子如需要爬取像http://news.163.com/17/1225/14/D6GQU683000189FH.html这样的链接,还需要着手扩展下上述代码中socketOpen函数(设置下请求头信息,详细情况见另一篇博文),

参考资料

  • 1.[PHP实例精通 (编程实例大讲堂)] 宫垂刚
  • 2.

转载于:https://www.cnblogs.com/renzhicai/p/8110460.html

你可能感兴趣的文章
我的友情链接
查看>>
思科通配符(Cisco Wildcard Mask)
查看>>
PHP cURL快速入门
查看>>
在errpt中报E87EF1BE的解决方法(转载)
查看>>
aix chfs及mklvcopy报错的解决方法
查看>>
取消新增的constraints
查看>>
OPTIMIZE TABLE
查看>>
flask框架+pygal+sqlit3搭建图形化业务数据分析平台
查看>>
shell实战训练营Day20
查看>>
jQuery 之 TAB切换菜单
查看>>
mysql 数据库集群搭建:(二)3台CentOS-7安装Percona-XtraDB-Cluster-57集群
查看>>
Jenkins实战演练之Windows系统节点管理
查看>>
MySQL高可用架构之MHA
查看>>
1.8 nginx域名跳转
查看>>
PHP面向对象之接口编程
查看>>
使用 Docker Compose 管理多个容器实例
查看>>
ThinkPHP 删除数据记录 delete 方法
查看>>
Gradle学习笔记(二)--创建Java项目
查看>>
IntelliJ IDEA 快捷键
查看>>
qury-easyui DataGrid 整合struts2增删查该入门实例(三)
查看>>