第 3 章 BeautifulSoup使用注意事项

目录

3.1. BeautifulSoup的Tag的属性
3.2. BeautifulSoup有时候会遇到非法的,不支持的html源码而导致无法解析或无法正常解析html

摘要

3.1. BeautifulSoup的Tag的属性

BeautifulSoup处理这种html源码:

<a href="http://creativecommons.org/licenses/by/3.0/deed.zh" target="_blank">版权声明</a>

后,是可以通过

soup.a['href']

去获得对应的href属性值的。

但是,想要去获得当前的某个未知的BeautifulSoup.Tag中,一共存在多少个属性,以及每个属性的值的时候,却不知道如何下手了。

比如对于如下html源码:

<p class="cc-lisence" style="line-height:180%;">......</p>

想要得知,一共有两个属性,分别是class和style,然后就可以通过上面的方法,去获得对应的属性值了。

对此问题,虽然看到了官网的解释:Tags的属性中的你可以将Tag看成字典来访问标签的属性

但是还是无法通过:

if("class" in soup)

的方式去判断soup中是否存在class属性,因为此时soup是Beautifulsoup.Tag类型变量,而不是dict变量。

并且,如果去强制将soup转换成为dict变量:

soupDict = dict(soup)

会报错的。

最后,还是无意间发现,原来Beautifulsoup.Tag是有个attrs属性的,其可以获得对应的元组列表,每一个元组是对应属性名和属性值:

attrsList = soup.attrs;
print "attrsList=",attrsList;
    
attrsList= [(u'class', u'cc-lisence'), (u'style', u'line-height:180%;')]

这样,就可以从元组列表中,自己去转换,获得属性的列表或字典变量了,就可以接着按照自己意愿去处理了。

[提示] 提示

另外,此处也通过

soup.name

获得了该tag的名字

而想要获得整个soup变量所有的属性和方法的话,可以用经典的dir去打印出来:

print "dir(soup)=",dir(soup);

此处的打印输出为:

dir(soup)= ['BARE_AMPERSAND_OR_BRACKET', 'XML_ENTITIES_TO_SPECIAL_CHARS', 'XML_SPECIAL_CHARS_TO_ENTITIES', '__call__', '__contains__', '__delitem__', '__doc__', '__eq__', '__getattr__', '__getitem__', '__init__', '__iter__', '__len__', '__module__', '__ne__', '__nonzero__', '__repr__', '__setitem__', '__str__', '__unicode__', '_convertEntities', '_findAll', '_findOne', '_getAttrMap', '_invert', '_lastRecursiveChild', '_sub_entity', 'append', 'attrMap', 'attrs', 'childGenerator', 'containsSubstitutions', 'contents', 'convertHTMLEntities', 'convertXMLEntities', 'decompose', 'escapeUnrecognizedEntities', 'extract', 'fetch', 'fetchNextSiblings', 'fetchParents', 'fetchPrevious', 'fetchPreviousSiblings', 'fetchText', 'find', 'findAll', 'findAllNext', 'findAllPrevious', 'findChild', 'findChildren', 'findNext', 'findNextSibling', 'findNextSiblings', 'findParent', 'findParents', 'findPrevious', 'findPreviousSibling', 'findPreviousSiblings', 'first', 'firstText', 'get', 'has_key', 'hidden', 'insert', 'isSelfClosing', 'name', 'next', 'nextGenerator', 'nextSibling', 'nextSiblingGenerator', 'parent', 'parentGenerator', 'parserClass', 'prettify', 'previous', 'previousGenerator', 'previousSibling', 'previousSiblingGenerator', 'recursiveChildGenerator', 'renderContents', 'replaceWith', 'setup', 'substituteEncoding', 'toEncoding']
        

有需要的话,可以对这些属性和方法,都尝试一下,以便更加清楚其含义。

刚写完上面这句话呢,然后自己随便测试了一下attrMap:

attrMap = soup.attrMap;
print "attrMap=",attrMap;
        

然后就很惊喜的发现,原来此处的attrMap,就是我程序中所需要的属性的dict变量啊:

attrMap= {u'style': u'line-height:180%;', u'class': u'cc-lisence'}

这样,就又省去了我程序中将attrs转换为dict变量的操作了,更加提高了效率。在次感谢Beautifulsoup的开发者。