【问题标题】:Can't decode output from BeautifulSoup in Python无法在 Python 中解码 BeautifulSoup 的输出
【发布时间】:2011-12-03 01:12:54
【问题描述】:

我一直在尝试使用 BeautifulSoup 在 Python 中编写一个小爬虫。 一切都很顺利,直到我尝试打印(或写入文件)包含在各种 HTML 元素中的字符串。我正在抓取的网站是:http://www.yellowpages.ca/search/si/1/Boots/Montreal+QC,其中包含各种法语字符。出于某种原因,当我尝试将内容打印到终端或文件中时,而不是像预期的那样解码字符串,我得到的是原始的 unicode 输出。 这是脚本:

from BeautifulSoup import BeautifulSoup as bs
import urllib as ul
##import re

base_url = 'http://www.yellowpages.ca'
data_file = open('yellow_file.txt', 'a')

data = ul.urlopen(base_url + '/locations/Quebec/Montreal/90014002.html').readlines()

bt = bs(str(data))

result = bt.findAll('div', 'ypgCategory')

bt = bs(str(result))

result = bt.findAll('a')

for tag in result:
    link = base_url + tag['href']
    ##print str(link)
    data = ul.urlopen(link).readlines()

    #data = str(data).decode('latin-1')
    bt = bs(str(data), convertEntities=bs.HTML_ENTITIES, fromEncoding='latin-1')
    titles = bt.findAll('span', 'listingTitle')
    phones = bt.findAll('a', 'phoneNumber')

    entries = zip(titles, phones)

    for title, phone in entries:
        #print title.prettify(encoding='latin-1')
        #data_file.write(title.text.decode('utf-8') + "   " + phone.text.decode('utf-8') + "\n")
        print title.text

data_file.close()

/************/

这个输出是:Projets Autochtones Du Qu\xc3\xa9bec

正如您所见,应该在魁北克使用的带有重音的 e 没有显示。我已经尝试了 SO 中提到的所有内容,调用 unicode(),将 fromEncoding 传递给汤,.decode('latin-1') 但我什么也没得到。

有什么想法吗?

【问题讨论】:

  • 想要输出是什么?
  • 我希望解码操作将 Unicode 实体转换为可读字符,例如:“Québec”

标签: python unicode beautifulsoup decoding


【解决方案1】:

这应该是你想要的:

from BeautifulSoup import BeautifulSoup as bs
import urllib as ul

base_url = 'http://www.yellowpages.ca'
data_file = open('yellow_file.txt', 'a')

bt = bs(ul.urlopen(base_url + '/locations/Quebec/Montreal/90014002.html'))

for div in bt.findAll('div', 'ypgCategory'):
    for a in div.findAll('a'):
        link = base_url + a['href']

        bt = bs(ul.urlopen(link), convertEntities=bs.HTML_ENTITIES)

        titles = bt.findAll('span', 'listingTitle')
        phones = bt.findAll('a', 'phoneNumber')

        for title, phone in zip(titles, phones):
            line = '%s   %s\n' % (title.text, phone.text)
            data_file.write(line.encode('utf-8'))
            print line.rstrip()

data_file.close()

【讨论】:

  • 这很有趣。我尝试了您的版本,现在当它在终端中打印时效果很好,但是当我查看文件时,字符串包含与以前相同的原始输出,更奇怪的是文件中存在 html 实体好。我尝试将编码更改为解码,但这给了我一个新错误:UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 25: ordinal not in range(128)
  • 好的,感谢您的指导,我找到了一个可行的解决方案。事实证明,要将 Unicode 字符串写入文件,您需要使用 codecs.open('filename', 'mode', 'utf-8') 打开文件。完成此操作后,一切都顺利进行。再次感谢!
  • @史蒂夫。您确定要在文本编辑器中以“utf-8”格式打开文件吗?它对我来说非常好。我也没有看到任何 html 实体(尽管我只查看了前两千行)。
  • 另外,我将文件打开调用更改为: data_file = codecs.open( "yellow_file.txt", "a", "utf-8" ) 最里面的最后两行 for循环到这个: data_file.write(line.rstrip()) print line.rstrip()
【解决方案2】:

谁让你使用latin-1 来解码UTF-8 的东西? (在元标记上明确指定)

  1. 如果您在 Windows 上使用,您可能无法将 Unicode 输出到控制台,最好先测试写入文本文件。

  2. 如果您以文本形式打开文件,请不要向其中写入二进制文件:

    • codecs.open(...,"w","utf-8").write(unicode_str)
    • open(...,"wb").write(unicode_str.encode("utf_8"))

【讨论】:

  • 我实际上已经先用 utf-8 尝试了上述所有方法,但是当那不起作用时,我尝试了 latin-1。我的错。
猜你喜欢
  • 2020-01-12
  • 1970-01-01
  • 2019-08-29
  • 1970-01-01
  • 2012-06-08
  • 2014-10-28
  • 2015-10-04
  • 1970-01-01
相关资源
最近更新 更多