beautifulsoup4: как разобрать сообщение на форуме? - PullRequest
0 голосов
/ 15 мая 2019

У меня несколько раз встречается следующая (упрощенная) структура данных, найденная в программном обеспечении форума:

<li id="post12345" class="anchorFixedHeader" style="order: 1">
  <div class="messagesidebar member" item-prop="author">
    <div class="messageauthor">
      <div class="messageauthorcontainer">
        <a id="mac12">
          <span class="username" itemprop="text">MostInnovativeUsernameEver</span>
        </a>
      </div>
    </div>
  </div>
  <div class="messagecontent">
    <div class="messagebody">
      <div class="messagetext" itemprop="text">
        Text before the quote.
        <blockquote class="quotebox">
          <div class="quoteboxcontent">
            <p>
              Hello, I'm a quote.
            </p>
          </div>
        </blockquote>
        Text after the class.
      </div>
    </div>
  </div>
</li>

Что я хочу сделать для каждого случая, так это извлечь имя пользователя и для каждого имени пользователя соответствующее содержание сообщения. Я мог бы сделать это успешно, если бы не было единственной проблемы: цитата. Когда я распечатываю извлеченные данные в консоли, структура данных цитаты (естественно) портится.

Мне (кажется) нужен текст перед цитатой, сама цитата и текст после цитаты, чтобы разобраться с ними отдельно. Я перепробовал кучу вещей, но пока еще не нашел свой путь в красивой паре.

Тьфу ... ребята, вы понимаете, что я пытаюсь сделать?

1 Ответ

0 голосов
/ 16 мая 2019

Ну, если я понял ваш вопрос, вот способ решить:

import re

import bs4

html = """<li id="post12345" class="anchorFixedHeader" style="order: 1">
  <div class="messagesidebar member" item-prop="author">
    <div class="messageauthor">
      <div class="messageauthorcontainer">
        <a id="mac12">
          <span class="username" itemprop="text">MostInnovativeUsernameEver</span>
        </a>
      </div>
    </div>
  </div>
  <div class="messagecontent">
    <div class="messagebody">
      <div class="messagetext" itemprop="text">
        Text before the quote.
        <blockquote class="quotebox">
          <div class="quoteboxcontent">
            <p>
              Hello, I'm a quote.
            </p>
          </div>
        </blockquote>
        Text after the class.
      </div>
    </div>
  </div>
</li>"""

forum_posts = []
re_break_line = re.compile(r'[^\n].*')

soup = bs4.BeautifulSoup(html, features='html.parser')
posts = soup.find_all('li')
for post in posts:
    username = post.find('span', {'class': 'username'})
    content = post.find('div', {'class': 'messagecontent'})

    forum_post = {
        'username': username.text,
        'content': re_break_line.findall(content.text.replace('  ', ''))
    }
    forum_posts.append(forum_post)

print(forum_posts)

Выходная консоль:

[{'content': ['Text before the quote.', "Hello, I'm a quote.", 'Text after the class.'], 'username': 'MostInnovativeUsernameEver'}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...