获取BeautifulSoup以正确解析php标签或忽略它们

时间:2019-04-24 15:55:06

标签: php python parsing beautifulsoup html-parsing

我目前需要解析许多.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自定义规则忽略或beautifulsoup? 谢谢!

1 个答案:

答案 0 :(得分:0)

最好的选择是删除所有PHP元素,然后再将其提供给BeautifulSoup进行解析。这可以通过使用正则表达式来发现所有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)
相关问题