如何从Beautiful Soup返回纯文本而不是unicode

时间:2013-07-18 19:52:26

标签: python encoding beautifulsoup

我正在使用BeautifulSoup4来抓取这个网页,但是我得到了BeautifulSoup返回的奇怪的unicode文本。

这是我的代码:

    site = "http://en.wikipedia.org/wiki/"+a+"_"+str(b)
    hdr = {'User-Agent': 'Mozilla/5.0'}
    req = urllib2.Request(site,headers=hdr)  
    req.add_header('Accept-enconding', 'gzip') #Header to check for gzip
    page = urllib2.urlopen(req)
    if page.info().get('Content-Encoding') == 'gzip': #IF checks gzip
        data = page.read()
        data = StringIO.StringIO(data)
        gzipper = gzip.GzipFile(fileobj=data)
        html = gzipper.read()
        soup = BeautifulSoup(html, fromEncoding='gbk')
    else:
        soup = BeautifulSoup(page)

    section = soup.find('span', id='Events').parent
    events = section.find_next('ul').find_all('li')
    print soup.originalEncoding
    for x in events:
        print x

基本上我希望x用简单的英语。相反,我会看到这样的事情:

<li><a href="/wiki/153_BC" title="153 BC">153 BC</a> – <a href="/wiki/Roman_consul" title="Roman consul">Roman consuls</a> begin their year in office.</li>

这个特定的字符串中只有一个例子,但你明白了。

相关:我继续用一些正则表达式和其他字符串切割方法来剪切这个字符串,我应该在切割之前或之后将其切换为纯文本吗?我认为没关系,但看到因为我还是推迟了,我想我会问。

如果有人知道如何解决这个问题,我会很感激。感谢

编辑:感谢J.F.的提示,我现在在我的for循环之后使用了这个:

    for x in events:
        x = x.encode('ascii')
        x = str(x)
        #Find Content
        regex2 = re.compile(">[^>]*<")
        textList = re.findall(regex2, x)
        text = "".join(textList)
        text = text.replace(">", "")
        text = text.replace("<", "")
        contents.append(text)

但是,我仍然会这样:

2013 &#8211; At least 60 people are killed and 200 injured in a stampede after celebrations at F&#233;lix Houphou&#235;t-Boigny Stadium in Abidjan, Ivory Coast.

编辑: 这是我如何制作我的Excel电子表格(csv)并在我的列表中发送

rows = zip(days, contents)
with open("events.csv", "wb") as f:
writer = csv.writer(f)
for row in rows:
    writer.writerow(row)

因此在程序期间创建了csv文件,并在生成列表后导入所有内容。我只需要将它作为可读文本。

2 个答案:

答案 0 :(得分:3)

fromEncoding(已将其重命名为from_encoding以符合PEP8)告诉解析器如何解释输入中的数据。您(您的浏览器或urllib)从服务器接收的只是一个字节流。为了理解它,即为了从这个字节流构建一系列抽象字符(这个过程称为解码),必须知道信息是如何被编码的。这条信息是必需的,您必须提供它才能确保您的代码正常运行。维基百科告诉你他们如何对数据进行编码,它在每个网页的源代码顶部都有说明,例如。

<meta charset="UTF-8" />

因此,从维基百科的Web服务器接收的字节流应使用UTF-8编解码器进行解释。你应该调用

soup = BeautifulSoup(html, from_encoding='utf-8')

而不是BeautifulSoup(html, fromEncoding='gbk'),它试图用一些中文字符编解码器解码字节流(我想你是盲目地从here复制了那段代码)。

您确实需要确保理解文本编码的基本概念。实际上,你想要输出中的 unicode,这是一系列字符/符号的抽象表示。在这种情况下,没有“普通英语”这样的东西。

答案 1 :(得分:2)

There is no such thing as plain text。您看到的是使用错误字符编码解释为文本的字节,即字符串的编码与终端使用的字符串不同,除非之前通过对网页使用不正确的字符编码引入错误。

print x调用str(x),为BeautifulSoup对象返回UTF-8编码的字符串。

尝试:

print unicode(x)

或者:

print x.encode('ascii')