@Kakagawa

Почему не парсятся ссылки на python?

Есть файл parsed-data2.txt. В нем лежат статьи на многих разных языках, но структура одна:
Title: Текст
Text: Текст
Images: перечень ссылок на изображения

Есть вот такой код:

from langdetect import detect
import re
import os

def get_language(text):
    try:
        lang = detect(text)
        return lang
    except:
        return None

def process_article(title, text, images):
    lang = get_language(text)
    
    if lang:
        lang_file_path = f'db/{lang}.txt'
        mode = 'a' if os.path.exists(lang_file_path) else 'w'
        
        with open(lang_file_path, mode, encoding='utf-8') as file:
            file.write(f'Title: {title}\n')
            file.write(f'Text: {text}\n')
            file.write('Images:\n')
            for img in images:
                file.write(f'{img}\n')
            file.write('\n')
    else:
        print(f"Could not detect language for article:\nTitle: {title}\nText: {text}\nImages: {', '.join(images)}\n")

def main():
    with open('parsed-data2.txt', 'r', encoding='utf-8') as file:
        data = file.read()
    
    articles = re.split(r'Title: ', data)[1:]
    
    for article in articles:
        lines = article.strip().split('\n')
        title = lines[0]
        text = lines[1][6:]
        images = [img.strip() for img in lines[2][8:].split(',')]
        
        process_article(title, text, images)

if __name__ == "__main__":
    main()


Но я не могу понять почему он не хватает ссылки. То есть после Images: пусто. Помогите, пожалуйста, с решением.
  • Вопрос задан
  • 114 просмотров
Решения вопроса 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
Смотрите внимательно как устроен ваш парсер. Вам уже намекнули в соседнем ответе.
Вы парсите статью так, будто бы её текст весь в одной строке (во второй по счету). А ссылки вы ищете в третьей строке, но из-за того, что статья многострочная там их нет.

Разбивайте задачу на маленькие подзадачи и делайте их отдельно, на каждом шагу убеждаясь, что всё как надо. Для этого можно делать отладочный выхлоп в промежуточных состояниях.

ВОт вы почему-то свято уверены, что lines[2][8:] - это перечень ссылок через запятую. Может быть даже в одном из примеров в какой-то момент когда-то так оно и было, но с тех пор вы уже поменяли, скорее всего, код или входной формат, но не учли это.
Делайте больше отладочного вывода. Лучше не принтами, а с использованием модуля logging, тогда отладочный выхлоп можно включать и отключать при необходимости не трогая код.
Каждый раз, когда вы меняете код, не важно для исправления старых ошибок, или для добавления новой функциональности, вы неизбежно вносите новые ошибки.
Чтобы это контролировать пишут юнит-тесты. Но вам, похоже, еще рановато.
Ещё, особенно в небольших скриптах, полезно убеждаться, что всё идёт как надо в промежуточных этапах. Для этого в питоне есть ключевое слово assert.
Оно позволяет указать обязательное условие, которое должно соблюдаться в этом месте выполнения программы, и текст ошибки, с которой упадёт программа в этом месте, если условие не соблюдается.
Конкретно здесь, можно было бы убедиться с помощью assert, что в третьей строке вы отрезали 8 символов и эти символы соответствуют префиксу "Images: ".
Падение программы на этом месте даст вам понять, что вы где-то ошиблись и что-то пошло не так, как вы ожидали. Эти ассерты также помогут вам сразу обнаруживать изменение входного формата данных, за который, возможно, отвечает не ваш код.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Ну значит тут что-то накосячил:
images = [img.strip() for img in lines[2][8:].split(',')]

Не видя перед собой примера данных, трудно сказать что именно.

EDIT: Проблема в строке lines = article.strip().split('\n')
Ты почему-то думаешь, что у тебя весь текст статьи будет на одной строке. Это далеко не так.
Единственный маркер, который у тебя есть - Images: в начале одной из строк. И да, если такое встретится в тексте статьи - парсер сломается.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы