Получите BeautifulSoup для правильного разбора php-тегов или игнорирования их - PullRequest
0 голосов
/ 24 апреля 2019

В настоящее время мне нужно проанализировать множество файлов .phtml, получить определенные HTML-теги и добавить в них пользовательский атрибут данных.Я использую Python Beautifulsoup для анализа всего документа и добавления тегов, и эта часть работает отлично.

Проблема в том, что в файлах просмотра (phtml) есть теги, которые также анализируются.Ниже приведен пример ввода-вывода

INPUT

<?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>

OUTPUT

<?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 голосов
/ 26 апреля 2019

Лучше всего удалить все элементы 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)
...