Удалить элемент HTML, если он содержит определенное количество цифровых символов - PullRequest
0 голосов
/ 04 ноября 2018

Для преобразования файла в формате html в простой текстовый файл с помощью Python мне нужно удалить все таблицы, если текст в таблице содержит более 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)

Если у вас есть представление о том, что может быть не так с этим кодом, я был бы очень рад, если бы вы поделились им со мной. Спасибо!

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Спасибо за ваши ответы до сих пор!

После интенсивных исследований я нашел решение загадочного удаления всего совпадения. Казалось, что функция считала только первые 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)
0 голосов
/ 05 ноября 2018

Как я и предлагал вам в комментариях, я бы не использовал регулярные выражения для анализа и использования 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

UPDATE: В любом случае, только эта строка вашего кода удаляет все HTML-теги, как вы узнаете, потому что вы используете его для подсчета символов / цифр

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

Но это небезопасно, поскольку внутри текста ваших тегов также может быть <>, или HTML-код может быть разбит или потерян

Я оставил его там, где он есть, потому что для примера это работает. Но подумайте об использовании BeautifulSoup для всего управления HTML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...