不存在官方维护的名为 crawler 的 Composer 包,应使用 spatie/crawler(推荐)、goutte/goutte 或 symfony/dom-crawler 等替代方案;直接执行 composer require crawler 会报错。

Composer 安装 crawler 库前先确认有没有这个包
根本不存在官方维护的名为 crawler 的 Composer 包。你搜到的所谓“crawler”库,大概率是:spatie/crawler(最常用)、goutte/goutte(轻量 HTTP 抓取)、symfony/dom-crawler(配合 HTTP Client 使用),或者一些已废弃/无人维护的冷门包。
别直接跑 composer require crawler —— 这会报错:Could not find package crawler。
实操建议:
- 用
composer search crawler查当前可用包名(注意看 stars 和 last update 时间) - 优先选
spatie/crawler:它自带并发、队列、URL 去重、robots.txt 遵守,适合中等规模抓取 - 如果只是解析 HTML 内容,
symfony/dom-crawler+symfony/http-client组合更轻、更可控 - 避免用
fabpot/goutte(旧版)或phpcrawl(PHP 5 时代,不兼容 PHP 8+)
安装 spatie/crawler 并初始化一个基础爬虫
spatie/crawler 是目前最稳妥的选择,但依赖 Guzzle 和 Symfony 组件,PHP 版本需 ≥ 8.0。
运行命令安装:
composer require spatie/crawler
注意:它默认不带浏览器渲染能力(不能执行 JS),纯服务端 HTML 解析。如果你要抓 JS 渲染页,得额外配 Puppeteer 或 Playwright,spatie/crawler 不处理这部分。
一个最小可运行示例:
setCrawlObserver(new class extends \Spatie\Crawler\CrawlObservers\CrawlObserver {
public function crawled(\Psr\Http\Message\UriInterface $url, \GuzzleHttp\Psr7\Response $response, ?\Throwable $error = null): void
{
if ($error === null) {
echo "✅ {$url} ({$response->getStatusCode()})\n";
} else {
echo "❌ {$url}: {$error->getMessage()}\n";
}
}
})
->startCrawling('https://example.com');
常见坑:
- 没配
allow_url_fopen=On或 OpenSSL 扩展未启用 → 报cURL error 60: SSL certificate problem,加->setCrawlRequestOptions(['verify' => false])仅限测试 - 目标站有反爬(如 Cloudflare)→
spatie/crawler会直接被 403 或 503 拦住,需手动加User-Agent和延迟 - 没写
->respectRobotsTxt()→ 可能违反 robots.txt,被封 IP
抓取后怎么提取网页标题和链接?用 DomCrawler 更直接
很多人装了 spatie/crawler 却卡在“怎么取数据”。它本身不提供 DOM 查询 API,得靠 symfony/dom-crawler 或原生 DOMDocument。
推荐组合:用 spatie/crawler 负责调度 + symfony/dom-crawler 负责解析:
composer require symfony/dom-crawler symfony/css-selector
在 crawled() 回调里加解析逻辑:
$crawler = new \Symfony\Component\DomCrawler\Crawler((string) $response->getBody());
$title = $crawler->filter('title')->text(null, '');
$links = $crawler->filter('a[href]')->extract(['href']);
注意点:
-
filter()支持 CSS 选择器,但不支持所有现代语法(比如:has()在旧版本不支持) -
text()第二个参数是 fallback 值,防止空节点报 Notice - 如果 HTML 是乱码(如 GBK),需先用
mb_convert_encoding()转 UTF-8,否则filter()失效
为什么本地跑通了,上线就超时或内存溢出?
spatie/crawler 默认并发 10,深度不限,遇到大型网站(比如整站抓取)很容易撑爆内存或触发超时。
必须显式限制:
- 加
->setMaximumCrawlCount(100)控制总请求数 - 加
->setMaximumDepth(3)防止无限跳转子页面 - 加
->setDelayBetweenRequests(1000)(毫秒),降低请求频率 - 生产环境务必用
->executeJavaScript(false)(默认就是 false,但有人误开)
还有个隐藏问题:日志输出太多(尤其用 var_dump 或 echo)会导致 CLI 缓冲区满、进程假死。线上部署建议关掉所有调试输出,改用 Monolog 记日志。
真正难的不是装包,而是判断该不该爬、能不能爬、怎么爬得稳——robots.txt、User-Agent 合理性、响应头里的 X-Robots-Tag、RateLimit 字段,这些比写代码花的时间多得多。










