【问题标题】:Find next items to tag in Beautiful Soup在 Beautiful Soup 中查找下一个要标记的项目
【发布时间】:2018-02-09 11:48:58
【问题描述】:

我想用 Beautiful Soup 和 Python 之类的方式解析 HTML 文件

<h1>Title 1</h1>
<div class="item"><p>content 1</p></div>
<div class="item"><p>content 2</p></div>
...
<h1>Title 2</h1>
<div class="item"><p>content 3</p></div>
<div class="item"><p>content 4</p></div>
<div class="item"><p>content 5</p></div>
...

我怎样才能把它解析成像这样的字典

{
   "Title 1": [
      {
         "content": "content 1"
      },
      {
         "content": "content 2"
      }
   ],
   "Title 2": [
      {
         "content": "content 3"
      },
      {
         "content": "content 4"
      },
      {
         "content": "content 5"
      }
   ]
}

我已经用 nextSibling 试过了,但我无法检查标签名称。

【问题讨论】:

  • 你不能用相同的键将它解析为字典,你必须使用列表或其他东西(我说content键)
  • 我已经编辑了字典

标签: python beautifulsoup


【解决方案1】:

您可以使用next_sibling 执行此操作,并通过.name 检查标签类型:

soup = BeautifulSoup(html_page, 'html.parser')
temp_tag = soup.h1
result = {temp_tag.text: []}
temp_key = temp_tag.text
while True:
    temp_tag = temp_tag.next_sibling
    if temp_tag.name == 'div':
        buf = temp_tag.contents[0].text
        result[temp_key].append({'content': buf})
    elif temp_tag.name == 'h1':
        temp_key = temp_tag.text
        result[temp_key] = []
    else:
        break

print(result)

这段代码的输出:

{
u'Title 1': [
    {'content': u'content 1'},
    {'content': u'content 2'}
    ], 
u'Title 2': [
    {'content': u'content 3'},
    {'content': u'content 4'},
    {'content': u'content 5'}
    ]
}

【讨论】:

    【解决方案2】:

    以下是实现此目的的方法:

    soup = bs4.BeautifulSoup(html)
    data = {}
    row = []
    title = ""
    for tag in soup:
        print(tag)
        if tag.name == 'h1':
            if title:
                data[title] = row
            row = []
            title = tag.string
    
        elif tag.name == 'div':
            row.append(tag.string)
    
    if title:
        data[title] = row
    

    这个想法是迭代标签。 如果当前标签是&lt;h1&gt;,则创建一个新的内容列表。 否则,如果是&lt;div&gt; 标记,则将其内容附加到当前内容列表中。 当找到新的&lt;h1&gt; 标签时,将当前内容列表放入全局数据结构(即字典)中,放在最后一个标题的名称下。

    标签的类型可以在tag.name 中找到。 这是您需要检查的内容,以便确定标签是&lt;h1&gt; 还是&lt;div&gt;

    这给出的结构与你要求的有点不同,但我认为这是一个更好的数据结构,因为你字典中的键总是content,所以基本上不需要键,列表更好.


    测试输入:

    html = """<h1>Title 1</h1>
    <div class="item"><p>content 1</p></div>
    <div class="item"><p>content 2</p></div>
    <h1>Title 2</h1>
    <div class="item"><p>content 3</p></div>
    <div class="item"><p>content 4</p></div>
    <div class="item"><p>content 5</p></div>
    """
    

    输出:

    {'Title 1': ['content 1', 'content 2'], 'Title 2': ['content 3', 'content 4', 'content 5']}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多