讲师中心 微信公众号
AI工具推荐 视频效率加速

采集 PHP

夏雪君_4729

夏雪君_4729

发布时间:2016-05-25 17:15:10

|

1870人浏览过

|

来源于php中文网

原创

充分利用正则的强大字串处理能力,使用简单,功能也比较简单,能满足一般应用,功能也在不断完善中,使用过程:设置一个初始url,添加导航规则,添加采集字段和规则,保存输出即可

<?php
set_time_limit(0);
header("Content-type: text/html; charset=utf-8");
/**
* 采集程序类
* @author  shooting
* @version 1.0.0
*/
class spider
{
/**
* 采集的终端页地址
*
* @var array
*/
var $pages = array();
/**
* 采集结果
*
* @var array
*/
var $result = array();
/**
* 第一层链接页面
*
* @var array
*/
var $startUrls = array();
/**
* 超时时间
*
* @var integer
*/
var $timeout;
/**
* 正在处理的文件内容
*
* @var string
*/
var $httpContent;
/**
* 正在处理的文件头
*
* @var array
*/
var $httpHead=array();
/**
* 自定义的head数组
*
* @var array
*/
var $putHead = array();
/**
* 采集字段与规则数组
*
* @var array
*/
var $field_arr = array();
/**
* 采集层次数
*
* @var interger
*/
var $deep;
/**
* 采集层次结构
*
* @var array
*/
var $layout_arr = array();
/**
* 采集限制条数
*
* @var integer
*/
var $limit = 0;
/**
* 程序运行时间
*
* @var float
*/
var $runtime = 0;
/**
* 被采集页面编码
*
* @var string
*/
var $charset = 'UTF-8';
/**
* 页面引用地址
*
* @var string
*/
var $httpreferer;
var $pagelimit = 0;
var $filepath = './';
function spider()
{
  $this->timeout = 30;
}
/**
* 运行采集
*
* @return array
*/
function run()
{
  $begintime = $this->microtime_float();
  $cnt = 1;
  foreach ($this->startUrls as $starturl){
  /**
   * 解析出起始地址中的页码区间
   */
   if(preg_match("~\{(\d+),(\d+)\}~",$starturl,$pagenum)){
    $pagebegin = intval($pagenum[1]);
    $pageend = intval($pagenum[2]);
    for(;$pagebegin<=$pageend;$pagebegin++){
     $starturl = str_replace($pagenum[0],$pagebegin,$starturl);
     $urllists = $this->getLists($this->layout_arr[0]['pattern'],$this->getContent($starturl));
     foreach ($urllists as $url){
      if(($this->limit > 0 && $cnt <= $this->limit)||$this->limit == 0)
      {
       $this->filterContent($this->getContent($url,$starturl));
       $cnt++;
      }
     }
    }
   }else{
    $urllists = $this->getLists($this->layout_arr[0]['pattern'],$this->getContent($starturl));
    foreach ($urllists as $url){
     if(($this->limit > 0 && $cnt <= $this->limit)||$this->limit == 0)
     {
      $this->filterContent($this->getContent($url,$starturl));
      $cnt++;
     }
    }
   }
  }
  $this->runtime =  $this->microtime_float()-$begintime;
  return $this->result;
}
/**
* 从文字段中根据规则提取出url列表
*
* @param string $pattern
* @param string $content
* @return Array
*/
function getLists($pattern='',$content='')
{
  if(strpos($pattern,'{*}') === false)return array($pattern);
  $pattern = preg_quote($pattern);
  $pattern = str_replace('\{\*\}','([^\'\">]*)',$pattern);
  $pattern = "~".$pattern."~is";
  preg_match_all($pattern,$content,$preg_rs);
  return array_unique($preg_rs[0]);
}
/**
* 获取指定url的html内容包括头
*
* @param string $url
* @return string
*/
function getContent($url,$referer = '')
{
  $url = $this->urlRtoA($url,$referer);
  preg_match("/(http:\/\/)([^:\/]*):?(\d*)(\/?.*)/i",$url,$preg_rs);
  $host = $preg_rs[2];
  $port = empty($preg_rs[3])?80:$preg_rs[3];
  $innerUrl = $preg_rs[4];
  $fsp = fsockopen($host,$port,$errno,$errstr,$this->timeout);
  if(!$fsp)$this->log($errstr.'('.$errno.')');
  $output = "GET $url HTTP/1.0\r\nHost: $host\r\n";
  if(!isset($this->putHead['Accept']))$this->putHead['Accept']= "*/*";
  if(!isset($this->putHead['User-Agent']))$this->putHead['User-Agent']='Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2)';
  if(!isset($this->putHead['Refer'])){
   $this->putHead['Refer'] = ($referer == '')?'http://'.$host:$referer;
  }
  foreach ($this->putHead as $headname => $headvalue){
   $output .= trim($headname).': '.trim($headvalue)."\r\n";
  }
  $output .= "Connection: close\r\n\r\n";
  fwrite($fsp,$output);
  $content = '';
  while (!feof($fsp)) {
        $content .= fgets($fsp,256);
    }
    fclose($fsp);
    $this->getHead($content);
    $this->httpContent = $content;
    if(strtoupper($this->charset) != 'UTF-8'){
     $content = iconv($this->charset,'utf-8',$content);
    }else if(!empty($this->httpHead['charset']) && $this->httpHead['charset']!='UTF-8')
    {
    $content = iconv($this->httpHead['charset'],'utf-8',$content);
    }
    $this->httpreferer = $referer;
  return $content;
}
/**
* 按照规则从内容提取所有字段
* @param Array
* @return Array
*/
function filterContent($content='')
{
  $rs = array();
  foreach ($this->field_arr as $field => $fieldinfo){
   $rs[$field] = $this->getPregField($fieldinfo,$content);
  }
  $this->result[] = $rs;
}
/**
* 相对路径转化为绝对路径
*
* @param string $relative
* @param string $referer
* @return string
*/
function urlRtoA($relative,$referer)
{
  /**
   * 去除#后面的部分
   */
  $pos = strpos($relative,'#');
  if($pos >0)$relative = substr($relative,0,$pos);
  /**
   * 检测路径如果是绝对地址直接返回
   */
  if(preg_match("~^(http|ftp)://~i",$relative))
  return $relative;
  /**
   * 解析引用地址,获得协议,主机等信息
   */
  preg_match("~((http|ftp)://([^/]*)(.*/))([^/#]*)~i", $referer, $preg_rs);
  $parentdir = $preg_rs[1];
  $petrol = $preg_rs[2].'://';
  $host = $preg_rs[3];
  /**
   * 如果以/开头的情况
   */
  if(preg_match("~^/~i",$relative))
   return $petrol.$host.$relative;
  return $parentdir.$relative;
}
/**
* 根据规则提取一个字段
*
* @param string $pattern
* @param string $content
* @return string
*/
function getPregField($fieldinfo,$content)
{
  /**
   * 规则为固定值的情况,直接返回固定值
   */
  if(strpos($fieldinfo['pattern'],'{'.$fieldinfo['field'].'}') === false)
  return $fieldinfo['pattern'];
  if($fieldinfo['isregular'] == 'true'){
   $pattern = $fieldinfo['pattern'];
   $pattern = str_replace('{'.$fieldinfo['field'].'}','(?P<'.$fieldinfo['field'].'>.*?)',$pattern);
  }else{
   $pattern = preg_quote($fieldinfo['pattern']);
   $pattern = str_replace('\{'.$fieldinfo['field'].'\}','(?P<'.$fieldinfo['field'].'>.*?)',$pattern);
  }
  $pattern = "~".$pattern."~is";
  preg_match($pattern,$content,$preg_rs);
  $fieldresult = $preg_rs[$fieldinfo['field']];
  /**
   * 去掉换行符
   */
  $fieldresult = preg_replace("~[\r\n]*~is",'',$fieldresult);
  /**
   * 对采集到的结果根据规则再进行二次替换处理
   */
  $replace_arr = $fieldinfo['replace'];
  if(is_array($replace_arr)){
   $replace_arr[0] = "~".$replace_arr[0]."~s";
   $fieldresult = preg_replace($replace_arr[0],$replace_arr[1],$fieldresult);
  }
  /**
   * 针对有下一页的字段递归采集
   */
  if($this->pagelimit == 0){
  if($fieldinfo['nextpage'] != ''){
   $pattern = $fieldinfo['nextpage'];
   $pattern = str_replace('{nextpage}','(?P<nextpage>[^\'\">]*?)',$pattern);
   $pattern = "~".$pattern."~is";
   if(preg_match($pattern,$content,$preg_rs) && $preg_rs['nextpage'] != ''){
    $fieldresult .= $this->getPregField($fieldinfo,$this->getContent($preg_rs['nextpage'],$this->httpreferer));
   }
  }
  }
  if(!empty($fieldinfo['callback']))$fieldresult = $fieldinfo['callback']($fieldresult);
  return $fieldresult;
}
/**
* 添加一个采集字段和规则
*
* @param string $field
* @param string $pattern
*/
function addField($field,$pattern,$replace_arr='',$isregular='false',$nextpage = '',$callback='')
{
  $rs = array(
    'field' => $field,
    'pattern' => $pattern,
    'replace' => $replace_arr,
    'isregular' => $isregular,
    'nextpage' => $nextpage,
    'callback'=>$callback
    );
  $this->field_arr[$field] =$rs;
}
/**
* 输出
*
*/
function output()
{
  echo "The result is:<br/>";
  echo "runtime :$this->runtime S<br/><pre>";
  print_r($this->result);
  echo "</pre>";
}
/**
* 输出到XLS文件
*
* @param string $file
*/
function saveXls($file = 'spider_result.xls')
{
  $fp = fopen($file,'w');
  if($fp){
   foreach ($this->result as  $result)
   {
    $line = implode("\t",$result)."\n";
    fputs($fp,$line);
   }
  }
  fclose($fp);
  echo 'The result has been saved to '.$file.'.<br/>Cost time:'.$this->runtime;
}
function saveSql($table = 'spider_result',$file = 'spider_result.sql')
{
  $fp = fopen($file,'w');
  if($fp){
   foreach($this->field_arr as $fieldinfo){
    $sql_key .= ', `'.$fieldinfo['field'].'`';
   }
   $sql_key = substr($sql_key,1);
   foreach ($this->result as  $result)
   {
    $sql_value = array();
    foreach ($result as $key => $value){
     $sql_value[] = "'".$this->addslash($value)."'";
    }
    $line ="INSERT INTO `$table` ( $sql_key ) VALUES (".join(', ',$sql_value).");\r\n";
    fputs($fp,$line);
   }
  }
  fclose($fp);
  echo 'The result has been saved to '.$file.'.<br/>Cost time:'.$this->runtime;
}
/**
* 取得响应内容的头部信息
*
* @param string $content
* @return array
*/
function getHead($content)
{
  $head = explode("\r\n\r\n",$content);
  $head = $head[0];
//  echo $head;
  if(!preg_match("~charset\=(.*)\r\n~i",$head,$preg_rs))
  preg_match('~charset=([^\"\']*)~i',$content,$preg_rs);
  $this->httpHead['charset'] = strtoupper(trim($preg_rs[1]));
//  preg_match("~charset\=(.*)~i",$head,$preg_rs);
  return $this->httpHead;
}
/**
* 设置采集页面的编码
* 在程序不能自动识别的情况下采集前要手动调用此函数
*
* @param string $charset
*/
function setCharset($charset){
  $this->charset = strtoupper($charset);
}
/**
* 设置第一层链接页面地址
*
* @param array $url_arr
*/
function setStartUrls($url_arr)
{
  $this->startUrls = $url_arr;
}
/**
* 增加一个第一层链接页面地址
*
* @param string $url
*/
function addStartUrl($url)
{
  $this->startUrls[] = $url;
}
/**
* 添加一个采集层次
*
* @param integer $deep
* @param string $layout
* @param boolean $isSimple
* @param boolean $isPageBreak
* @param string $pattern
*/
function addLayer($deep,$layout,$pattern = '',$isSimple = 'false',$isPageBreak = 'false')
{
  $this->layout_arr[$deep] = array(
         'layout'=>$layout,
         'isSimple'=>$isSimple,
         'isPageBreak'=>$isPageBreak,
         'pattern'=>$pattern );
}
/**
* 自定义head
* @param string $namespace
* @param string $value
*/
function setHead($name,$value)
{
  $this->putHead[$name] = $value;
}

/**
* 清除html代码
*  @param string $content;
*  @param string $cleartags
*  @return string
*/
function clearHtml($content,$cleartags = 'p')
{
  $cleartags_arr = explode('|',$cleartags);
  foreach ($cleartags_arr as $cleartag){
   $pattern = '~<\/?'.$cleartag.'[^>]*>~is';
   $content = preg_replace($pattern,'',$content);
  }
  return $content;
}
/**
* 日志
*
*/
function log($str)
{
  echo $str."<br/>\n";
}
/**
* 获取采集运行时间
*
* @return float
*/
function getRuntime()
{
  return $this->runtime;
}
function microtime_float()
{
     list($usec, $sec) = explode(" ", microtime());
     return ((float)$usec + (float)$sec);
}
function addslash($string)
{
  return addslashes($string);
}
}
$spider  = new spider();
$spider->addStartUrl('http://hi.baidu.com/shuntian/blog/index/{0,5}');
$spider->setCharset('gb2312');
$spider->addLayer(0,'list','/shuntian/blog/item/{*}.html');
$spider->addField('title','<title>{title}</title>',array('_顺者的天空-shooting's sky      ',''));
$spider->addField('body','<td><p id="blog_text" class="cnt"  >{body}</p></td></tr></table>');
$spider->addField('author','shooting');
$spider->run();
$spider->saveSql();

 以上就是采集的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
C++运算符基础入门
C++运算符基础入门

本专题详细讲解了C++运算符的类型、语法与使用方法,涵盖算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、条件运算符及其他特殊运算符,并通过代码示例解析优先级与结合性。

0

2026.10.09

PixPix官网入口合集
PixPix官网入口合集

本专题汇总了PixPix官网在线使用入口及平台功能详解,涵盖文生图、图生图、AI图片编辑、AI视频创作等核心能力,并整理了AI爆款图片复刻、商品套图、详情页生成、视频变清晰与去水印等电商专项工具的使用教程。同时收录了PixPix MCP接入Codex、Claude Code等主流Agent的操作指南,助您一站式完成AI图片与视频创作。

0

2026.10.09

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

60

2026.10.08

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

160

2026.09.30

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

140

2026.09.30

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

100

2026.09.30

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

100

2026.09.30

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

120

2026.09.29

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

320

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP爬虫采集课程
PHP爬虫采集课程

共11课时 | 2.6万人学习

后盾网织梦DedeCMS视频教程
后盾网织梦DedeCMS视频教程

共9课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn