Добавление текста в группу в html-документе на основе условия

#python #beautifulsoup

#python #beautifulsoup

Вопрос:

Я разбираю большой html документ. Я использовал groups для «группировки» текста и разделения с помощью nn . Весь текст находится в <font> </font> тегах документа.

Каждая группа имеет 5 полей, Serial#.........,Cust#...........,Customer Name...,BILL TO NO NAME.,DATE......

Мне нужно использовать Cust#........... из каждой «группы» и сравнить ее с любой другой группой в списке, чтобы найти дубликат Cust#........... .

Если найден дубликат, то мне нужно добавить BILL TO NO NAME. в каждую группу дубликат Cust#...........

Пример html:

Serial#......... 12345678974566321nCust#........... 123456nCustomer Name... Humpfrey BearnBILL TO NO NAME. Bill To: 001166 - Some CompanynDATE...... 01/01/00nn'Serial#......... sgfdsfd546545645nCust#........... 123456nCustomer Name... Humpfrey BearnBILL TO NO NAME. Bill To: 0165487 - Some Other CompanynDATE...... 01/01/00nn'Serial#......... Jgfdhdgfhgfdh4545nCust#........... 88483nCustomer Name... John SmithnBILL TO NO NAME. Bill To: 0146897 - Some CompanynDATE...... 01/01/00nn'Serial#......... JF2SJads5dsafdsafnCust#........... 015648nCustomer Name... Eric CantonanBILL TO NO NAME. Bill To: 8888154 - Man UtdnDATE...... 01/01/00nn'Serial#......... JdsfrfdsgHG091797nCust#........... 015648nCustomer Name... Eric CantonanBILL TO NO NAME. Bill To: 9876524 - Big Big CompanynDATE...... 01/01/00nn'

Вывод, который мне нужен, это: Serial#......... 12345678974566321nCust#........... 123456nCustomer Name... Humpfrey BearnBILL TO NO NAME. Bill To: 001166 - Some Company Bill To: 0165487 - Some Other CompanynDATE...... 01/01/00nn',Serial#......... JF2SJads5dsafdsafnCust#........... 015648nCustomer Name... Eric CantonanBILL TO NO NAME. Bill To: 8888154 - Man Utd Bill To: 9876524 - Big Big CompanynDATE...... 01/01/00nn'

В моем выводе были опущены дубликаты, основанные на Cust # ……xxxxx, но я просто пытаюсь немного яснее показать ожидаемый результат. Я могу отсортировать дубликаты позже.

Сокращенная версия того, что у меня есть на данный момент, остальное несущественно.

 from bs4 import BeautifulSoup
import re
import urllib
import os



with open(r'.html', 'r') as f:
   html_string = f.read()

soup = BeautifulSoup(html_string, 'html.parser')

groups = soup.font.text.replace('Serial#', 'xxxSerial#').split('xxx')
  

Комментарии:

1. Можете ли вы немного подробнее объяснить, какова связь с вашим примером ввода и желаемым результатом? BILL TO NO NAME Тег присутствует в каждой записи в вашем примере ввода. Указанный вами желаемый результат, по-видимому, является просто единственным экземпляром двух дублированных записей, но, похоже, никаких дополнительных BILL TO NO NAME тегов добавлено не было, и вы также ничего не сказали об исключении не дубликатов в вашем результате. Было бы полезно некоторое дополнительное разъяснение.

2. Во входных данных также нет HTML, который я вижу — он выглядит как обычный текст. Я имею в виду, обычный текст является частью допустимого HTML, но я не уверен, зачем вам нужно использовать BeautifulSoup здесь, кажется, что любой метод обработки строк был бы приемлем. Это верно?

3. У меня есть некоторый код, который позже опустит дубликаты, не нужно беспокоиться об этом. Правильно, мне не нужен красивый суп, я просто начал с этого и продолжал.. Открыт для любых идей

4. Хорошо, спасибо. В чем я все еще не уверен, так это в следующем: вы написали «Если найден дубликат, мне нужно добавить СЧЕТ БЕЗ ИМЕНИ». Но каждая запись в вашем примере ввода уже содержит «СЧЕТ БЕЗ ИМЕНИ». И ваш вывод не отображается в каких-либо дополнительных тегах «СЧЕТ БЕЗ ИМЕНИ». Итак, если исключение дубликатов не является целью, и в тексте уже есть «СЧЕТ БЕЗ НАЗВАНИЯ», что вы пытаетесь сделать — просто определить, какие записи имеют повторяющиеся Cust# значения?

Ответ №1:

Это не совсем похоже на ожидаемый результат в вашем вопросе, но это может подвести вас достаточно близко:

 bills = """[your html above]"""
groups = bills.replace('Serial#','xxxSerial#').split('xxx')
cust_nums = []
ng= []
for group in groups[1:]:
    items = group.split('n')
    cn = items[1].split('. ')[1]
    bill = items[3].split('. ')[1]
    if cn not in cust_nums:
        cust_nums.append(items[1].split('. ')[1])            
    else:
        items[3] =' ' bill
        ng.append(items[:-2])
ng
  

Вывод:

 [['Serial#......... sgfdsfd546545645',
  'Cust#........... 123456',
  'Customer Name... Humpfrey Bear',
  'BILL TO NO NAME. Bill To: 0165487 - Some Other Company Bill To: 0165487 - Some Other Company',
  'DATE...... 01/01/00'],
 ['Serial#......... JdsfrfdsgHG091797',
  'Cust#........... 015648',
  'Customer Name... Eric Cantona',
  'BILL TO NO NAME. Bill To: 9876524 - Big Big Company Bill To: 9876524 - Big Big Company',
  'DATE...... 01/01/00']]
  

Ответ №2:

Если ваша цель — идентифицировать повторяющиеся Cust# значения, вот один из подходов:

 import re

sep = "Serial#"

def get_cust_number(entry):
    """ Isolate the customer ID number. """
    pattern = re.compile("Cust#[^0-9] (d )")
    return pattern.findall(entry)[0]

# return a list of dicts, each element has full entry and customer id
parsed = [{"full_entry": sep   x, "cust_id": get_cust_number(x)} 
          for x in data.split(sep) if x]

# example parsed element
{'full_entry': "Serial#......... 12345678974566321nCust#........... 123456nCustomer Name... Humpfrey BearnBILL TO NO NAME. Bill To: 001166 - Some CompanynDATE...... 01/01/00nn'",
  'cust_id': '123456'}
  

Теперь используйте a set для поиска дубликатов Cust# и сохранения дублирующихся записей в dupes :

 seen = set()
dupes = list()

# iterate over each entry, store :cust_id: values in :seen: set.
# if :cust_id: is already in :seen:, it is a dupe.  store it in :dupes:.
for entry in parsed:
    if entry['cust_id'] in seen:
        dupes.append(entry['full_entry'])
    else:
        seen.add(entry['cust_id'])
        
dupes
["Serial#......... sgfdsfd546545645nCust#........... 123456nCustomer Name... Humpfrey BearnBILL TO NO NAME. Bill To: 0165487 - Some Other CompanynDATE...... 01/01/00nn'",
 "Serial#......... JdsfrfdsgHG091797nCust#........... 015648nCustomer Name... Eric CantonanBILL TO NO NAME. Bill To: 9876524 - Big Big CompanynDATE...... 01/01/00nn'"]
  

Я не понимаю, почему в вашем выводе есть вторая запись «Humpfrey Bear», но первая запись «Eric Cantona». Этот ответ генерирует список только повторяющихся выходных данных (что означает, что первой записи там нет).