BeautifulSoup是一个html解析器,其主要功能是将html解析成树的结构,关于具体的用法官网介绍(http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html)了很多,在这里不在赘述。
在用BeautifulSoup解析html过程中遇到几个问题需要注意下:
1、解析html需要添加源文件字符集
url = 'http://newhouse.sh.fang.com/house/saledate/param_sd201011_or_pa1.htm' request = urllib2.Request(url) request.add_header('Accept-encoding', 'gzip') response = urllib2.urlopen(request,timeout=20) buf = StringIO( response.read()) f = gzip.GzipFile(fileobj=buf) html = f.read() soup=BeautifulSoup(html,from_encoding="gb18030")
其中使用BeautifulSoup解析html的时候最好添加from_encoding参数(该参数可以在html里面查看到<meta http-equiv=”Content-Type”content=”text/html; charset=gb2312” />),防止写文件时候出现经典错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
2、多层级的时候soup.div只能匹配到第一个div,这个我按照官方文档里面也没有匹配到第二个div,对于这个问题得具体问题具体分析,举个例子来说,在我爬取网页的过程中查看html源码发现我需要的元素都是一个class为bibiseetext的框架下,为此我使用
soup.findAll(attrs={"class":"bibiseetext"})
获取我需要的内容,然后使用
content.findAll("a")
来获取需要的内容
3、在将获取的内容写到txt的时候,发现出现上面经典的错误
UnicodeDecodeError
为此,需要在程序的头部添加
# -*- coding: utf-8 -*-
reload(sys) sys.setdefaultencoding( "utf-8" )
即可解决如上问题,使写入的文件全部正常。其实这是跟Python的内部原理有关,Python涉及到两个过程编码以及解码。编码是将Unicode转为String,解码是将String转换为Unicode,为什么采用Unicode的方式存放其实很好理解,因为不同的国家语言不一样,如utf8以及gbk,unicode相当于一个转换口,实现不同字符的转换。
(http://blog.youkuaiyun.com/crazyhacking/article/details/39375535)
头部设置
# -*- coding: utf-8 -*-
意思是脚本是以utf8的编码存储,假设不设置setdefaultencoding,那么脚本的字符将一utf8的编码方式保存。如果定义
str='你好' str.encode('gb18030')
将会报错,因为没有设置setdefaultencoding,以utf8保存的str将会以默认ANSCII的方式进行转为gb18030格式,简化如下:
str(utf-8保存)->转换(python默认使用anscii方式解析str的字符)->转为GB18030,报错。(前提是头部有标注脚本编码格式为UTF-8 )
附加为部分爬虫代码:
详情查看本人官方BLOG :)