PHP项目Symfony css-selector选择器

wen PHP项目 2

本文目录导读:

PHP项目Symfony css-selector选择器

  1. 安装与基础使用
  2. 常用CSS选择器示例
  3. 高级操作
  4. 实际开发示例
  5. 注意事项
  6. 常见问题解决

在Symfony项目中,CSS选择器(CSS Selector)主要通过 Symfony DomCrawler 组件 实现,它允许你使用CSS选择器语法来解析和遍历HTML/XML文档。

安装与基础使用

安装组件

composer require symfony/dom-crawler
composer require symfony/css-selector  # CSS选择器转换器

基本用法

use Symfony\Component\DomCrawler\Crawler;
$html = '<html>
    <body>
        <div class="content">
            <h1>标题</h1>
            <p class="text">第一段</p>
            <p class="text">第二段</p>
            <a href="/link1" class="link">链接1</a>
            <a href="/link2" class="link">链接2</a>
            <ul id="list">
                <li data-id="1">项目1</li>
                <li data-id="2">项目2</li>
            </ul>
        </div>
    </body>
</html>';
$crawler = new Crawler($html);

常用CSS选择器示例

标签选择器

// 选择所有p标签
$paragraphs = $crawler->filter('p');
// 获取第一个p标签的内容
$firstParagraph = $crawler->filter('p')->first()->text();
// 遍历所有p标签
$crawler->filter('p')->each(function ($node) {
    echo $node->text();
});

类选择器

// 选择class为"text"的元素
$textElements = $crawler->filter('.text');
// 选择同时包含两个class的元素
$elements = $crawler->filter('.text.link');
// 多类选择器
$elements = $crawler->filter('.text.link');

ID选择器

// 选择id为"list"的元素
$list = $crawler->filter('#list');

属性选择器

// 选择有href属性的元素
$withHref = $crawler->filter('[href]');
// 选择href等于特定值
$specificLink = $crawler->filter('[href="/link1"]');
// 选择href包含特定文本
$partialMatch = $crawler->filter('[href*="link"]');
// 选择href以特定文本开头
$startsWith = $crawler->filter('[href^="/link"]');
// 选择href以特定文本结尾
$endsWith = $crawler->filter('[href$="1"]');
// 选择data属性
$dataItems = $crawler->filter('[data-id]');
$item1 = $crawler->filter('[data-id="1"]');

组合选择器

// 后代选择器
$divParagraphs = $crawler->filter('div p');
// 子元素选择器
$directChildren = $crawler->filter('div > p');
// 相邻兄弟选择器
$adjacentSibling = $crawler->filter('h1 + p');
// 通用兄弟选择器
$generalSibling = $crawler->filter('h1 ~ p');

伪类选择器

// 第一个子元素
$firstChild = $crawler->filter('li:first-child');
// 最后一个子元素
$lastChild = $crawler->filter('li:last-child');
// 第n个子元素
$nthChild = $crawler->filter('li:nth-child(2)');
// 奇数/偶数元素
$oddItems = $crawler->filter('li:nth-child(odd)');
$evenItems = $crawler->filter('li:nth-child(even)');
// 不包含某个选择器
$notClass = $crawler->filter('p:not(.special)');

高级操作

链式调用

// 先选择父元素,再选择子元素
$result = $crawler
    ->filter('.content')
    ->filter('p')
    ->first()
    ->text();

获取属性和文本

// 获取文本内容
$text = $crawler->filter('h1')->text();
// 获取HTML内容
$html = $crawler->filter('div')->html();
// 获取属性值
$href = $crawler->filter('a')->attr('href');
// 获取多个属性
$attributes = $crawler->filter('a')->extract(['href', 'class']);

数据提取

// 提取多个元素的数据
$links = $crawler->filter('a')->each(function ($node) {
    return [
        'text' => $node->text(),
        'href' => $node->attr('href'),
        'class' => $node->attr('class'),
    ];
});
// 提取表格数据
$tableData = $crawler->filter('table tr')->each(function ($row) {
    return $row->filter('td')->each(function ($cell) {
        return $cell->text();
    });
});

实际开发示例

网页爬虫示例

// 在Controller中使用
public function scrapeWebsite()
{
    $client = new \Symfony\Component\BrowserKit\HttpBrowser(); // 需要安装 browser-kit
    $crawler = $client->request('GET', 'https://example.com');
    // 提取文章标题
    $articles = $crawler->filter('article')->each(function ($node) {
        return [
            'title' => $node->filter('h2')->text(),
            'description' => $node->filter('.description')->text(),
            'link' => $node->filter('a')->attr('href'),
            'image' => $node->filter('img')->attr('src'),
        ];
    });
    // 提取分页链接
    $nextPage = $crawler->filter('a.next-page')->attr('href');
    // 提取表单数据
    $form = $crawler->filter('#search-form')->form();
    $form['q'] = '搜索关键词';
    $result = $client->submit($form);
}

表单处理

// 选择和提交表单
$form = $crawler->filter('form')->form();
$form['username'] = 'user123';
$form['password'] = 'pass456';
$crawler = $client->submit($form);
// 获取表单字段
$fields = $form->getValues();

注意事项

  1. 性能考虑:对于大型文档,避免过度使用each(),考虑使用reduce()或直接提取
  2. 命名空间:确保XML文档正确处理命名空间
  3. 编码问题:处理非UTF-8编码时需注意字符编码
  4. :CSS选择器只能处理静态HTML,动态内容需要配合JavaScript渲染工具

常见问题解决

// 处理命名空间
$crawler = new Crawler($xmlContent);
$crawler->registerNamespace('ns', 'http://example.com/ns');
$elements = $crawler->filter('ns|element');
// 处理编码问题
$html = mb_convert_encoding($html, 'UTF-8', 'GBK');
$crawler = new Crawler($html);

CSS选择器是Symfony DomCrawler最强大的功能之一,合理使用可以大幅提高HTML解析和数据提取的效率。

抱歉,评论功能暂时关闭!