在使用Beautifulsoup过程中,对于大多数html源码,通过指定正确的编码,或者本身是默认UTF-8编码而无需指定编码类型,其都可以正确解析html源码,得到对应的soup变量。
然后就接着去利用soup实现你所想要的功能了。
但是有时候会发现,有些html解析后,有些标签等内容丢失了,即所得到的soup不是所期望的完整的html的内容。
这时候,很可能遇到了非法的html,即其中可能包含了一些不合法的html标签等内容,导致Beautifulsoup虽然可以解析,没有报错,但是实际上得到的soup变量,内容缺失了一部分了。
比如我就遇到过不少这样的例子:
之前在为BlogsToWordPress添加Blogbus支持过程中去解析Blogbus的帖子的时候,遇到一个特殊的帖子:http://ronghuihou.blogbus.com/logs/89099700.html,其中一堆的非html5的代码中,包含了这样一段html5的代码的写法,即标签属性值不加括号的:
<SCRIPT language=JavaScript> document.oncontextmenu=new Function("event.returnValue=false;"); //禁止右键功能,单击右键将无任何反应 document.onselectstart=new Function( "event.returnValue=false;"); //禁止先择,也就是无法复制 </SCRIPT language=JavaScript>
结果导致Beautifulsoup解析错误,得到的soup中,找不到所需要的各种class等属性值。
对应的解决办法就是,把这部分的代码删除掉,然后再解析就可以了:
其中一堆的非html5的代码中,包含了这样一段html5的代码的写法,即标签属性值不加括号的:
foundInvliadScript = re.search("<SCRIPT language=JavaScript>.+</SCRIPT language=JavaScript>", html, re.I | re.S ); logging.debug("foundInvliadScript=%s", foundInvliadScript); if(foundInvliadScript): invalidScriptStr = foundInvliadScript.group(0); logging.debug("invalidScriptStr=%s", invalidScriptStr); html = html.replace(invalidScriptStr, ""); logging.debug("filter out invalid script OK"); soup = htmlToSoup(html);
之前在给BlogsToWordpress添加新浪博客的支持的过程中
遇到很多新浪博客的帖子的html中,包含很多判断浏览器版本的相关代码:
<!–[if lte IE 6]> xxx xxx <![endif]–>
由此导致Beautifulsoup解析html不正常。
接上面那个解析新浪博客帖子的例子,期间又遇到另外一个问题,对于一些特殊帖子:http://blog.sina.com.cn/s/blog_5058502a01017j3j.html
其包含特殊的好几十个font标签且是一个个嵌套的代码,导致无法Beautifulsoup无法解析html,后来把对应嵌套的font标签删除掉,才可以正常解析。
相关python代码为:
# handle special case for http://blog.sina.com.cn/s/blog_5058502a01017j3j.html processedHtml = processedHtml.replace('<font COLOR="#6D4F19"><font COLOR="#7AAF5A"><font COLOR="#7AAF5A"><font COLOR="#6D4F19"><font COLOR="#7AAF5A"><font COLOR="#7AAF5A">', ""); processedHtml = processedHtml.replace("</FONT></FONT></FONT></FONT></FONT></FONT>", "");
遇到其他类似的问题,也可以去删除或替换出错代码,即可解决问题。
不过需要说明的是,很多时候,你未必很容易就找到出错的代码。
想要找到出错的代码,更多的时候,需要你一点点调试,一点点的删除看似可疑的一些html源码,然后最终才能定位到出错的代码,然后删除掉后,才可以正常工作的。