我正试图为国家和资本对刮取维基百科世界首都页面

时间:2016-01-03 20:53:04

标签: python web-scraping

该程序工作了很短的时间,然后遇到错误,我不知道它意味着什么或如何解决它。 这是代码:

from bs4 import BeautifulSoup
import urllib

BASE_URL = "https://en.wikipedia.org/wiki/List_of_national_capitals_in_alphabetical_order"

capitals_countries = []

html = urllib.urlopen(BASE_URL).read()
soup = BeautifulSoup(html, "html.parser")
country_table = soup.find('table', {"class" : "wikitable sortable"})

for row in country_table.find_all('tr'):
    cols = row.find_all('td')

    if len(cols) == 3:
        capitals_countries.append((cols[0].text.strip(), cols[1].text.strip()))

for capital, country in capitals_countries:
    print('{:35} {}'.format(capital, country))

这是错误:

Traceback (most recent call last):
  File "/Users/Kyle/Documents/scraper.py", line 19, in <module>
    print('{:35} {}'.format(capital, country))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 5: ordinal not in range(128)

我对html和刮擦有一个相当基本的理解。我很感激任何人都可以提供我这里发生的事情。

3 个答案:

答案 0 :(得分:0)

这应解决问题:

print('{:35} {}'.format(capital.decode('utf-8'), country.decode('utf-8')))

或者@karlson在评论中建议,我们也可以使用unicode字符串,如:

print(u'{:35} {}'.format(capital, country))

现在u'{:35} {}'部分是unicode,因此您不再需要解码它。

答案 1 :(得分:0)

当我查看列表时,我看到代码在波哥大打破了

我认为由于特殊字符á

而破裂

当我将print语句更改为

print(u'{:35} {}'.format(capital, country))

完美无缺

答案 2 :(得分:0)

你已经有了一个unicode字符串,尝试capital.decode('utf-8'),会给你:

In [13]: s =  u'\xe1'
In [14]: print s
á  
In [15]: s.decode("utf-8")
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-15-61efbeae9c77> in <module>()
----> 1 s.decode("utf-8")

/usr/lib/python2.7/encodings/utf_8.pyc in decode(input, errors)
     14 
     15 def decode(input, errors='strict'):
---> 16     return codecs.utf_8_decode(input, errors, True)
     17 
     18 class IncrementalEncoder(codecs.IncrementalEncoder):

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 0: ordinal not in range(128)

你在自己的代码中看到它的原因是当你在你试图将字符串编码为ascii的unicode字符串上调用format时,你试图使用str.format做同样的事情,因为你有非ascii字符:

In [16]: print "{}".format(s)
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-16-1119d22adcca> in <module>()
----> 1 print "{}".format(s)

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 0: ordinal not in range(128)

您只需要将str.format字符串设置为带有前导u的unicode字符串,不要解码任何内容:

In [17]: print u"{}".format(s)
á

因此,在您自己的代码中,您需要在格式字符串上使用前导u,而不是其他内容。

for capital, country in capitals_countries:
    print(u'{:35} {}'.format(capital, country))

您可以通过添加输出<type 'unicode'>的打印类型(大写)来验证您是否拥有unicode字符串。