如何在python中忽略BeautifulSoup解析器的换行符?

问题描述 投票:0回答:1

好吧,我开始我的第一个问题。我正试图用BeautifulSoup解析一个网站的一些内容。我想抓取的内容在td标签中,但有时是两行,有时不是(包括代码中的换行)。

例为牛头犬。

有时 <td class="searchResultsDogBreed">Bulldog</td> 其他时候 <td class="searchResultsDogBreed">Bulldog<br/>French</td>"

当我用下面的方法来列出狗的品种时。

for db in soup.body.find_all('td', class_="searchResultsDogBreed"):
         list_dogbreed.append(db.text.strip())

它带来的一些结果是 斗牛犬法国人 正如预期的那样,因为它去掉了所有的空格。我想要么忽略法式,而只保留了 斗牛犬 因为我只关心它是不是牛头犬,或者至少列出它,使输出是 "牛头犬法语",这样我就可以把这两个词分开。

我必须以某种方式去掉空格,因为在不使用 strip()的情况下,实际的输出结果是这样的

"                               BulldogFrench      "

谢谢你的帮助!

python html beautifulsoup html-parsing
1个回答
0
投票

BeautifulSoup 有特殊功能 get_text() 其中有选项 separator 来分隔不同子代的文本。默认情况下,它使用空字符串作为分隔符,所以你得到的是 BulldogFrench 但你可以使用空格作为分隔符。如果你有一些带空格的字符串你想保留,那么你可以使用一些独特的字符,如 | 备用 split("|").

from bs4 import BeautifulSoup as BS

text = '''
<td class="searchResultsDogBreed">Bulldog1</td>
<td class="searchResultsDogBreed">Bulldog2<br/>French</td>
'''

soup = BS(text, 'html.parser')

all_items = soup.find_all('td')
for item in all_items:
    text = item.get_text(separator='|')
    print('before:', text)
    text = text.split('|')[0]
    print('after:', text)

结果。

before: Bulldog1
 after: Bulldog1
---
before: Bulldog2|French
 after: Bulldog2
---

BTW: get_text() 也有选项 strip=True 在将元素连接到一个字符串之前去除空格--当你的元素之间有许多空格时,这很有用。


你也可以使用 .children 创建包含所有子元素的列表,并只获取第一个元素。

from bs4 import BeautifulSoup as BS

text = '''
<td class="searchResultsDogBreed">Bulldog1</td>
<td class="searchResultsDogBreed">Bulldog2<br/>French</td>
'''

soup = BS(text, 'html.parser')

all_items = soup.find_all('td')
for item in all_items:
    elements = list(item.children)
    print('  All:', elements)
    print('First:', elements[0])
    print('---')

结果。

  All: ['Bulldog1']
First: Bulldog1
---
  All: ['Bulldog2', <br/>, 'French']
First: Bulldog2

BTW: 只获取文本元素

elements = [x for x in item.children if isinstance(x, str)]

结果。

All: ['Bulldog1']
All: ['Bulldog2', 'French']

EDIT: 而不是... list(item.children) 你可以试试

elements = item.contents

您也可以尝试 item.next 但可能会有下一次 td (或 \n)如果当前 td 是空的。

from bs4 import BeautifulSoup as BS

text = '''
<td class="searchResultsDogBreed">Bulldog1</td>
<td class="searchResultsDogBreed"></td>
<td class="searchResultsDogBreed">Bulldog2<br/>French</td>
'''

soup = BS(text, 'html.parser')
all_items = soup.find_all('td')

for item in all_items:
    print('    item:', item)
    print('children:', list(item.children))
    print('contents:', item.contents)
    print('    next:', item.next)
    print(' 2x next:', item.next.next)
    print(' 3x next:', item.next.next.next)
    #elements = list(item.children)
    elements = item.contents
    #elements = [x for x in item.children if isinstance(x, str)]
    print('     All:', elements)
    if elements:
        print('   First:', elements[0])
    else:
        print('   First:')
    print('---')

结果:

   item: <td class="searchResultsDogBreed">Bulldog1</td>
children: ['Bulldog1']
contents: ['Bulldog1']
    next: Bulldog1
 2x next: 

 3x next: <td class="searchResultsDogBreed"></td>
     All: ['Bulldog1']
   First: Bulldog1
---
    item: <td class="searchResultsDogBreed"></td>
children: []
contents: []
    next: 

 2x next: <td class="searchResultsDogBreed">Bulldog2<br/>French</td>
 3x next: Bulldog2
     All: []
   First:
---
    item: <td class="searchResultsDogBreed">Bulldog2<br/>French</td>
children: ['Bulldog2', <br/>, 'French']
contents: ['Bulldog2', <br/>, 'French']
    next: Bulldog2
 2x next: <br/>
 3x next: French
     All: ['Bulldog2', <br/>, 'French']
   First: Bulldog2
---
© www.soinside.com 2019 - 2024. All rights reserved.