Как сделать чистку в BeautifulSoup с помощью рекурсии? - PullRequest
1 голос
/ 06 ноября 2019

Я пытаюсь очистить XML-файл, используя следующий код, который прекрасно работает: -

    f = open("sample_data.xml", "r")
    contents = f.read()
    soup = BeautifulSoup(contents, features="xml")
    for component in soup.find_all("component"):
        for section in component.find_all("section"):
            for entry in section.find_all("entry"):
                for encounter in entry.find_all("encounter"):
                    for participant in encounter.find_all("participant"):
                        for participantRole in participant.find_all("participantRole"):
                            for playingEntity in participantRole.find_all("playingEntity"):
                                for name in playingEntity.find_all("name"):
                                    print(name.text)

Но вместо того, чтобы использовать так много циклов for, я хотел бы поместить его в рекурсию. Для этой цели я создал список, который будет служить нашим путем обхода для поиска нужного элемента, как показано ниже: -

traversal_path = ['component', 'section', 'entry', 'encounter', 'participant', 'participantRole', 'playingEntity', 'name']

И чтобы служить точкой останова для нашей рекурсивной функции, мы можем использовать последний путь обходапункт, который в нашем случае name. По мере того, как мы продолжаем работу над traversal_path, первый элемент из списка удаляется, пока не останется только один последний элемент. В соответствии с этим теперь моя функция стала такой: -

f = open("sample_data.xml", "r")
contents = f.read()
soup = BeautifulSoup(contents, features="xml")
traversal_path = ['component', 'section', 'entry', 'encounter', 'participant', 'participantRole', 'playingEntity', 'name']

def rec(traversal_path, soup):
    print(traversal_path)
    if len(traversal_path) == 1:
        for last_item in soup.find_all(traversal_path[0]):
            print(last_item.text)
    else:
        t = traversal_path.pop(0)
        for first_item in soup.find_all(t):
            return rec(traversal_path, first_item)

rec(traversal_path, soup)

Вывод, который я получаю, - это просто путь прохождения печати, как показано ниже: -

['component', 'section', 'entry', 'encounter', 'participant', 'participantRole', 'playingEntity', 'name']
['section', 'entry', 'encounter', 'participant', 'participantRole', 'playingEntity', 'name']
['entry', 'encounter', 'participant', 'participantRole', 'playingEntity', 'name']
['encounter', 'participant', 'participantRole', 'playingEntity', 'name']

Когда я печатаюsoup вместо traversal_path Я получаю выводной суппорт только до entry.

Также проблема в моей функции, похоже, заключается в другой части, где она не входит в рекурсию. Любая помощь в этом вопросе очень ценится.

1 Ответ

1 голос
/ 06 ноября 2019
 def rec(traversal_path, soup):
    if len(traversal_path) == 1:
        for last_item in soup.find_all(traversal_path[0]):
            print(last_item.text)
    else:
         try:
            for first_item in soup.find_all(traversal_path[0]):
                rec(traversal_path, first_item)
            t = traversal_path.pop(0)
        except Exception as e:
            pass

rec(field['traversal_path'].split(" "), soup)

Просто удалите оператор возврата и обработайте исключения

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