【问题标题】:Python Beautiful Soup unwrap() not working as expected - want to extract content of a tagPython Beautiful Soup unwrap() 没有按预期工作 - 想要提取标签的内容
【发布时间】:2020-04-28 06:00:09
【问题描述】:

我是使用 Beautiful Soup 的新手,无法理解为什么 unwrap() 会像我一样工作。

我有python 3.6.9beautifulsoup4 4.8.2

我的输入 HTML 是:

 html='''
    <html>
    <head>
        <meta charset="utf-8"/>
        <link rel="stylesheet" type="text/css" href="../../common/style.css"/>
    </head>
    <body>
    <div id="content">
       <h3  HEAD /h3>
          <div class="myclass">
          <br>
          MY TEXT
          <br>
         </div>
        <h3  HEAD2 /h3>
          <div class="myclass">
          <br>
          MY TEXT 2
          <br>
         </div>
    </div>
    </body>
    </html>
    '''  

我想用id“内容”获取div的内容。 我认为这可以通过使用unwrap()

soup=BeautifulSoup(html, 'lxml')    
content=soup.find('div', {"id": "content"}).unwrap()

但这给了我标签,没有它的内容:

print(content):

<div id="content"></div>

这里发生了什么?如何正确提取标签的内容,而不保留周围的标签?

我期望的输出是:

   <h3  HEAD /h3>
      <div class="myclass">
      <br>
      MY TEXT
      <br>
     </div>
    <h3  HEAD2 /h3>
      <div class="myclass">
      <br>
      MY TEXT 2
      <br>
     </div>

当使用 .children 的方法时,在附加到 BeautifulSoup 对象时,我遇到了转义标签的问题:

final_content=''.join([str(i) for i in content.children]) 
body.append(final_content)

这会导致:

&lt;h3 head=""&gt;
&lt;div class="myclass"&gt;
&lt;br/&gt;
      MY TEXT
      &lt;br/&gt;
&lt;/div&gt;
&lt;h3 head2=""&gt;
&lt;div class="myclass"&gt;
&lt;br/&gt;
      MY TEXT 2
      &lt;br/&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;/h3&gt;</div>

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    首先,我们编辑您的 html,使其实际工作(问题出在 h3 标签中):

    html='''
       <html>
       <head>
           <meta charset="utf-8"/>
           <link rel="stylesheet" type="text/css" href="../../common/style.css"/>
       </head>
       <body>
       <div id="content">
          <h3>  HEAD </h3>
             <div class="myclass">
             <br>
             MY TEXT
             <br>
            </div>
           <h3>  HEAD2 </h3>
             <div class="myclass">
             <br>
             MY TEXT 2
             <br>
            </div>
       </div>
       </body>
       </html>
       '''  
    

    unwrap() 从你的汤中删除标签并将其内容放入父标签中(如果你再次检查你的汤,运行代码后没有“内容”ID)。所以你应该这样做:

    content = soup.find('div', {"id": "content"})
    content.contents[1:]
    

    输出:

    <h3>  HEAD </h3>, '\n', <div class="myclass">
     <br/>
              MY TEXT
              <br/>
     </div>, '\n', <h3>  HEAD2 </h3>, '\n', <div class="myclass">
     <br/>
              MY TEXT 2
              <br/>
     </div>, '\n'
    

    根据@KunduK 的回答使用children 替代:

    final_content = ''.join([str(i) for i in content.children])
    

    输出 2:

    ''.join([str(i) for i in content.children])
    Out[96]: '\n<h3>  HEAD </h3>\n<div class="myclass">\n<br/>\n         MY TEXT\n         <br/>\n</div>\n<h3>  HEAD2 </h3>\n<div class="myclass">\n<br/>\n         MY TEXT 2\n         <br/>\n</div>\n'
    

    【讨论】:

    • 这不是我想要的。我想完全删除外部标签,而不是替换它
    • 也许您应该在问题中说明您的预期输出,以便我们更好地帮助您。
    • 似乎您的 html 格式不正确,因为它无法识别您的 HEAD 字符串
    • 对我来说很合适:w3schools.com/tags/tag_hn.asp
    • h3 标签是问题,现在我可以做到了
    【解决方案2】:

    使用element.children,然后进行迭代。

    html='''
        <html>
        <head>
            <meta charset="utf-8"/>
            <link rel="stylesheet" type="text/css" href="../../common/style.css"/>
        </head>
        <body>
        <div id="content">
           <h3>  HEAD </h3>
              <div class="myclass">
              <br>
              MY TEXT
              <br>
             </div>
            <h3>  HEAD2 </h3>
              <div class="myclass">
              <br>
              MY TEXT 2
              <br>
             </div>
        </div>
        </body>
        </html>
        '''
    
    soup=BeautifulSoup(html,'html.parser')
    for item in soup.find('div',id='content').children:
         print(item)
    

    输出

    <h3>  HEAD </h3>
    
    
    <div class="myclass">
    <br/>
              MY TEXT
              <br/>
    </div>
    
    
    <h3>  HEAD2 </h3>
    
    
    <div class="myclass">
    <br/>
              MY TEXT 2
              <br/>
    </div>
    

    想要在变量中获取整个项目然后尝试。

    html='''
        <html>
        <head>
            <meta charset="utf-8"/>
            <link rel="stylesheet" type="text/css" href="../../common/style.css"/>
        </head>
        <body>
        <div id="content">
           <h3>  HEAD </h3>
              <div class="myclass">
              <br>
              MY TEXT
              <br>
             </div>
            <h3>  HEAD2 </h3>
              <div class="myclass">
              <br>
              MY TEXT 2
              <br>
             </div>
        </div>
        </body>
        </html>
        '''
    
    soup=BeautifulSoup(html,'html.parser')
    str1=''
    for item in soup.find('div',id='content').children:
        str1=str1+str(item)
    
    print(str1)
    

    【讨论】:

      【解决方案3】:

      TL;DR:打印soup,而不是content

      我遇到了同样的问题,不明白为什么unwrap() 没有返回我想要的结果。原因是它的工作方式与我们预期的略有不同。

      unwrap() 清除 initial soup 中的标签并返回标签。我们使用soup.find() 保存在其他变量中的任何内容都将只包含标签,不包含内容。

      【讨论】:

      • 几个代码示例会很有用,可以说明您的意思。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-11
      • 2020-08-24
      • 2017-12-31
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-01-15
      相关资源
      最近更新 更多