如何在python列表中编码bs4可导航字符串?

时间:2017-07-17 00:37:10

标签: python beautifulsoup unicode-string

我已经广泛搜索过,虽然有大量资源可以回答这个问题,但我似乎无法得到任何可行的答案。我看过Ned Batchelder关于Unicode(https://nedbatchelder.com/text/unipain.html)的演讲,并阅读了S.O.的许多答案。但我还是不知所措。

我正在使用Python 3和BeautifulSoup 4从维基百科中搜索和解析表格。我有一个名为fighter_B的列表

    print(type(fighter_B))
    <class 'list'>

    print(type(fighter_B[0])
    <class 'bs4.element.NavigableString'>

列表中的第二个和第三个观察结果包含带有非错误字母的名称,例如FabrícioWerdum。当我尝试打印战斗机名称时,我收到此错误,

print(fighter_B[1])
UnicodeEncodeError: 'ascii' codec can't encode character '\xed' in position 4: ordinal not in range(128)

我尝试了各种编码功能,但我总是抛出相同的错误。

[fighter.encode('utf-8') for fighter in fighter_B]
print(fighter_B[1])
UnicodeEncodeError: 'ascii' codec can't encode character '\xed' in position 4: ordinal not in range(128)

for i in fighter_B:
    i.encode('utf-8')
print(fighter_B[1])
UnicodeEncodeError: 'ascii' codec can't encode character '\xed' in position 4: ordinal not in range(128)

[fighter.decode('utf-8') for fighter in fighter_B]
AttributeError: 'NavigableString' object has no attribute 'decode'

[str(fighter).decode('utf-8) for fighter in fighter_B]
AttributeError: 'str' object has no attribute 'decode'

[fighter.encode('ascii') for fighter in fighter_B]
UnicodeEncodeError: 'ascii' codec can't encode character '\xed' in position 4: ordinal not in range(128)

我看到的所有各种答案都只是建议将变量编码为'utf-8'。我不确定为什么编码在这里不起作用,我想知道是否是由于列表中的每个项目都是'bs4.element.NavigableString'类型的事实。任何提示都会非常感激,因为我觉得这一点非常难过。

1 个答案:

答案 0 :(得分:1)

初步答复:

我遇到了一个问题,你试图迭代一些HTML块来提取一些值或值,但它看起来像这样:

>>> for elem in li:
    type(elem)

<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'bs4.element.Tag'>
<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>

在这些情况下,您无法轻松迭代对象,因为对象具有不同的方法。因此,添加另一个包含元素进一步特异性的findAll可能是有意义的。

以下是否执行了该操作?

import requests
from bs4 import BeautifulSoup

url = r'https://en.wikipedia.org/wiki/List_of_male_mixed_martial_artists'

html = requests.get(url)
soup = BeautifulSoup(html.text, 'html.parser')

names = []

for li in soup.findAll('li'):
    for i,link in enumerate(li.findAll('a')):
        if i == 1:
            names.append(link.getText())

'Fabrício Werdum' in names返回True