首页 > 代码库 > 使用bs4和urllib2抓取网页,都是坑
使用bs4和urllib2抓取网页,都是坑
今天折腾了一天使用python抓取新浪门户上的新闻,其实难倒是不难,关键就是在下面三个问题上卡住了。
问题一:新浪新闻返回gzip格式的数据
一开始read data之后,希望使用decode将读取到的字符串转化为unicode字符串,显然这是python处理乱七八糟字符串的常用套路。但是一上午都在各种encode error,以为是返回的数据中包含了乱七八糟的字符导致的。后来想起来自己在实习的时候用过别人的代码抓取网页内容,经过了一个gzip的过程,于是才想起来很有可能是服务器返回的数据使用gzip格式进行压缩。
于是当你接收到服务器返回的数据后,你判断一下”Content-Encoding”是否为’gzip’格式,如果是的话就要用gzip进行解压;否则的话则直接读取response的数据即可。可以参见下面的代码。
#coding=utf8 import urllib2 from StringIO import StringIO from bs4 import BeautifulSoup import gzip def loadData(url): request = urllib2.Request(url) request.add_header('Accept-encoding', 'gzip') response = urllib2.urlopen(request) print response.info().get('Content-Encoding') if response.info().get('Content-Encoding') == 'gzip': print 'response data is in gzip format.' buf = StringIO(response.read()) f = gzip.GzipFile(fileobj=buf) data = http://www.mamicode.com/f.read()>问题二:字符串编码问题
通常来说包含中文的网页,我们大都可以认为采用了GB系列的编码,其主要有三种分别是GB2312、GBK和GB18030三种,从时间发展先后来说GB2312 < GBK <GB18030,通常来说包含的字符的个数也是这个关系。如果说在使用GB2312时用到了属于GBK中的字符,那么我们可以在创建BeautifulSoup的时候指定from_encoding=’GBK’,当然由于GB18030中可编码的字符最多,可以不管网页使用的是GB2312或者是GBK编码,都可以一律在构造BeautifulSoup的时候指定from_encoding=’GB18030’。
另外在python中处理字符编码的时候,我们通常的套路是读入的时候要先将字符串decode到unicode,输出的时候我们进行encode,这样保证在内存中处理的都是unicode类型的字符串。
问题三:BeautifulSoup的使用
BeautifulSoup是方便高效的处理HTML或XML格式的内容的package,具体只会用一点点。可以参考Beautiful Soup的官方文档http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html。
吐槽一下,人生不如意十有八九,希望现在的不如意是为以后的生活攒人品吧。
使用bs4和urllib2抓取网页,都是坑