首页 > 解决方案 > 获取 BeautifulSoup 以正确解析 php 标签或忽略它们

问题描述

我目前需要解析很多 .phtml 文件,获取特定的 html 标记并向它们添加自定义数据属性。我正在使用 python beautifulsoup 来解析整个文档并添加标签,这部分工作得很好。

问题是在视图文件(phtml)上也有被解析的标签。下面是一个输入输出的例子

输入

<?php

$stars = $this->getData('sideBarCoStars', []);

if (!$stars) return;

$sideBarCoStarsCount = $this->getData('sideBarCoStarsCount');
$title = $this->getData('sideBarCoStarsTitle');
$viewAllUrl = $this->getData('sideBarCoStarsViewAllUrl');
$isDomain = $this->getData('isDomain');
$lazy_load = $lazy_load ?? 0;
$imageSrc = $this->getData('emptyImageData');
?>
<header>
    <h3>
        <a href="<?php echo $viewAllUrl; ?>" class="noContentLink white">
        <?php echo "{$title} ({$sideBarCoStarsCount})"; ?>
        </a>
    </h3>

输出

<?php
$stars = $this->
getData('sideBarCoStars', []);

if (!$stars) return;

$sideBarCoStarsCount = $this-&gt;getData('sideBarCoStarsCount');
$title = $this-&gt;getData('sideBarCoStarsTitle');
$viewAllUrl = $this-&gt;getData('sideBarCoStarsViewAllUrl');
$isDomain = $this-&gt;getData('isDomain');
$lazy_load = $lazy_load ?? 0;
$imageSrc = $this-&gt;getData('emptyImageData');
?&gt;
<header>
 <h3>
  <a class="noContentLink white" href="&lt;?php echo $viewAllUrl; ?&gt;">
   <?php echo "{$title} ({$sideBarCoStarsCount})"; ?>
  </a>
 </h3>

我尝试了不同的方法,但没有成功让 beautifulsoup 忽略 PHP 标签。是否有可能获得 html.parser 自定义规则来忽略或美丽汤?谢谢!

标签: phppythonparsingbeautifulsouphtml-parsing

解决方案


您最好的选择是在将其提供给 BeautifulSoup 解析之前删除所有 PHP 元素。这可以使用正则表达式来发现所有 PHP 部分并用安全的占位符文本替换它们。

使用 BeautifulSoup 进行所有修改后,即可替换 PHP 表达式。

由于 PHP 可以在任何地方,即也可以在带引号的字符串中,因此最好使用简单的唯一字符串占位符,而不是尝试将其包装在 HTML 注释中(请参阅 参考资料php_sig)。

re.sub()可以赋予功能。每次进行替换时,原始 PHP 代码都存储在一个数组 ( php_elements) 中。然后反向进行,即搜索 的所有实例php_sig并将它们替换为 的下一个元素php_elements。如果一切顺利,php_elements最后应该是空的,如果不是,那么您的修改导致占位符被删除。

from bs4 import BeautifulSoup
import re

html = """<html>
<body>

<?php 
$stars = $this->getData('sideBarCoStars', []);

if (!$stars) return;

$sideBarCoStarsCount = $this->getData('sideBarCoStarsCount');
$title = $this->getData('sideBarCoStarsTitle');
$viewAllUrl = $this->getData('sideBarCoStarsViewAllUrl');
$isDomain = $this->getData('isDomain');
$lazy_load = $lazy_load ?? 0;
$imageSrc = $this->getData('emptyImageData');
?>

<header>
    <h3>
        <a href="<?php echo $viewAllUrl; ?>" class="noContentLink white">
        <?php echo "{$title} ({$sideBarCoStarsCount})"; ?>
        </a>
    </h3>

</body>"""

php_sig = '!!!PHP!!!'
php_elements = []

def php_remove(m):
    php_elements.append(m.group())
    return php_sig

def php_add(m):
    return php_elements.pop(0)

# Pre-parse HTML to remove all PHP elements
html = re.sub(r'<\?php.*?\?>', php_remove, html, flags=re.S+re.M)

soup = BeautifulSoup(html, "html.parser")

# Make modifications to the soup
# Do not remove any elements containing PHP elements

# Post-parse HTML to replace the PHP elements
html = re.sub(php_sig, php_add, soup.prettify())

print(html)

推荐阅读