Python BeautifulSoup unwrap () не работает должным образом. Хотите извлечь содержимое тега - PullRequest
0 голосов
/ 10 января 2020

Я новичок в работе с BeautifulSoup и у меня проблемы с пониманием того, почему unwrap () работает так же, как в моем случае.

У меня python 3.6.9 и beautifulsoup4 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>
    '''  

И я хочу получить содержимое div с id «содержимым». Я подумал, что это будет сделано с помощью 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>

Ответы [ 2 ]

1 голос
/ 10 января 2020

Используйте 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)
1 голос
/ 10 января 2020

Сначала мы отредактируем ваш 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() удаляет тег из вашего супа и помещает его содержимое в родительский тег ( если вы снова проверите свой суп, после запуска кода не будет идентификатора контента. Поэтому вы должны сделать что-то вроде:

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'

Альтернатива с использованием children на основе ответа @ KunduK:

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...