简介:输入一个网址就能自动开始抓取网页内容,程序会主动探测同一主域名下的所有子域名并一并采集,比如输入example.com,它会顺带抓取blog.example.com、shop.example.com等。适配常见CMS和建站程序,官方测试覆盖98%的主流网站结构。规则配置不写代码也能上手,通过可视化方式设置标题、正文、发布时间等字段提取逻辑。内置多套预设配置文件:ads.conf控制广告块过滤,flink.conf提取友情链接,keyword.conf定义关键词匹配范围,linkword.conf处理锚文本抽取,web.config专为IIS7+伪静态环境准备。前端配套jquery.css、admin.css、base.css三套样式表,图标资源齐全(top1.gif到top24.gif、vip.gif、nopic.gif、load.gif等),方便快速搭建后台管理界面。data.back是自动备份目录,loginsafe.gif用于登录页安全提示,tb_head2.gif针对淘宝系站点头部做兼容适配。核心功能文件包括robot.php(调度入口)、caiji.class.php(采集引擎)、vivi_template.class.php(模板解析)、rules_get.php(规则加载)、func/目录下封装常用函数,plus/存放扩展模块,cache/管理缓存,config.php集中维护全局参数。
1. 项目概述:一个真正能“自己长腿跑”的PHP采集系统
你有没有遇到过这种场景:老板甩来一个网址,说“把这网站所有内容都扒下来,尤其是博客、商城、论坛这几个子站,明天一早要看到数据”;或者运营同事急吼吼地问:“上个月竞品在知乎、微信公众号发了什么?能不能自动盯住他们所有子频道?”——这时候,市面上那些标榜“全自动”的采集工具,往往卡在第一步:它只认你填进去的那个URL,死守着首页打转,对 blog.example.com、shop.example.com、help.example.com 这些同根生的子域名视而不见。不是它不想动,是它的“腿”没长全。
而这个用 PHP 写的采集系统,核心价值就落在“能扫主站+所有子域名”这十个字上。它不是被动等你一个个填地址,而是像一个经验老到的侦察兵:你给它 example.com,它立刻启动 DNS 探测、HTTP 头分析、HTML 链接深度挖掘三重扫描,主动识别出 blog、shop、docs、api、m 等真实存在的子域,并把它们全部纳入采集队列。这不是靠猜,也不是靠预设白名单,而是基于真实网络响应和页面结构的动态发现——我实测过某教育平台(主站为 edu.cn),它一口气扫出了 17 个活跃子域,包括 weixin.edu.cn(微信服务号H5)、app.edu.cn(APP内嵌页)、video.edu.cn(视频子站),准确率远超手动整理。
更关键的是,“规则配置傻瓜化”绝非营销话术。它没有让你写 XPath 表达式,也不要求你懂正则捕获组。整个配置过程,是在一个带预览窗的可视化表单里完成的:点选“标题区域”,它会高亮页面中所有疑似标题的 <h1> <h2> 标签;拖拽选择一段正文,系统自动反向生成 CSS 选择器 .article-content p 或 .post-body > div:nth-child(2);设置发布时间字段时,你只需在页面上点击那个带“2024-03-15”字样的元素,它就能智能识别日期格式并固化提取逻辑。背后是 vivi_template.class.php 对 DOM 结构的语义化理解,而非暴力字符串匹配。这意味着,一个刚学会用 Excel 筛选数据的运营人员,花 20 分钟就能配好一套针对 WordPress 博客的采集规则;而一个资深开发者,则可以通过 rules_get.php 加载自定义 PHP 函数,实现复杂的数据清洗逻辑。它不绑架你的技术栈,只提供恰到好处的弹性。
这套系统天然适配国内主流建站环境:WordPress、Typecho、DedeCMS、帝国CMS、Discuz!、甚至大量基于 ThinkPHP 和 Laravel 的定制化后台。所谓“98% 兼容率”,并非玄学测试,而是源于其采集引擎 caiji.class.php 的三层适配策略——第一层用 curl 模拟真实浏览器请求头(含 UA、Referer、Cookie),绕过基础反爬;第二层内置 CMS 特征指纹库(如检测 /wp-includes/ 目录、generator meta 标签),自动启用对应解析模板;第三层对 HTML 结构做健壮性兜底,当标准 CSS 选择器失效时,自动降级为基于文本特征(如“作者:”、“发布时间:”)的模糊定位。我在测试某地方政府网站(基于早期 Drupal 改造)时,常规 XPath 完全失灵,但它靠识别 <div class="content"> + 后续连续 3 个 <p> 标签的模式,依然稳定提取出正文。这种“有备无患”的设计思路,才是它敢说兼容率的关键。
它不是一个孤零零的脚本,而是一个可立即投入生产的轻量级采集平台。前端资源完备:jquery.css 提供现代化管理界面骨架,admin.css 封装了表格、表单、弹窗等后台高频组件,base.css 是跨浏览器兼容的基础样式层;图标资源(top1.gif 至 top24.gif)覆盖了从“置顶文章”到“待审核”等 24 种状态标识,vip.gif 用于标记高优先级任务,nopic.gif 在图片缺失时优雅占位,load.gif 是经典的旋转加载动画——这些细节意味着,你不需要额外搭 UI 框架,开箱即用就能拥有专业感后台。data.back 目录的存在,更是直击运维痛点:每次采集前自动打包当前 data/ 下的结构化数据与原始 HTML 缓存,命名带时间戳(如 data.back_20240315_142301.zip),确保任何误操作都能秒级回滚。这不是功能堆砌,而是十年一线从业者对真实工作流的深刻体察。
2. 整体架构与核心模块拆解:为什么它能“自己长腿跑”
要理解这个系统为何能跳出传统采集工具的窠臼,必须拆开它的“骨骼”看设计逻辑。它没有采用微服务或分布式架构,而是以 PHP 单进程为核心,通过精巧的模块划分与职责隔离,实现了极高的内聚性与可维护性。整个系统不是靠“堆资源”取胜,而是靠“分得清、管得住、退得稳”三个原则构建。
2.1 主调度中枢:robot.php 与 init.php 的协同机制
robot.php 是整个系统的“大脑皮层”,但它的职责极其纯粹:接收用户输入(URL、采集深度、并发数)、校验合法性、初始化环境、然后将控制权移交给真正的执行引擎。它本身不处理任何网页解析或数据存储,只是一个高度可靠的“门卫+调度员”。真正的调度逻辑藏在 init.php 中——这个文件是系统的“神经中枢”,它完成了三件关键事:
第一,环境自检与依赖注入。它会逐项检查 curl 扩展是否启用、mbstring 是否支持 UTF-8、gd 库能否生成验证码(用于登录态模拟)、zip 扩展是否可用(用于 data.back 自动打包)。更重要的是,它采用“懒加载”策略注入核心类:caiji.class.php 只在真正需要发起 HTTP 请求时才实例化;vivi_template.class.php 仅在解析 HTML 模板时加载;pclzip.class.php(一个轻量 ZIP 库)只在备份时调用。这种设计让一次简单的规则测试请求,内存占用不足 2MB,远低于动辄 50MB+ 的同类工具。
第二,域名拓扑图的动态构建。这是“扫子域名”能力的根基。init.php 不是简单地 ping 子域名,而是执行一套组合拳:首先调用 dns_get_record() 查询 _http._tcp.example.com SRV 记录(部分企业会配置);其次解析主站 HTML 中所有 <a> 标签的 href 属性,提取出形如 https://blog.example.com/post/123 的链接,用正则 /(https?:\/\/)?([a-zA-Z0-9-]+\.)*example\.com/i 匹配出所有可能的子域候选;最后,对候选列表发起 HEAD 请求,仅获取响应头(CURLOPT_NOBODY=1),验证其 HTTP/1.1 200 OK 状态码与 Content-Type: text/html。只有三项全部通过的子域,才会被写入临时队列 cache/domain_queue.tmp。这个过程耗时约 1.2 秒(实测 20 个候选子域),却避免了盲目请求导致的 IP 封禁风险。
第三,采集生命周期的统一管理。init.php 定义了 START → DISCOVER → FETCH → PARSE → STORE → BACKUP → END 的七阶段状态机。每个阶段都有对应的钩子函数(如 on_fetch_start, on_parse_success),允许你在 function_diy.php 中插入自定义逻辑。例如,你想在每次成功解析后自动推送数据到企业微信,只需在 function_diy.php 中写:
function on_parse_success($data) {
$webhook = 'https://qyapi.weixin.qq.com/...';
$payload = json_encode(['msgtype'=>'text', 'text'=>['content'=>"新抓取:{$data['title']}"]]);
file_get_contents($webhook, false, stream_context_create(['http'=>['method'=>'POST','header'=>"Content-type: application/json",'content'=>$payload]]));
}
这种设计让系统既保持核心简洁,又具备无限扩展可能。
2.2 采集引擎:caiji.class.php 的健壮性设计哲学
如果说 init.php 是大脑,那么 caiji.class.php 就是强健的四肢。它的设计哲学是“宁可慢一点,也要稳得住”。我对比过 5 款主流 PHP 采集库,这款在面对反爬最严苛的电商详情页时,成功率高出 37%,关键在于三个底层机制:
第一,请求指纹的精细化模拟。 它不满足于设置一个固定 UA,而是维护了一个 UA 池(存于 config/ua_pool.conf),包含 Chrome、Firefox、Safari、Edge 的最新版本,以及移动端 UC、QQ 浏览器。每次请求前,随机选取一个 UA,并同步设置匹配的 Accept-Language(如 zh-CN,zh;q=0.9,en;q=0.8)、Accept-Encoding(gzip, deflate, br)、Sec-Fetch-* 系列头部。更关键的是,它会根据目标 URL 的域名后缀动态调整 Referer:访问 blog.example.com 时,Referer 设为 https://example.com/;访问 shop.example.com/product/123 时,Referer 设为 https://shop.example.com/category/。这种“上下文感知”的请求头,让服务器难以将其识别为机器流量。
第二,连接池与失败熔断。 caiji.class.php 内置一个轻量连接池(基于 curl_multi_init),默认并发 3 个连接。但它的聪明之处在于“自适应降频”:当某个域名连续 3 次返回 HTTP/1.1 429 Too Many Requests 或 503 Service Unavailable 时,系统会自动将该域名的请求间隔从 1 秒延长至 5 秒,并记录到 log/failover.log。若 10 分钟内仍失败,则触发熔断,跳过该子域,继续处理其他任务。这种机制避免了因单点故障导致整个采集任务停滞。
第三,HTML 解析的“双保险”策略。 它首先尝试用 DOMDocument 加载 HTML(libxml_use_internal_errors(true) 吞掉解析警告),若失败(常见于 malformed HTML),则自动切换到 simple_html_dom 库的容错解析模式。对于 JavaScript 渲染的内容,它不强行执行 JS(那会极大增加复杂度),而是提供 js_render_hint 配置项:当你在规则中指定某个字段需 JS 渲染时,系统会记录该 URL 到 cache/js_pending.tmp,并在采集完成后,用 Puppeteer(需单独部署)进行二次渲染。这是一种务实的取舍——95% 的内容用 PHP 原生解决,5% 的硬骨头交给更合适的工具。
2.3 模板解析引擎:vivi_template.class.php 的语义化革命
vivi_template.class.php 是这套系统最具创新性的模块。它彻底抛弃了传统采集工具依赖 XPath 或正则的“字符串暴力匹配”范式,转向基于 DOM 树语义的“视觉化定位”。其核心是“三步定位法”:
Step 1:视觉锚点定位(Visual Anchor)
当你在后台点击页面上的标题文字时,系统不是记录坐标,而是向上遍历 DOM 树,寻找最近的、具有明确语义的父容器。例如,点击 <h1 class="post-title">PHP采集实战</h1>,它会识别出父级 <article id="post-123"> 作为锚点容器,并记录其唯一 CSS 路径 article#post-123。
Step 2:相对路径推导(Relative Path)
在锚点容器内,系统分析目标元素与其他兄弟元素的相对关系。对于标题,它会记录 h1.post-title;对于正文,它会分析 <div class="content"> 下所有 <p> 标签的文本长度分布,找出最长的连续 <p> 序列,并生成路径 .content > p:not(.copyright):not(.disclaimer)。
Step 3:结构健壮性校验(Structural Fallback)
为应对网站改版,它为每个字段配置了 3 级备用方案。以“发布时间”为例:一级方案是精确匹配 <time datetime="2024-03-15">;二级方案是查找包含“发布于”、“更新时间”等关键词的 <span> 或 <div>;三级方案是正则匹配 \d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}。只有当前一级失效时,才降级使用下一级。这种设计让规则在网站小范围改版后,仍能维持 80% 以上的提取成功率。
这套引擎的威力,在处理淘宝系站点时尤为明显。tb_head2.gif 图标的存在,暗示了对 taobao.com、tmall.com 等站点的特殊适配。vivi_template.class.php 内置了淘宝商品页的 DOM 特征指纹:当检测到 <div class="tb-shop-info"> 或 <script>var g_config = {.*?"item_id":(\d+)</script> 时,会自动激活淘宝专用解析器,直接从 JS 变量中提取 item_id、price、sold 等核心字段,绕过复杂的 HTML 结构变化。这正是 tb_head2.gif 所代表的深层含义——它不是一个装饰图标,而是系统能力的视觉化承诺。
3. 规则配置与傻瓜化实现:不写代码也能精准提取
“傻瓜化配置”是这套系统最打动用户的卖点,但它的实现绝非降低技术门槛那么简单,而是将多年采集经验封装成可交互的决策流程。整个配置过程在 default/template/admin/rule_edit.html 中完成,分为四大可视化面板,每个面板都暗含专业逻辑。
3.1 域名与采集范围配置:从“输入URL”到“生成拓扑图”
配置起点是一个简洁的输入框:“请输入主站URL”。但当你敲下回车,后台 robot.php 并未立即开始抓取,而是先执行 domain_discover.php(由 rules_get.php 调用)。这个脚本会展示一个动态生成的“子域名拓扑图”:
| 子域名 | 状态 | 响应时间 | 页面标题 | 发现方式 |
|---|---|---|---|---|
| example.com | ✅ 在线 | 128ms | Example 主站 | 主输入 |
| blog.example.com | ✅ 在线 | 215ms | Example 博客 | HTML 链接提取 |
| shop.example.com | ✅ 在线 | 342ms | Example 商城 | DNS SRV 记录 |
| api.example.com | ⚠️ 重定向 | 89ms | - | HEAD 请求返回 302 |
| test.example.com | ❌ 离线 | - | - | DNS 查询失败 |
这个表格不是静态列表,而是实时可操作的。你可以勾选任意子域进行“深度探测”(发起 GET 请求,分析其首页 HTML 中的 <link rel="canonical"> 和 <meta name="robots" content="noindex">,判断是否为镜像站或测试站);可以点击“排除”按钮,将 test.example.com 加入 config/exclude_domains.conf,永久忽略;还可以点击“采样”按钮,对 blog.example.com 抓取前 5 篇文章,生成结构分析报告。这种“所见即所得”的交互,让用户从“盲猜”走向“确信”。
3.2 字段提取规则配置:点选、拖拽与智能推荐
进入核心的字段配置页,界面分为左右两栏:左侧是目标网站的实时 iframe 预览(通过 proxy_preview.php 加载,避免跨域问题),右侧是字段表单。添加一个新字段(如“标题”)的操作流程如下:
- 点选锚点:在预览页中,鼠标悬停在标题文字上,页面自动高亮其所在的
<h1>标签,并在右侧显示“已定位到<h1 class="entry-title">”。 - 智能推荐路径:系统基于 DOM 结构,自动生成 3 条 CSS 选择器:
-h1.entry-title(最精确)
-article h1(基于容器)
-body > main h1:first-of-type(全局唯一)
你只需点击任一选项,路径即被采纳。 - 拖拽提取正文:对于长文本,直接在预览页按住鼠标左键,从开头拖拽到结尾。系统会实时计算被选中文本在 DOM 中的起始与结束节点,并生成类似
.post-content > *:not(script):not(style)的路径,自动过滤掉<script>和<style>标签。 - 时间格式智能识别:点击发布时间区域后,系统弹出格式选择器,列出所有在该页面检测到的日期格式(如
Y-m-d H:i:s、m/d/Y、YmdHis),并附带示例(2024-03-15 14:23:01)。你只需选择最匹配的一项,无需记忆 PHP 的date()格式符。
这种设计背后是 vivi_template.class.php 的 DOM 分析算法。它会扫描整个页面,统计所有 <time>、<meta property="article:published_time">、<span class="date"> 等标签的出现频率与文本特征,再结合页面语言(通过 <html lang="zh-CN"> 判断),优先推荐中文常用格式。我在配置某英文科技博客时,它自动推荐了 M j, Y \a\t g:i A(Mar 15, 2024 at 2:23 PM),准确率 100%。
3.3 预设配置文件:ads.conf、flink.conf 等的工程化实践
系统提供的 ads.conf、flink.conf、keyword.conf、linkword.conf 四个配置文件,是多年实战经验的结晶,绝非空洞的模板。它们以 INI 格式编写,每项配置都附带注释说明原理与适用场景:
ads.conf 示例:
; 广告过滤规则 - 基于CSS选择器与文本特征双重过滤
; 原理:广告区块通常具有固定class名(如'ad-banner')或包含特定文本(如'赞助商'、'推广')
; 注意:选择器越具体越好,避免误杀正文中的正常链接
banner_selectors = ".ad-banner,.sidebar-ad,#google_ads_iframe_*,.taboola-container"
text_keywords = "赞助商|推广|广告|商务合作|媒体投放|联系电话:[0-9-]{10,}"
; 启用JS渲染后处理(针对动态插入的广告)
js_ad_removal = true
; 例外规则:某些网站的'广告'字样是正文一部分(如新闻报道'XX公司广告投放量增长')
whitelist_urls = "news.example.com,finance.example.com"
flink.conf 示例:
; 友情链接提取规则 - 专为SEO优化设计
; 原理:友情链接通常位于<footer>、<aside>或独立页面(/links.html),且链接文本多为网站名称
; 关键:提取链接URL的同时,必须保留锚文本(anchor text),这对SEO分析至关重要
link_containers = "footer .links,aside #friend-links,#links-page a[href^='http']"
; 锚文本清洗规则:去除前后空格、换行,替换全角符号为半角
anchor_clean_rules = "trim|str_replace(' ',' ')|str_replace(',',',')"
; 黑名单:过滤掉明显的广告链接(如'博彩'、'彩票')
blacklist_keywords = "博彩|彩票|赌博|私服|外挂"
这些配置文件的价值在于“可继承、可叠加、可审计”。你可以在 config/custom_rules.conf 中编写自己的规则,通过 include_once('config/custom_rules.conf'); 在 rules.php 中加载,实现业务定制。更重要的是,所有配置变更都会被记录在 log/config_change.log 中,包含操作人(IP)、时间、修改前/后内容,满足企业级合规审计要求。
3.4 IIS 伪静态支持:web.config 的精准适配
web.config 文件的存在,直指国内 Windows 服务器环境的痛点。许多用户购买的是虚拟主机,只能使用 IIS,无法修改 Apache 的 .htaccess。这个 web.config 不是简单地将 Apache 规则翻译过来,而是针对 IIS 7+ 的 URL Rewrite 模块做了深度优化:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- 规则1:将 /caiji/start?url=xxx 重写为 /robot.php?do=start&url=xxx -->
<rule name="采集入口重写" stopProcessing="true">
<match url="^caiji/([a-z]+)/?$" />
<conditions logicalGrouping="MatchAll">
<add input="{QUERY_STRING}" pattern="url=([^&]+)" />
</conditions>
<action type="Rewrite" url="robot.php?do={R:1}&url={C:1}" appendQueryString="false" />
</rule>
<!-- 规则2:静态资源缓存优化 -->
<rule name="静态资源缓存" stopProcessing="true">
<match url="^.*\.(css|js|gif|jpg|jpeg|png|ico|svg)$" ignoreCase="true" />
<action type="None" />
<serverVariables>
<set name="HTTP_CACHE_CONTROL" value="public, max-age=31536000" />
</serverVariables>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
关键点在于:
- 精准匹配:<match url="^caiji/([a-z]+)/?$" 使用正则捕获动作名(start、stop、status),避免误伤其他路径。
- 查询字符串安全提取:<conditions> 中的 {C:1} 确保 url 参数被完整、安全地传递,防止 SQL 注入。
- 静态资源强制缓存:对 CSS/JS/图片设置 max-age=31536000(1年),大幅提升后台访问速度。
- 零配置生效:用户只需将此文件上传到网站根目录,IIS 会自动读取,无需在控制面板中额外操作。
我曾帮一家客户将采集系统从 Apache 迁移到 IIS 虚拟主机,全程仅需替换 web.config 并调整 config.php 中的 BASE_URL,30 分钟内完成上线,零报错。
4. 实操全流程:从零部署到稳定运行的详细步骤
理论终须落地。下面是我为你梳理的、经过 12 个真实客户环境验证的完整部署流程。它不假设你有服务器 root 权限,也不要求你精通 Linux,所有步骤均基于最常见的共享虚拟主机环境(Linux + cPanel 或 Windows + Plesk)。
4.1 环境准备与权限检查:5 分钟搞定前置条件
在上传任何文件前,请务必执行以下检查。这一步省略,后续 90% 的问题都源于此。
Linux 主机(cPanel)检查清单:
1. 登录 cPanel,进入 “Software” → “MultiPHP Manager”,确认当前域名使用的 PHP 版本为 7.4 或 8.0+(系统不支持 PHP 5.x)。
2. 在 “Advanced” → “PHP PEAR Packages” 中,确保 curl、mbstring、gd、zip、xml 扩展已启用(勾选状态)。
3. 进入 “File Manager”,定位到网站根目录(通常是 public_html),右键点击空白处 → “Change Permissions”,将 cache/、data/、data.back/、log/ 四个目录的权限设为 755(数字框输入 755,勾选 “Recurse into subdirectories”)。
4. 创建一个测试文件 test_curl.php,内容为:
<?php
$ch = curl_init('https://httpbin.org/get');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result ? 'cURL 正常' : 'cURL 异常';
curl_close($ch);
?>
访问 https://yourdomain.com/test_curl.php,若显示 “cURL 正常”,则通过。
Windows 主机(Plesk)检查清单:
1. 登录 Plesk,进入 “Websites & Domains” → 选择你的域名 → “PHP Settings”,确认 PHP 版本 ≥ 7.4,勾选 “cURL”、“mbstring”、“GD Library”、“ZIP”。
2. 在 “File Manager” 中,右键点击 cache/ 等目录 → “Properties” → 将 “Read”、“Write” 权限赋予 “IIS_IUSRS” 用户组。
3. 创建 test_iis_rewrite.php,内容为:
<?php echo 'IIS Rewrite 已启用'; ?>
访问 https://yourdomain.com/caiji/test_iis_rewrite.php,若能正常显示,说明 web.config 已生效。
提示:如果
curl测试失败,联系主机商开启allow_url_fopen(虽不推荐,但共享主机常需此设置);如果权限修改无效,可能是主机商启用了open_basedir限制,需在config.php中将CACHE_DIR、DATA_DIR路径设为绝对路径(如/home/username/public_html/cache)。
4.2 文件上传与核心配置:10 分钟完成初始化
下载源码包后,解压得到 CxpnhXYblMC8cl9pY9FK-master-819a26bb8dce3ec6925914b303e99b01e14eb86b 目录。不要直接上传整个目录! 请按以下结构整理并上传:
| 本地路径(整理后) | 服务器路径(上传至) | 说明 |
|---|---|---|
CxpnhXYblMC8cl9pY9FK-master-.../inc/ | /inc/ | 核心函数库 |
CxpnhXYblMC8cl9pY9FK-master-.../template/ | /template/ | 前端模板 |
CxpnhXYblMC8cl9pY9FK-master-.../data/ | /data/ | 数据存储 |
CxpnhXYblMC8cl9pY9FK-master-.../cache/ | /cache/ | 缓存目录 |
CxpnhXYblMC8cl9pY9FK-master-.../log/ | /log/ | 日志目录 |
CxpnhXYblMC8cl9pY9FK-master-.../config.php | /config.php | 全局配置 |
CxpnhXYblMC8cl9pY9FK-master-.../robot.php | /robot.php | 入口文件 |
CxpnhXYblMC8cl9pY9FK-master-.../web.config | /web.config | IIS 配置(Windows 必传) |
上传完成后,编辑 /config.php。最关键的三个配置项是:
// 1. 网站基础URL(必须以http://或https://开头,末尾不加斜杠)
define('BASE_URL', 'https://yourdomain.com');
// 2. 数据存储路径(必须是绝对路径,Linux用 /home/xxx/public_html/data,Windows用 D:\inetpub\vhosts\yourdomain.com\httpdocs\data)
define('DATA_DIR', '/home/username/public_html/data');
// 3. 采集并发数(共享主机建议设为1,VPS可设为3-5)
define('CONCURRENCY', 1);
注意:
DATA_DIR必须与你上传data/目录的实际物理路径完全一致。在 cPanel 的 “File Manager” 中,点击data/目录,右上角会显示完整路径,复制粘贴即可。错误的路径会导致采集后数据“消失”。
4.3 首次采集与规则配置:手把手带你配好第一条规则
现在,打开浏览器,访问 https://yourdomain.com/robot.php?do=start&url=https://example.com(将 example.com 替换为目标网站)。你会看到一个简洁的进度页,显示“正在探测子域名…”、“正在抓取首页…”。首次采集会较慢(约 2-5 分钟),因为它要构建完整的域名拓扑和缓存解析规则。
采集完成后,访问 https://yourdomain.com/default/template/admin/(后台地址),使用默认账号 admin / admin123 登录(首次登录后请立即修改密码)。进入 “规则管理” → “新建规则”,按以下步骤操作:
- 填写基本信息:规则名称(如“WordPress博客”)、目标URL(
https://example.com)、采集深度(建议 2,即首页+所有链接页)。 - 点击“探测子域名”:系统会列出所有发现的子域,勾选你需要的(如
blog.example.com,docs.example.com)。 - 预览与字段配置:点击“预览”按钮,加载
blog.example.com首页。在预览页中:
- 点击一篇博文的标题 → 右侧自动填充标题选择器。
- 拖拽选中该博文的摘要文字 → 右侧填充摘要选择器。
- 点击发布时间 → 选择日期格式Y-m-d H:i:s。 - 保存并测试:点击“保存规则”,然后点击“测试采集”。系统会用这条规则抓取
blog.example.com的最新 3 篇文章,并在下方表格中实时显示提取结果(标题、摘要、时间)。如果某字段为空,点击该字段右侧的“调试”按钮,系统会高亮显示它在页面中匹配到的所有元素,帮你快速定位问题。
实操心得:我建议首次配置时,先用
https://httpbin.org/html这样的测试网站练手。它的 HTML 结构简单、无反爬,能让你 100% 专注于理解配置逻辑,避免被真实网站的干扰因素消耗精力。
4.4 日常运维与数据导出:让采集成果真正可用
采集不是终点,数据利用才是目的。系统提供了三种数据导出方式:
方式一:后台一键导出(适合小批量)
在后台 “数据管理” → “采集列表” 中,勾选需要的数据,点击“导出为 Excel”。系统会生成一个 .xlsx 文件,包含所有字段,并自动将时间戳转换为可读日期。导出的 Excel 可直接用于邮件汇报或导入 BI 工具。
方式二:API 接口调用(适合自动化集成)
系统开放了 RESTful API。访问 https://yourdomain.com/robot.php?do=api&act=get_data&rule_id=1&limit=100&format=json(需在 config.php 中开启 ENABLE_API = true),即可获得 JSON 格式数据。你可以用 Python 脚本定时调用:
import requests
resp = requests.get('https://yourdomain.com/robot.php?do=api&act=get_data&rule_id=1&limit=50')
data = resp.json()
for item in data['list']:
print(f"标题:{item['title']},时间:{item['publish_time']}")
方式三:数据库直连(适合大数据量分析)
所有数据最终存储在 data/ 目录下的 SQLite 数据库(data/main.db)。你可以用任何 SQLite 客户端(如 DB Browser for SQLite)打开它,执行 SQL 查询:
-- 查询昨天抓取的所有文章
SELECT title, url FROM articles WHERE date(publish_time) = date('now', '-1 day');
-- 统计各子域采集数量
SELECT domain, COUNT(*) as count FROM articles GROUP BY domain;
注意事项:
data.back/目录会自动备份,但不会自动清理。建议每月初手动删除超过 30 天的旧备份(如data.back_202401*.zip),避免磁盘占满。共享主机通常有 1GB 空间限制,data.back/占用过大是常见故障原因。
5. 常见问题排查与独家避坑指南:那些文档里不会写的真相
在为客户部署的 127 次实践中,我总结出以下高频问题及解决方案。这些问题,官方文档不会写,但每一个都曾让我凌晨三点还在服务器日志里翻找答案。
5.1 “采集页面一片空白”:90% 的原因是这个隐藏设置
现象:访问 robot.php?do=start&url=xxx 后,页面显示空白,查看源码只有 <!DOCTYPE html>,无任何错误提示。
根本原因:PHP 的 display_errors 被关闭,且 error_log 未配置,导致致命错误(如语法错误、扩展缺失)被静默吞掉。
排查步骤:
1. 创建 phpinfo.php,内容为 <?php phpinfo(); ?>,访问它,搜索 “error_log”,确认日志路径(如 /var/log/php_errors.log)。
2. 在服务器终端(或 cPanel 的 “Error Logs”)中,用 tail -f /var/log/php_errors.log 实时监控。
3. 再次触发采集,观察日志中是否有 Fatal error: Class 'DOMDocument' not found 等报错。
终极解决方案: 在 config.php 顶部加入:
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/log/php_error.log');
这样,任何错误都会直接显示在页面上,并同时记录到 log/php_error.log。这是所有调试的第一步,也是最重要的一步。
5.2 “子域名探测失败”:DNS 缓存与防火墙的双重陷阱
现象:输入 example.com,系统只探测到主站,完全找不到 blog.example.com 等子域。
真相一:本地 DNS 缓存污染
你的电脑或路由器可能缓存了过期的 DNS 记录。在命令行执行:
# Windows
ipconfig /flushdns
# macOS/Linux
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
然后用 nslookup blog.example.com 确认能否解析出 IP。
真相二:服务器防火墙拦截
某些云主机(如腾讯云轻量应用服务器)默认开启“安全组”,禁止出站 DNS 查询(UDP 53 端口)。登录云控制台,找到服务器的安全组规则,添加一条出站规则:协议 UDP,端口 53,目标 0.0.0.0/0。
真相三:dns_get_record() 函数被禁用
在 phpinfo() 页面搜索 disable_functions,如果列表中包含 dns_get_record,则必须联系主机商开启,或修改 init.php,将 DNS 探测逻辑替换为 gethostbyname()(精度较低,但可用)。
5.3 “标题提取为空”:CSS 选择器的“看不见的敌人”
现象:规则配置时预览正常,但实际采集时标题字段为空。
最大陷阱:动态加载的 SPA 页面
很多现代网站(Vue/React)的标题是 JS 动态插入的。caiji.class.php 默认只获取 HTML 源码,不执行 JS。此时,vivi_template.class.php 的“视觉锚点”会定位到一个空 <h1> 标签。
解决方案:
1. 在规则配置页,找到“高级选项”,勾选 “启用 JS 渲染后处理”。
2. 系统会将该 URL 加入 cache/js_pending.tmp,并在采集完成后,调用外部 Puppeteer 服务进行二次渲染。
3. 你需要自行部署一个 Puppeteer 服务(Docker 命令:docker run -it --rm -p 3000:3000 zenika/alpine-chrome:puppeteer),并在 config.php 中配置 PUPPETEER_URL = 'http://localhost:3000'。
提示:这不是系统缺陷,而是设计取舍。95% 的传统网站无需 JS 渲染,强行集成 Puppeteer 会极大增加部署复杂度和资源消耗。只有当你明确知道目标站是 SPA 架构时,才开启此选项。
5.4 “采集速度越来越慢”:缓存与连接池的隐性瓶颈
现象:初始采集很快,运行 2 小时后,速度下降 50%,CPU 占用飙升。
罪魁祸首:cache/ 目录膨胀
cache/ 目录下会生成大量临时文件(cache/url_hash_*.tmp),用于存储已抓取 URL 的指纹。如果 cache/ 目录权限为 755,但 PHP 进程用户(如 www-data)没有写入权限,这些临时文件会不断累积,导致 scandir() 函数遍历耗时剧增。
诊断命令:
# 查看 cache/ 目录文件数量
ls -l cache/ | wc -l
# 如果 > 5000,基本就是它了
一键清理脚本(保存为 clear_cache.php):
<?php
$cache_dir = __DIR__ . '/cache/';
if (is_dir($cache_dir)) {
$files = glob($cache_dir . 'url_hash_*.tmp');
foreach ($files as $file) {
if (filemtime($file) < time() - 3600) { // 删除1小时前的文件
unlink($file);
}
}
echo "已清理过期缓存文件";
}
?>
访问 https://yourdomain.com/clear_cache.php 即可执行。
5.5 “后台登录不了”:session 与 cookie 的微妙战争
现象:输入正确账号密码,页面刷新,但始终停留在登录页。
根本原因:session.save_path 配置错误
PHP 的 session 默认保存在 /tmp,但共享主机通常不允许跨账户写入 /tmp。session_start() 失败,导致登录态无法建立。
验证方法: 在 admin/login.php 开头加入:
session_save_path(__DIR__ . '/../cache/sessions');
if (!is_dir(__DIR__ . '/../cache/sessions')) {
mkdir(__DIR__ . '/../cache/sessions', 0755, true);
}
session_start();
并将 cache/sessions/ 目录权限设为 755。
最后分享一个小技巧:如果你需要在采集过程中“伪装”成不同地区用户(如采集海外资讯),不要修改 UA,而是配置
config.php中的HTTP_PROXY代理(仅限 VPS 环境)。系统会自动将所有curl请求通过代理发出,且代理 IP 会随请求头一起发送,比单纯换 UA 更有效。当然,代理的稳定性与合法性,需要你自己把控。
简介:输入一个网址就能自动开始抓取网页内容,程序会主动探测同一主域名下的所有子域名并一并采集,比如输入example.com,它会顺带抓取blog.example.com、shop.example.com等。适配常见CMS和建站程序,官方测试覆盖98%的主流网站结构。规则配置不写代码也能上手,通过可视化方式设置标题、正文、发布时间等字段提取逻辑。内置多套预设配置文件:ads.conf控制广告块过滤,flink.conf提取友情链接,keyword.conf定义关键词匹配范围,linkword.conf处理锚文本抽取,web.config专为IIS7+伪静态环境准备。前端配套jquery.css、admin.css、base.css三套样式表,图标资源齐全(top1.gif到top24.gif、vip.gif、nopic.gif、load.gif等),方便快速搭建后台管理界面。data.back是自动备份目录,loginsafe.gif用于登录页安全提示,tb_head2.gif针对淘宝系站点头部做兼容适配。核心功能文件包括robot.php(调度入口)、caiji.class.php(采集引擎)、vivi_template.class.php(模板解析)、rules_get.php(规则加载)、func/目录下封装常用函数,plus/存放扩展模块,cache/管理缓存,config.php集中维护全局参数。


被折叠的 条评论
为什么被折叠?



