@Eger_U

Почему парсер PDF документов не работает с несколькими тегами?

Мне по работе необходимо довольно часто проверять все ли слова (которые содержат тег) есть в 2 документах. Для этого я написал небольшой парсер. Суть парсера в том что-бы находил слова имеющие теги сравнивал есть ли данные слова в двух документах и уникальные слова для обоих документов мне выдавал списком.

Парсер прекрасно работает если я использую один тег, а если пытаюсь несколько то парсер ничего не выдает.

Вот результаты с использованием 1 тега (тег=UPS):
Уникальные слова в первом PDF файле:
SNR-UPS-ONRT-100 (страница 5)
SNR-UPS-ONRT-100 (страница 6)
SNR-UPS-ONRT-100 (страница 7)
SNR-UPS-ONRT-100 (страница 8)
SNR-UPS-ONRT-100 (страница 9)
SNR-UPS-ONRT-200 (страница 4)
SNR-UPS-RK-CS (страница 5)
SNR-UPS-RK-CS (страница 6)
SNR-UPS-RK-CS (страница 7)
SNR-UPS-RK-CS (страница 9)

Уникальные слова во втором PDF файле:
1.UPS1.10 (страница 16)
1.UPS1.2 (страница 16)
2.UPS1.2 (страница 16)
3.UPS1.2 (страница 16)
4.UPS1.2 (страница 16)
5.UPS1.2 (страница 16)
SNR-UPS-ONRT-1000-S24 (страница 11)
SNR-UPS-ONRT-1000-S24 (страница 12)
SNR-UPS-ONRT-1000-S24 (страница 13)
SNR-UPS-ONRT-1000-S24 (страница 14)
SNR-UPS-ONRT-1000-S24 (страница 15)
SNR-UPS-ONRT-1000-S24 (страница 16)
SNR-UPS-ONRT-1000-S24 (страница 16)
SNR-UPS-ONRT-1000-S24 (страница 16)
SNR-UPS-ONRT-1000-S24 (страница 16)
SNR-UPS-ONRT-1000-S24 (страница 16)
SNR-UPS-ONRT-1000-S24 (страница 18)
SNR-UPS-ONRT-1000-S24 (страница 19)
SNR-UPS-ONRT-1000-S24 (страница 20)
SNR-UPS-ONRT-1000-S24 (страница 21)
SNR-UPS-ONRT-1000-S24 (страница 22)
SNR-UPS-ONRT-2000-E48 (страница 10)
SNR-UPS-ONRT-2000-E48 (страница 16)
SNR-UPS-ONRT-2000-E48 (страница 17)
UPS (страница 1)
Тут все работает корректно

Вот результаты с использованием 2-х тегов (теги=UPS, SW):
Уникальные слова в первом PDF файле:

Уникальные слова во втором PDF файле:

Вот код программы

import pdfplumber
import re


def extract_unique_words_with_tag(pdf_path, tags, remove_duplicates=False):
    """
    Извлечение слов с тегом из PDF с указанием номера страницы.

    Args:
        pdf_path (str): Путь к PDF файлу.
        tag (str): Тег, по которому фильтруются слова (например, 'BGB').
        remove_duplicates (bool): Если True, удаляет дубли на всех страницах.

    Returns:
        list: Список кортежей (слово, номер страницы).
    """
    try:
        with pdfplumber.open(pdf_path) as pdf:
            all_words_with_pages = []

            for i, page in enumerate(pdf.pages):
                text = page.extract_text()
                if text:
                    lines = text.split("\n")
                    page_words = []

                    for line in lines:
                        words = line.split()
                        tagged_words = [
                            re.sub(r'[^a-zA-Z0-9\.\-]', '', word)
                            for word in words
                            if re.search(rf'\b\w*{tags}\w*\b', word)
                        ]
                        page_words.extend([(word, i + 1) for word in tagged_words])

                    if remove_duplicates:
                        page_words = list(set(page_words))

                    all_words_with_pages.extend(page_words)

            if remove_duplicates:
                all_words_with_pages = list(set(all_words_with_pages))

            unique_words_with_pages = sorted(all_words_with_pages, key=lambda x: (x[0], x[1]))
            return unique_words_with_pages

    except Exception as e:
        print(f"[ERROR] Произошла ошибка: {e}")
        return []


def find_unique_to_each_pdf(pdf_path1, pdf_path2, tags, remove_duplicates_for_pdf1=False, remove_duplicates_for_pdf2=False):
    """
    Находит слова, уникальные для каждого PDF файла, с указанием номера страницы.

    Args:
        pdf_path1 (str): Путь к первому PDF файлу.
        pdf_path2 (str): Путь ко второму PDF файлу.
        tag (str): Тег для поиска.
        remove_duplicates_for_pdf1 (bool): Если True, удаляет дубли в первом PDF.
        remove_duplicates_for_pdf2 (bool): Если True, удаляет дубли во втором PDF.

    Returns:
        tuple: Два списка — слова с номерами страниц, уникальные для первого и второго PDF.
    """
    unique_words_pdf1 = extract_unique_words_with_tag(pdf_path1, tags, remove_duplicates=remove_duplicates_for_pdf1) or []
    unique_words_pdf2 = extract_unique_words_with_tag(pdf_path2, tags, remove_duplicates=remove_duplicates_for_pdf2) or []

    words_only_pdf1 = set(word for word, _ in unique_words_pdf1)
    words_only_pdf2 = set(word for word, _ in unique_words_pdf2)

    unique_to_pdf1 = [(word, page) for word, page in unique_words_pdf1 if word not in words_only_pdf2]
    unique_to_pdf2 = [(word, page) for word, page in unique_words_pdf2 if word not in words_only_pdf1]

    return sorted(unique_to_pdf1), sorted(unique_to_pdf2)
  • Вопрос задан
  • 60 просмотров
Пригласить эксперта
Ответы на вопрос 2
@SunTechnik
У Вас по тексту программы:
tag (str): Тег, по которому фильтрую.

Один тэг.
Во втором запуску происходит поиск не двух слов, а целиком одного тэга: UPS, SW

Дальше, если будете править программу, надо определиться, какие символы могут входить в тэг, а какие будут разделителями.
Ответ написан
Комментировать
Lord_of_Rings
@Lord_of_Rings
Python developer
spoiler
import pdfplumber
import re

def extract_unique_words_with_tag(pdf_path, tags, remove_duplicates=False):
    """
    Извлечение слов с тегом из PDF с указанием номера страницы.

    Args:
        pdf_path (str): Путь к PDF файлу.
        tags (list): Список тегов, по которым фильтруются слова (например, ['UPS', 'SW']).
        remove_duplicates (bool): Если True, удаляет дубли на всех страницах.

    Returns:
        list: Список кортежей (слово, номер страницы).
    """
    try:
        with pdfplumber.open(pdf_path) as pdf:
            all_words_with_pages = []

            for i, page in enumerate(pdf.pages):
                text = page.extract_text()
                if text:
                    lines = text.split("\n")
                    page_words = []

                    for line in lines:
                        words = line.split()
                        tagged_words = [
                            re.sub(r'[^a-zA-Z0-9\.\-]', '', word)
                            for word in words
                            if re.search(rf'\b\w*({"|".join(tags)})\w*\b', word)
                        ]
                        page_words.extend([(word, i + 1) for word in tagged_words])

                    if remove_duplicates:
                        page_words = list(set(page_words))

                    all_words_with_pages.extend(page_words)

            if remove_duplicates:
                all_words_with_pages = list(set(all_words_with_pages))

            unique_words_with_pages = sorted(all_words_with_pages, key=lambda x: (x[0], x[1]))
            return unique_words_with_pages

    except Exception as e:
        print(f"[ERROR] Произошла ошибка: {e}")
        return []

def find_unique_to_each_pdf(pdf_path1, pdf_path2, tags, remove_duplicates_for_pdf1=False, remove_duplicates_for_pdf2=False):
    """
    Находит слова, уникальные для каждого PDF файла, с указанием номера страницы.

    Args:
        pdf_path1 (str): Путь к первому PDF файлу.
        pdf_path2 (str): Путь ко второму PDF файлу.
        tags (list): Список тегов для поиска.
        remove_duplicates_for_pdf1 (bool): Если True, удаляет дубли в первом PDF.
        remove_duplicates_for_pdf2 (bool): Если True, удаляет дубли во втором PDF.

    Returns:
        tuple: Два списка — слова с номерами страниц, уникальные для первого и второго PDF.
    """
    unique_words_pdf1 = extract_unique_words_with_tag(pdf_path1, tags, remove_duplicates=remove_duplicates_for_pdf1) or []
    unique_words_pdf2 = extract_unique_words_with_tag(pdf_path2, tags, remove_duplicates=remove_duplicates_for_pdf2) or []

    words_only_pdf1 = set(word for word, _ in unique_words_pdf1)
    words_only_pdf2 = set(word for word, _ in unique_words_pdf2)

    unique_to_pdf1 = [(word, page) for word, page in unique_words_pdf1 if word not in words_only_pdf2]
    unique_to_pdf2 = [(word, page) for word, page in unique_words_pdf2 if word not in words_only_pdf1]

    return sorted(unique_to_pdf1), sorted(unique_to_pdf2)

# Пример использования
pdf_path1 = 'path/to/first/pdf'
pdf_path2 = 'path/to/second/pdf'
tags = ['UPS', 'SW']

unique_to_pdf1, unique_to_pdf2 = find_unique_to_each_pdf(pdf_path1, pdf_path2, tags)

print("Уникальные слова в первом PDF файле:")
for word, page in unique_to_pdf1:
    print(f"{word} (страница {page})")

print("\nУникальные слова во втором PDF файле:")
for word, page in unique_to_pdf2:
    print(f"{word} (страница {page})")
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы