必须同时安装 symfony/dom-crawler 和 symfony/css-selector 才能使用 css 选择器;仅装前者会导致 filter() 报 logicexception 或静默失效;初始化需传 html 字符串并指定编码,避免空响应或乱码;filter() 依赖 css 解析、容错弱,filterxpath() 更严格但需正确语法;调用 text()、attr() 前须检查节点存在。

直接装 symfony/dom-crawler 就能解析 HTML,但想用 CSS 选择器(比如 filter('article h2'))必须额外装 symfony/css-selector,否则会报错或返回空结果。
composer require 命令要分两步写
DomCrawler 本身不带 CSS 解析能力,filter() 方法依赖 symfony/css-selector。只装一个会导致调用失败或静默失效:
-
composer require symfony/dom-crawler—— 基础 DOM 遍历可用,但filter('div.class')会抛出LogicException: Unable to parse CSS selector -
composer require symfony/css-selector—— 必须补上这行,否则所有 CSS 选择器都不可用 - 如果项目已用 Laravel 或 Symfony 全栈框架,
css-selector可能已存在,但别假设——运行composer show symfony/css-selector确认是否在 vendor 里
new Crawler() 时传 HTML 字符串最稳妥
从字符串初始化是最快、最可控的方式;别指望 Crawler 自动发 HTTP 请求:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
-
$crawler = new Crawler($html_string);—— 推荐,编码明确,无外部依赖 -
new Crawler(null, 'https://example.com')不会自动抓取,只是设 base URL,后续仍需手动addContent(file_get_contents(...)) - 若 HTML 含中文或特殊符号,务必指定编码:
$crawler->addHtmlContent($html, 'utf-8'),否则text()可能乱码 - 避免直接传
file_get_contents()结果而不检查返回值——空响应或 404 会导致Crawler解析失败但不报错
filter() 和 filterXPath() 的行为差异很关键
两者返回的都是 Crawler 实例,但底层机制不同,影响结果范围和容错性:
-
$crawler->filter('ul li')—— 依赖css-selector,语法友好,但对 malformed HTML 容错弱(如缺失闭合标签时可能漏匹配) -
$crawler->filterXPath('//ul/li')—— 原生 DOM XPath,更严格,适合结构清晰的文档;注意 XPath 表达式必须以//或.开头,'ul/li'无效 - 混用时注意:
filterXPath()返回的节点集不能直接链式调用filter(),得先->reduce()或重新 new Crawler - 性能上,简单选择器二者差别不大;但嵌套多层或含伪类(如
:nth-child(2))时,filter()更慢,且部分伪类不支持
提取文本前先确认节点存在,否则 text() 报 Warning
text() 和 html() 在空节点上调用会触发 PHP Warning 并返回空字符串,容易掩盖逻辑错误:
- 别写
$title = $crawler->filter('h1')->text();—— 若没匹配到h1,text()返回空,但你不知道是内容为空还是没找到 - 应先判断:
if ($crawler->filter('h1')->count() > 0) { $title = $crawler->filter('h1')->text(); } - 或用
first()+isEmpty():$node = $crawler->filter('h1')->first(); if (!$node->isEmpty()) { $title = $node->text(); } -
attr('href')同理,未匹配或属性不存在时返回null,不是空字符串
真正麻烦的不是语法,而是 HTML 源本身——JS 渲染的内容、编码声明缺失、自闭合标签误写,这些都会让 filter() 返回比预期少的节点。别跳过 inspect 源 HTML 这一步。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










