使用BeautifulSoup从HTML页面获取内容类型

时间:2011-03-23 20:33:44

标签: python lambda beautifulsoup

我正在尝试获取我抓取的页面的字符编码,但在某些情况下它失败了。这就是我在做的事情:

resp = urllib2.urlopen(request)
self.COOKIE_JAR.extract_cookies(resp, request)
content = resp.read()
encodeType= resp.headers.getparam('charset')
resp.close()

这是我的第一次尝试。但如果charset以类型None的形式返回,我会这样做:

soup = BeautifulSoup(html)
if encodeType == None:
    try:
        encodeType = soup.findAll('meta', {'http-equiv':lambda v:v.lower()=='content-type'})
    except AttributeError, e:
        print e
        try:
            encodeType = soup.findAll('meta', {'charset':lambda v:v.lower() != None})
        except AttributeError, e:
            print e
            if encodeType == '':
                encodeType = 'iso-8859-1'

我正在测试的页面在标题中有这个: <meta charset="ISO-8859-1">

我希望第一个try语句返回一个空字符串,但是我在两个try语句中都出现了这个错误(这就是为什么第二个语句现在嵌套的原因):

'NoneType'对象没有属性'lower'

第二次尝试声明有什么问题?我猜第一个也是不正确的,因为它抛出一个错误而不仅仅是空白。

或者更好是否有一种更优雅的方法可以从页面中删除任何特殊字符编码?我想要完成的最终结果是我不关心任何特殊编码的字符。我想删除编码字符并保留原始文本。我是否可以跳过以上所有内容并告诉BeautifulSoup只删除任何编码的内容?

2 个答案:

答案 0 :(得分:1)

我决定和BeautifulSoup一起吐出来。然后,当我解析文档中的每个单词时,如果我无法将其转换为字符串,我只是忽略它。

for word in doc.lower().split(): 
        try:
            word = str(word)
            word = self.handlePunctuation(word)
            if word == False:
                continue
        except UnicodeEncodeError, e:
            #word couldn't be converted to string; most likely encoding garbage we can toss anyways
            continue 

答案 1 :(得分:0)

在尝试确定页面的字符编码时,我认为应该尝试的顺序是:

  1. 通过元标记(例如<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  2. 从HTML网页本身确定
  3. 通过HTTP标头确定编码(例如Content-Type: text/html; charset=ISO-8859-1
  4. 最后,如果上面没有产生任何结果,你可以做一些事情,比如使用算法来确定页面的字符编码,使用其中的字节分布(注意,不能保证找到正确的编码) 。查看chardet库以获取此选项。