Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.08.2024, 19:47   #1
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию Спарсить данные

здравствуйте, код:
Код:
import bs4
import re
patch = r'I:\Российская Федерация\5. ГОСТ Р 52289-2019_01.04.2020.htm'
with open(patch, 'r', encoding='utf-8') as f_in:
    html_code = f_in.read()
soup = bs4.BeautifulSoup(html_code, 'html.parser')
tables = soup.find_all('table')
tables = soup.find_all('table')
print(f"Количество таблиц: {len(tables)}")
for n, table in enumerate(tables):
    rows = table.find_all('tr')
    num_rows = len(rows)
    if num_rows != 1:
        first_row = rows[0]
        cells = first_row.find_all('td')  # Ищем только ячейки td
        # Проверяем, что во всех ячейках первой строки есть ссылки на изображения
        all_jpg_links = all(cell.find('img', src=re.compile(r'base_1_\d+_\d+\.jpg$')) for cell in cells)
        if all_jpg_links:
            print(f"Таблица {n+1} подходит")
            # Здесь можно добавить код для обработки найденной таблицы
            for cell in cells:
                img_src = cell.find('img')['src']
                # Извлекаем нужную часть имени файла
                filename = img_src.split(r'/')[-1]
                print(filename)
часть ответа:
Таблица 35 подходит
base_1_348566_2147483716.jpg
base_1_348566_2147483717.jpg
base_1_348566_2147483718.jpg
base_1_348566_2147483719.jpg
всё верно в ответе, только нужно, чтобы каждая строка была примерно такой:
base_1_348566_2147483716.jpg;1.1;Же лезнодорожный переезд со шлагбаумом

хтмл код, с которого парсится:
Код:
<td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="bottom" align="left"><div class="s0 aC bG"><img src="ГОСТ Р 52289-2019. Национальный стандарт Российской Федераци.htm_/base_1_348566_2147483716.jpg" class="aC" width="135" style="vertical-align:middle;" alt="" /></div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="bottom" align="left"><div class="s0 aC bG"><img src="ГОСТ Р 52289-2019. Национальный стандарт Российской Федераци.htm_/base_1_348566_2147483717.jpg" class="aC" width="137" style="vertical-align:middle;" alt="" /></div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="bottom" align="left"><div class="s0 aC bG"><img src="ГОСТ Р 52289-2019. Национальный стандарт Российской Федераци.htm_/base_1_348566_2147483718.jpg" class="aC" width="136" style="vertical-align:middle;" alt="" /></div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="bottom" align="left"><div class="s0 aC bG"><img src="ГОСТ Р 52289-2019. Национальный стандарт Российской Федераци.htm_/base_1_348566_2147483719.jpg" class="aC" width="136" style="vertical-align:middle;" alt="" /></div></td></tr><tr style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;">
<td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG"><a id="Par2697" ></a>1.1</div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG"><a id="Par2698" ></a>1.2</div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG"><a id="Par2699" ></a>1.3.1</div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG"><a id="Par2700" ></a>1.3.2</div></td></tr><tr style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;">
<td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG">Железнодорожный переезд со шлагбаумом</div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG">Железнодорожный переезд без шлагбаума</div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG">Однопутная железная дорога</div></td><td style="padding-left: 3pt;padding-right: 3pt;padding-top: 5pt;padding-bottom: 5pt;min-height: 12pt; border-left: none; border-right: none; border-top: none; border-bottom: none; " valign="top" align="left"><div class="s0 aC bG">Многопутная железная дорога</div></td></tr></table>
и скрин данных прилагаю, спасибо
Изображения
Тип файла: jpg Ряд знаков.jpg (76.9 Кб, 0 просмотров)
Ципихович Эндрю вне форума Ответить с цитированием
Старый 10.08.2024, 11:11   #2
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию

Код:
import bs4
import re
patch = r'I:\Российская Федерация\5. ГОСТ Р 52289-2019_01.04.2020.htm'
with open(patch, 'r', encoding='utf-8') as f_in:
    html_code = f_in.read()
soup = bs4.BeautifulSoup(html_code, 'html.parser')
tables = soup.find_all('table')
tables = soup.find_all('table')
print(f"Количество таблиц: {len(tables)}")
for n, table in enumerate(tables):
    rows = table.find_all('tr')
    num_rows = len(rows)
    if num_rows != 1:
        first_row = rows[0]
        cells = first_row.find_all('td')  # Ищем только ячейки td
        # Проверяем, что во всех ячейках первой строки есть ссылки на изображения
        all_jpg_links = all(cell.find('img', src=re.compile(r'base_1_\d+_\d+\.jpg$')) for cell in cells)
        if all_jpg_links:
            print(f"Таблица {n+1} подходит")
            for row in table.find_all('tr'):
                for cell in row.find_all('td'):
                    text = cell.text.strip()
                    img = cell.find('img')
                    if text:
                        print(text)
                    elif img:
                        print(img['src'].split(r'/')[-1])
                    else:
                        # Обработка пустой ячейки (по желанию)
                        print("Пустая ячейка")
часть ответа
Таблица 35 подходит
base_1_348566_2147483716.jpg
base_1_348566_2147483717.jpg
base_1_348566_2147483718.jpg
base_1_348566_2147483719.jpg
1.1
1.2
1.3.1
1.3.2
Железнодорожный переезд со шлагбаумом
Железнодорожный переезд без шлагбаума
Однопутная железная дорога
Многопутная железная дорога
ответ верный, как эти же данные расставить:
1.1=Железнодорожный переезд со шлагбаумом=base_1_348566_2147483716 .jpg
1.2=Железнодорожный переезд без шлагбаума=base_1_348566_2147483717. jpg
1.3.1=Однопутная железная дорога=base_1_348566_2147483718.jpg
1.3.2=Многопутная железная дорога=base_1_348566_2147483719.jpg
?? спасибо
Ципихович Эндрю вне форума Ответить с цитированием
Старый 10.08.2024, 17:46   #3
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Код:
import bs4
import re
import itertools

patch = r'gost.htm'
with open(patch, 'r', encoding = 'utf-8') as f_in:
    html_code = f_in.read()

soup = bs4.BeautifulSoup(html_code, 'html.parser')
tables = soup.find_all('table')
print(f"Количество таблиц: {len(tables)}")

for n, table in enumerate(tables, 1):
    rows = table.find_all('tr')
    if len(rows) != 3:
        continue

    # Проверяем, что во всех ячейках первой строки есть ссылки на изображения
    all_jpg_links = all(cell.find('img', src = re.compile(r'base_1_\d+_\d+\.jpg$')) for cell in rows[0].find_all('td'))
    if not all_jpg_links:
        continue

    print(f"Таблица {n} подходит")

    links = list(cell.find('img', src = re.compile(r'base_1_\d+_\d+\.jpg$'))['src'].split(r'/')[-1] for cell in rows[0].find_all('td'))
    nums = list(cell.text.strip() for cell in rows[1].find_all('td'))
    names = list(cell.text.strip() for cell in rows[2].find_all('td'))

    result = list('='.join((num, name, link)) for num, name, link in zip(nums, itertools.cycle(names), links))
    print('\n'.join(result))
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 10.08.2024 в 17:48.
BDA вне форума Ответить с цитированием
Старый 10.08.2024, 19:01   #4
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию

BDA, спасибо большое!!!
код закончил работу на данных:
8.22.3=Препятствие=base_1_348566_21 47484024.jpg
а там ещё есть
8.24=Работает эвакуатор
8.25=Экологический класс транспортного средства
8.26=Зарядка электромобилей
и ещё много пропущено
между
7.21=Автозаправочная станция с возможностью зарядки электромобилей=base_1_348566_214748 3954.jpg
и
8.22.1=Препятствие=base_1_348566_21 47484022.jpg
подправьте пожалуйста ваш код
понятно, что эти ошибки возможны из-за того, что вы изменили в моём коде условие: if num_rows != 1 на != 3
поэтому лучше приложить хтмл файл, что я и делаю
упс форма не даёт загрузить, её ответ 5. ГОСТ Р 52289-2019_01.04.2020.htm:
поэтому изменю его на txt
упс форма ответила
5. ГОСТ Р 52289-2019_01.04.2020.htm.txt:
Ваш файл занимает 1.35 Мб байт, что превышает предел на форуме в 117.2 Кб для этого типа файла.
поэтому обрежу - как получится ХЗ, если что не так - перезалью, спасибо
Вложения
Тип файла: txt 5. ГОСТ Р 52289-2019_01.04.2020.htm.txt (77.8 Кб, 1 просмотров)

Последний раз редактировалось Ципихович Эндрю; 10.08.2024 в 19:05.
Ципихович Эндрю вне форума Ответить с цитированием
Старый 10.08.2024, 19:20   #5
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию

сейчас только увидел что там кроме jpg есть ещё и изображения png - видимо тут собака и зарыта....
Ципихович Эндрю вне форума Ответить с цитированием
Старый 10.08.2024, 21:09   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
кроме jpg есть ещё и изображения png
Это тоже влияет. Но в таблицах есть еще нюансы с colspan и rowspan. colspan вроде учел, а таблицы, в которых есть rowspan, будут пропущены:
Код:
import bs4
import re
from collections import OrderedDict

patch = r'5. ГОСТ Р 52289-2019_01.04.2020.htm'
with open(patch, 'r', encoding = 'utf-8') as f_in:
    html_code = f_in.read()

soup = bs4.BeautifulSoup(html_code, 'html.parser')
tables = soup.find_all('table')
print(f"Количество таблиц: {len(tables)}")

for table_num, table in enumerate(tables, 1):
    rows = table.find_all('tr')
    num_rows = len(rows)
    if num_rows % 2 != 1 or num_rows < 3:
        print(f"Таблица {table_num} не подходит: {num_rows} строк")
        continue

    if any('rowspan' in cell.attrs for cell in table.find_all('td')):
        print(f"Таблица {table_num} не подходит: есть rowspan")
        continue

    links = []
    for row in rows[:-1:2]:
        for cell in row.find_all('td'):
            img = cell.find('img', src = re.compile(r'base_1_\d+_\d+\.(jpg|png)$'))
            n = int(cell['colspan']) if 'colspan' in cell.attrs else 1
            if img:
                links.extend([img['src'].split(r'/')[-1]] * n)

    nums = []
    for row in rows[1:-1:2]:
        for cell in row.find_all('td'):
            text = cell.text.strip()
            n = int(cell['colspan']) if 'colspan' in cell.attrs else 1
            if text:
                nums.extend([cell.text.strip()] * n)

    if len(links) != len(nums):
        print(f"Таблица {table_num} плохо распознана")
        continue

    names = []
    cells = rows[-1].find_all('td')
    for cell in cells:
        n = len(links) if len(cells) == 1 else int(cell['colspan']) if 'colspan' in cell.attrs else 1
        names.extend([cell.text.strip()] * n)

    print(f"Таблица {table_num} подходит")
    result = list(OrderedDict.fromkeys('='.join((num, name, link)) for num, name, link in zip(nums, names, links)))
    print('\n'.join(result))
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 11.08.2024, 07:29   #7
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию

BDA спасибо, помощь пришла откуда не ждали: http://www.artpatch.ru/dorznaki.html
там как минимум не хватает знаков:
8.24 Работает эвакуатор
8.25 Экологический класс транспортного средства
8.26 Зарядка электромобилей
но там же сказано: Сайт в процессе наполнения
сейчас начну более детально смотреть что имеется благодаря вашему коду
Ципихович Эндрю вне форума Ответить с цитированием
Старый 11.08.2024, 12:25   #8
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию

BDA, спасибо за код, неспеша осмотрел, 16 файлов не попали во внимание
base_1_348566_2147483829.jpg
base_1_348566_2147483830.jpg
base_1_348566_2147483842.jpg
base_1_348566_2147483843.jpg
base_1_348566_2147483844.jpg
base_1_348566_2147483845.jpg
base_1_348566_2147483875.jpg
base_1_348566_2147483876.jpg
base_1_348566_2147483877.jpg
base_1_348566_2147483878.jpg
base_1_348566_2147483959.png
base_1_348566_2147483960.png
base_1_348566_2147483961.png
base_1_348566_2147483962.png
base_1_348566_2147483963.png
base_1_348566_2147483964.png
буду признателен, если поможете
ну и ссылка на полный файл файл ГОСТ Р 52289-2019_01.04.2020.htm: https://cloud.mail.ru/public/UwtL/Cfz8P4Sd8
Ципихович Эндрю вне форума Ответить с цитированием
Старый 11.08.2024, 21:00   #9
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Предыдущий код ожидает таблицы со структурой: нечетные строки - картинки со знаками, четные строки - номера знаков, последняя строка - описания знаков. Причем номера знаков на следующей строке относительно картинок. 3829.jpg и 3830.jpg (4.5.4 и 4.5.6) находятся в отдельной таблице, где есть только картинки и номера, а описания нет (оно в следующей таблице). Все остальные перечисленные картинки находятся в таблицах с rowspan, из-за которого номера знаков находятся не в следующей строке, а где-то в других строках. Чуть исправил (но 4.5.4 и 4.5.6 все равно идут без описания):
Код:
import bs4
import re

patch = r'ГОСТ Р 52289-2019_01.04.2020.htm'
with open(patch, 'r', encoding = 'utf-8') as f_in:
    html_code = f_in.read()

soup = bs4.BeautifulSoup(html_code, 'html.parser')
tables = soup.find_all('table')
print(f"Количество таблиц: {len(tables)}")

for table_num, table in enumerate(tables, 1):
    texts = {}
    imgs = []
    for row_idx, row in enumerate(table.find_all('tr')):
        cell_idx = 0
        for cell in row.find_all('td'):
            cell_rows = int(cell['rowspan']) if 'rowspan' in cell.attrs else 1
            cell_cols = int(cell['colspan']) if 'colspan' in cell.attrs else 1
            img = cell.find('img', src = re.compile(r'base_1_\d+_\d+\.(jpg|png)$'))

            while (row_idx, cell_idx) in texts:
                cell_idx += 1

            if img:
                imgs.append((img['src'].split(r'/')[-1], row_idx + cell_rows, cell_idx))
                txt = ''
            else:
                txt = cell.text.strip()

            for i in range(row_idx, row_idx + cell_rows):
                for j in range(cell_idx, cell_idx + cell_cols):
                    texts[(i, j)] = txt

            cell_idx += cell_cols

    if len(imgs) == 0:
        print(f"Таблица {table_num} не подходит: нет картинок")
        continue

    max_i = max(i for i, _ in texts)
    num_pattern = re.compile("^\d+(\.\d+)+( <\*>)?$")
    if any(i > max_i for _, i, _ in imgs) or any(not num_pattern.match(texts[(i, j)]) for _, i, j in imgs):
        print(f"Таблица {table_num} не подходит: нумерация не найдена")
        print("Картинки пропущены:\n" + '\n'.join(img for img, _, _ in imgs))
        continue

    print(f"Таблица {table_num} подходит")
    for img, i, j in imgs:
        if i != max_i:
            print(texts[(i, j)] + '=' + texts[(max_i, j)] + '=' + img)
        else:
            # исключение, описание "убежало" в следующую таблицу
            print(texts[(i, j)] + '=НЕТ ОПИСАНИЯ=' + img)
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 12.08.2024, 10:01   #10
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,167
По умолчанию

BDA спасибо, неспеша проверю ваш код, ещё можно результат работы проверить с другого документа, мой код:
Код:
    patchPDD = r'I:\Российская Федерация\4. ПДД РФ_02.06.2023.htm'
    with open(patchPDD, 'r', encoding='utf-8') as f_in:
        html_PDD = f_in.read()
    soup = BeautifulSoup(html_PDD, 'html.parser')
    # Регулярное выражение для поиска нужных фрагментов
    pattern = r"([1-9].\d+)\s"
    matches = re.findall(pattern, html_PDD)
    for m, match in  enumerate(matches):
        print(f"{m+1}. {match.strip()}") # strip() удаляет пробельные символы в начале и конце строки
подскажите пожалуйста pattern, чтобы искало:
1.13 "Крутой спуск"
1.14 "Крутой подъем"
1.11.1, 1.11.2 "Опасный поворот"
1.4.1 - 1.4.6 "Приближение к железнодорожному переезду"
1.12.1, 1.12.2 - "Опасные повороты" - уже не подходит из-за тире
Ципихович Эндрю вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как спарсить данные с онлайн словаря в excel? Xillin Microsoft Office Excel 4 22.08.2017 04:42
Как спарсить NIKOLAYY2 Общие вопросы Delphi 13 29.03.2015 16:06
Спарсить данные из тега XML FleXik Общие вопросы Delphi 8 19.10.2014 02:39
Спарсить данные с кукисов snip4ik Работа с сетью в Delphi 3 05.03.2013 21:34
Спарсить строку (скопировать до и после пробела данные) sxcine Помощь студентам 3 10.11.2010 19:22