【问题标题】:BeautifulSoup and php/html filesBeautifulSoup 和 php/html 文件
【发布时间】:2017-01-12 20:31:34
【问题描述】:

我一直在使用 BeautifulSoup 将一些古老的 HTML 文件中的相对 URL 从存档站点转换为绝对 URL(主要是为了通过 .htaccess 规则更好地定位它们)。这部分我已经记下来了:搜索某些标签及其 atts,使用 urllib.parse.urljoin(这是 Python3)进行更正。很好。

但是,此集合中也有一些 .php 文件,来自该网站的后期。他们大多使用 3-5 行来包含其他 .php 文件,然后是 HTML,但也有一些例外。

问题: BeautifulSoup 解析器试图解释 <?php ?> 标记之间的内容。事实上,在某些情况下,他们只是去掉了尖括号,但留下了问号——我粗暴地解决了这样的行为:

for c in soup.contents:
    c = str(c) # previously a BeautifulSoup Tag

    # I don't need soup after this point, hence not reconstructing contents
    c = ('<' if c.startswith('?') else '') + c
    c = c + ('>' if c.endswith('?') else '')

但无论如何,我注意到整个&lt;?php ?&gt; 标签经常被破坏,具体方式取决于解析器。例如,html5lib 解析器采用以下几行:

<?
//echo "BEGIN PAGE: " . $_SESSION["i"]."<br>";
include ('util.php');

并将标签解释为以&gt; 结尾,而&lt;br&gt; 结束。

我更愿意让 php 标记保持不变。 (显然,在理想情况下,解析器会通读它们并处理任何内部 HTML,但这似乎要求太多了!)

可能的解决方案

  1. 跳过 .php 文件,只使用 .html —— 所做的工作不是必需的,只是优化,所以不会有太大的损失;
  2. 找到文档中未提及的可以更好地处理这些情况的 BeautifulSoup 解析器;
  3. 自己预解析文本,提取所有 &lt;?php ?&gt; 块,并在使用 BeautifulSoup 的工作完成后重新插入,注意回忆它们应该落在哪里(如果这数千个文件中的任何一个有 &lt;?php echo 'foobar' ?&gt;,可能会非常困难例如,在 HTML 行的中间)
  4. 与上述类似,以编程方式保护所有 &lt;?php ?&gt; 标记不受解析器的影响,例如在它们周围插入HTML cmets,然后在soup之后移除保护

【问题讨论】:

  • 如果您对自己的问题有答案,可以将其添加为答案,而不是将其包含在问题中。
  • 如果你已经知道答案,为什么还要问它?
  • 如果您不习惯这种格式,这可能看起来很奇怪,但这是首选的方式。 See the help center for more details.
  • @Don't Panic 谢谢!

标签: php python html parsing beautifulsoup


【解决方案1】:

回答我自己的问题... :)

我使用了解决方案 #4:通过在它们周围插入 HTML cmets 以编程方式保护所有 &lt;?php ?&gt; 标记免受解析器的影响。然后解析器跳过解释注释中的任何内容。稍后,当使用soup.prettify()soup.contents 时,可以直接将输出中的&lt;!--&lt;? 替换为&lt;?,同样用于结束标签。

请注意,这不适用于用于在某些 HTML 标记中生成动态内容的 PHP 标记,例如:

<a href= "<? echo foo_bar(); ?>" >

html.parserlxmlhtml5lib 的当前版本都将其解释为 &lt;a&gt; 的一系列无意义属性,即使 PHP 标记包含在 HTML cmets 中也是如此。在这种情况下,我使用正则表达式手动提取标签来解决我的问题。

【讨论】:

猜你喜欢
  • 2017-08-26
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 2017-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多