如何用python检测字符串是不是包含html代码?

Posted

技术标签:

【中文标题】如何用python检测字符串是不是包含html代码?【英文标题】:How to detect with python if the string contains html code?如何用python检测字符串是否包含html代码? 【发布时间】:2014-09-11 10:09:46 【问题描述】:

如何检测字符串是否包含 html(可以是 html4、html5,只是文本中的部分 html)?我不需要 HTML 版本,而是如果字符串只是一个文本或者它包含一个 html。文本通常是多行的,也有空行

更新:

示例输入:

html:

<head><title>I'm title</title></head>
Hello, <b>world</b>

非html:

<ht fldf d><
<html><head> head <body></body> html

【问题讨论】:

为什么需要知道?你打算做什么不同的事情? 只检测字符串是否包含html,然后删除字符串或打印出来 【参考方案1】:

您可以使用 HTML 解析器,例如 BeautifulSoup。请注意,它确实尽最大努力解析 HTML,甚至是损坏的 HTML,它可能非常宽松,也可能不是非常宽松,具体取决于 underlying parser:

>>> from bs4 import BeautifulSoup
>>> html = """<html>
... <head><title>I'm title</title></head>
... </html>"""
>>> non_html = "This is not an html"
>>> bool(BeautifulSoup(html, "html.parser").find())
True
>>> bool(BeautifulSoup(non_html, "html.parser").find())
False

这基本上试图在字符串中找到任何 html 元素。如果找到 - 结果是 True

另一个带有 HTML 片段的示例:

>>> html = "Hello, <b>world</b>"
>>> bool(BeautifulSoup(html, "html.parser").find())
True

或者,您可以使用lxml.html

>>> import lxml.html
>>> html = 'Hello, <b>world</b>'
>>> non_html = "<ht fldf d><"
>>> lxml.html.fromstring(html).find('.//*') is not None
True
>>> lxml.html.fromstring(non_html).find('.//*') is not None
False

【讨论】:

non-html = "&lt;html&gt;&lt;head&gt; head &lt;body&gt;&lt;/body&gt; html" bool(BeautifulSoup(non_html, "html.parser").find()) =&gt; True 怎么样?它不是 html sn-p 即使non_html = "&lt;html head&gt; head &lt;body jdkjs /body&gt; html dkslfjglangaiowmgiowe" 也会通过测试:( @static 好吧,这将是 True,因为 BeautifulSoup 会尽力解析 html 并保持宽松。它会将其转换为&lt;html&gt;&lt;head&gt; head &lt;body&gt;&lt;/body&gt; html&lt;/head&gt;&lt;/html&gt; 很好,它通过了许多有问题的案例,但看起来,它通过了太多:non_html = "&lt;ht fldf d&gt;&lt;" 也可以工作 @static 是的,在这种情况下,它认为fldfd 是属性,而ht 标签只是没有关闭。很好的例子,谢谢:)【参考方案2】:

我想到的一种方法是通过尝试将文本解析为 HTML 并将该集合与一组已知的可接受的 HTMl 元素相交来使找到的开始和结束标记相交。

示例:

#!/usr/bin/env python

from __future__ import print_function

from HTMLParser import HTMLParser


from html5lib.sanitizer import HTMLSanitizerMixin


class TestHTMLParser(HTMLParser):

    def __init__(self, *args, **kwargs):
        HTMLParser.__init__(self, *args, **kwargs)

        self.elements = set()

    def handle_starttag(self, tag, attrs):
        self.elements.add(tag)

    def handle_endtag(self, tag):
        self.elements.add(tag)


def is_html(text):
    elements = set(HTMLSanitizerMixin.acceptable_elements)

    parser = TestHTMLParser()
    parser.feed(text)

    return True if parser.elements.intersection(elements) else False


print(is_html("foo bar"))
print(is_html("<p>Hello World!</p>"))
print(is_html("<html><head><title>Title</title></head><body><p>Hello!</p></body></html>"))  # noqa

输出:

$ python foo.py
False
True
True

这适用于包含 HTML 元素子集的部分文本。

注意:这使用了html5lib,因此它可能不一定适用于其他文档类型,但该技术可以轻松适应。

【讨论】:

它与你的解决方案基本相同——只是一个不同的库并使用已知元素的集合交集:P 我在 html5lib 中找不到 HTMLSanitizerMixin【参考方案3】:

您可以轻松扩展已处理解析的内置HTMLParser,并收集(​​开始/结束)tagsattrsdata。要断言文档是否有效,开始标签的数量应该与结束标签的数量相匹配:

from html.parser import HTMLParser


class MyHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.start_tags = list()
        self.end_tags = list()
        self.attributes = list()
    
    def is_text_html(self):
        return len(self.start_tags) == len(self.end_tags)

    def handle_starttag(self, tag, attrs):
        self.start_tags.append(tag)
        self.attributes.append(attrs)

    def handle_endtag(self, tag):
        self.end_tags.append(tag)

    def handle_data(self, data):
        print("Encountered some data  :", data)

然后

>>> parser = MyHTMLParser()
>>> parser.feed("<head><title>I'm title</title></head>"
                "Hello, <b>world</b>")
>>> parser.is_text_html()

True

>>> parser.feed("<ht fldf d><"
                "<html><head> head <body></body> html")
>>> parser.is_text_html()

False

【讨论】:

【参考方案4】:

如果您只需要知道字符串是否包含 html 文本,那么此处未列出的另一种解决方案是使用如下的正则表达式:

&lt;/?\s*[a-z-][^&gt;]*\s*&gt;|(\&amp;(?:[\w\d]+|#\d+|#x[a-f\d]+);)

请记住,虽然这比使用 HTML 解析器要快得多,但根据您所期望的 html 标记的复杂性,它可能会不准确。

Here is a test 了解上述正则表达式的一般概念。

【讨论】:

【参考方案5】:

检查结束标签。我相信这是最简单和最强大的。

"</html>" in possibly_html

如果有一个结束的html标签,那么它看起来像html,否则没有那么多。

【讨论】:

这是一个很好的答案,假设输入是一个完整的 HTML 页面(其中包含 &lt;/html&gt;。它不适用于部分 HTML(如 &lt;b&gt;some word&lt;/b&gt;)。 这个方法可以扩展为搜索任何html结束标签,比如b。正则表达式可能会使其更快,但基本原理保持不变。 因为你不知道文本中有哪些潜在的 HTML 标记,所以这种技术不能很好地工作:/【参考方案6】:

扩展上一篇文章我会做这样的事情来快速简单:

import sys, os

if os.path.exists("file.html"):
    checkfile=open("file.html", mode="r", encoding="utf-8")
    ishtml = False
    for line in checkfile:
        line=line.strip()
        if line == "</html>"
            ishtml = True
    if ishtml:
        print("This is an html file")
    else:
        print("This is not an html file")

【讨论】:

partials 和非样式化的 html 怎么样(即

以上是关于如何用python检测字符串是不是包含html代码?的主要内容,如果未能解决你的问题,请参考以下文章

教你如何用Python检测出图像中的黄色?都在这里!

Python - 如何用非字母字符分割字符串

求助:请问在android中如何用代码检测是不是ping通指定的IP地址?

Python学习教程:如何用python统计代码行数

如何用PYTHON代码写出音乐

如何用Python进行数据分析?