2015-07-31 3 views
0

Я пытаюсь разобрать локальный файл html с помощью BeautifulSoup, но проблема с навигацией по дереву.Анализ HTML-файла BeautifulSoup

Файл находится в следующем формате:

<div class="contents"> 
    <h1> 
    USERNAME 
    </h1> 
<div> 
    <div class="thread"> 
    N1, N2 
    <div class="message"> 
     <div class="message_header"> 
     <span class="user"> 
      USERNAME 
     </span> 
     <span class="meta"> 
     Thursday, 1 January 2015 at 19:52 UTC 
     </span> 
    </div> 
    </div> 
    <p> 
     They're just friends 
    </p> 
    <div class="message"> 
     <div class="message_header"> 
     <span class="user"> 
      USERNAME 
     </span> 
     <span class="meta"> 
     Thursday, 1 January 2015 at 19:52 UTC 
     </span> 
    </div> 
    </div> 
    <p> 
     MESSAGE 
    </p> 
... 

Я хочу, чтобы извлечь для каждого потока:

для каждого divclass='message':

  • в spanclass='user' и мета-данных
  • сообщение в p напрямую после

Это длинный файл со многими из этих потоков и много сообщений в каждом потоке.

До сих пор я только что открыл файл и превратили его в суп

raw_data = open('file.html', 'r') 
soup = BeautifulSoup(raw_data) 

contents = soup.find('div', {'class' : 'contents'}) 

Я смотрю на хранение этих данных в словаре в формате

dict[USERNAME] = ([(MESSAGE1, time1), [MESSAGE2, time2]) 
+1

Хорошо, как вы пытались преобразовать суп в словарь? – hd1

+0

вставьте большую часть html с близкими divs (правильный DOM) – CodeNinja

ответ

0

Имя пользователя и метаинформацию относительно легко захватывать, поскольку они хорошо содержатся в их собственных тегах span с идентификатором класса. Само сообщение находится в свободном теге абзаца, это более сложный зверь ...

Если вы посмотрите раздел «Going Sideways» HERE, он говорит: «Вы можете использовать .next_sibling и .previous_sibling для навигации между элементами страницы, которые находятся на одном уровне дерева синтаксического анализа ".

с этим в виду, вы можете извлечь детали, которые вы хотите с этим:

from bs4 import BeautifulSoup 

your_html = "your html data" 

souped_data = BeautifulSoup(your_html) 
for message in souped_data.find_all("div", {"class": "message"}): 
    username = message.find('span', attrs={'class': 'user'}).get_text() 
    meta = message.find('span', attrs={'class': 'meta'}).get_text() 
    message = message.next_sibling 

Во-первых, найти все теги сообщений. В каждом из них вы можете искать имена пользователей и метаклассов. Тем не менее, это просто возвращает сам тег, используйте .get_text(), чтобы получить данные тега. Наконец, используйте магический .next_sibling, чтобы получить содержимое вашего сообщения в одиноких старых тегах «p».

Это дает вам данные, которые вам нужны. Что касается структуры словаря. Хммм ... Я бы бросил их всех в список объектов словаря. Тогда JSONify, что badboy! Однако, может быть, это не то, что вам нужно?

Смежные вопросы