【问题标题】:Delete HTML element if it contains a certain amount of numeric characters如果 HTML 元素包含一定数量的数字字符,则删除它
【发布时间】:2018-11-07 22:56:19
【问题描述】:

对于使用 Python 将 html 格式的文件转换为纯文本文件,如果表格中的文本包含超过 40% 的数字字符,我需要删除所有表格。

具体来说,我想:

  1. 标识 html 文件中的每个表格元素
  2. 计算文本中数字和字母字符的数量以及对应的比例,不考虑任何html标签中的字符。因此,删除所有 html 标签。
  3. 如果表格的文本由超过 40% 的数字字符组成,则删除表格。如果表格包含少于 40% 的数字字符,请保留表格。

我定义了一个在运行 re.sub 命令时调用的函数。 rawtext 变量包含我要解析的整个 html 格式的文本。在函数中,我尝试处理上述步骤,并根据数字字符的比例返回表格的 html 剥离版本或空格。但是,函数中的 first re.sub 命令似乎不仅删除了标签,还删除了所有内容,包括文本内容。

def tablereplace(table):
    table = re.sub('<[^>]*>', ' ', str(table))
    numeric = sum(c.isdigit() for c in table)
    alphabetic = sum(c.isalpha() for c in table)
    try:
            ratio = numeric / (numeric + alphabetic)
            print('ratio = ' + ratio)
    except ZeroDivisionError as err:
            ratio = 1
    if ratio > 0.4:
            emptystring = re.sub('.*?', ' ', table, flags=re.DOTALL)  
            return emptystring
    else:
            return table

rawtext = re.sub('<table.+?<\/table>', tablereplace, rawtext, flags=re.IGNORECASE|re.DOTALL)

如果您知道此代码可能有什么问题,如果您与我分享,我将非常高兴。谢谢!

【问题讨论】:

标签: python regex parsing


【解决方案1】:

正如我在 cmets 中建议的那样,我不会使用正则表达式来解析和使用代码中的 HTML。例如,您可以使用为此目的构建的 python 库,例如 BeautifulSoup

这里是一个如何使用它的例子

#!/usr/bin/python
try:
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup
html = """<html>
<head>Heading</head>
<body attr1='val1'>
    <div class='container'>
        <div id='class'>Something here</div>
        <div>Something else</div>
<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td> 
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td> 
    <td>94</td>
  </tr>
</table>
    </div>
</body>
</html>"""
parsed_html = BeautifulSoup(html, 'html.parser')
print parsed_html.body.find('table').text

所以你最终可能会得到这样的代码(只是给你一个想法)

#!/usr/bin/python
import re
try:
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup



def tablereplace(table):
    table = re.sub('<[^>]*>', ' ', str(table))
    numeric = sum(c.isdigit() for c in table)
    print('numeric: ' + str(numeric))
    alphabetic = sum(c.isalpha() for c in table)
    print('alpha: ' + str(alphabetic))
    try:
            ratio = numeric / float(numeric + alphabetic)
            print('ratio: '+ str(ratio))
    except ZeroDivisionError as err:
            ratio = 1
    if ratio > 0.4:
            return True
    else:
            return False

table = """<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>Age</th>
  </tr>
  <tr>
    <td>3241424134213424214321342424214321412</td>
    <td>213423423234242142134214124214214124124</td> 
    <td>213424214234242</td>
  </tr>
  <tr>
    <td>124234412342142414</td>
    <td>1423424214324214</td> 
    <td>2134242141242341241</td>
  </tr>
</table>
"""

if tablereplace(table):
        print 'replace table'
        parsed_html = BeautifulSoup(table, 'html.parser')
        rawdata = parsed_html.find('table').text
        print rawdata

更新: 无论如何,只要这行代码去掉所有 HTML 标记,您就会知道,因为您将它用于字符/数字计数目的

table = re.sub('<[^>]*>', ' ', str(table))

但这并不安全,因为您也可能在标签文本中包含 ,否则 HTML 可能会被破坏或放错位置

我将它留在原处,因为对于示例它正在工作。但考虑使用 BeautifulSoup 进行所有 HTML 管理。

【讨论】:

    【解决方案2】:

    感谢您到目前为止的回复!

    经过深入研究,我找到了整个匹配神秘删除的解决方案。该函数似乎只考虑了匹配的前 150 个左右字符。但是,如果您指定 table = table.group(0),则会处理整个匹配项。 group(0) 造成了很大的不同。

    您可以在下面找到我更新后的脚本,它可以正常工作(还包括其他一些小改动):

    def tablereplace(table):
        table = table.group(0)
        table = re.sub('<[^>]*>', '\n', table)
        numeric = sum(c.isdigit() for c in table)
        alphabetic = sum(c.isalpha() for c in table)
        try: 
            ratio = numeric / (numeric + alphabetic)
        except ArithmeticError:
            ratio = 1
        else:
            pass
        if ratio > 0.4:
            emptystring = ''  
            return emptystring
        else:
            return table 
    rawtext = re.sub('<table.+?<\/table>', tablereplace, rawtext, flags=re.IGNORECASE|re.DOTALL)
    

    【讨论】:

      猜你喜欢
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      • 2022-11-27
      • 2020-06-23
      相关资源
      最近更新 更多