Python2.7里内置了很多非常有用的库,它在我电脑上的位置在/usr/lib/python2.7中。
写个基本的爬虫要用到的库有urllib、urllib2、cookielib、sgmllib和re,下面先分别简单介绍下一些文件的信息和相关函数——具体的真的是建议阅读源码,网上找的资料反而不及它直观(但先了解个大概总是好的),但sgmllib除外。先看一段代码吧。
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
urllib2.install_opener(opener)
response = urllib2.urlopen(url)
urllib2.py 这个文件的注释是最最良心的,基本上看了下注释和浏览文件主class和def都能了解用法了。按注释上的说法,它是An extensible library for opening URLs using a variety of protocols. 其主要class有:
Handler —— Each Handler implements a particular protocol or option. 它并不是一个特定的class,而是一堆有各自专门作用的Handler的集合,比如在def build_opener里default_classes记录的ProxyHandler, HTTPHandler(各为一种class)。每一个Handler都是用特定的url协议打开url或处理url的一些相关内容,比如上面的HTTPCookieProcessor,能通过传入的CookieJar沿用之前的Cookie,并有http_request和http_response函数将其整入到request或response当中。这些class都继承于class BaseHandler。
class OpenerDirector —— The OpenerDirector sets up the User Agent as the python-urllib client and manages a collection of Handler objects.
在其__init__函数可以清楚的看到self.addheaders = [('User-agent', client_version)] 一句,可见它现在是准备构造一个请求(只是准备)。然后它还有add_handler(self, handler)方法来为其添加Handler。简单来说就是个人认为它是用来告诉urllib2(上面说了as the python-urllib client)该以怎样的方式处理作参传入的url。至于这个class下面的open这些方法稍后再说。
def build_opener(*handlers) 实例化一个OpenerDirector类, 并将它稍加处理后return
def install_opener 函数用于将传入的OpenerDirector对象用global转换成全局变量,这样urllib2打开url时就能用设定好的方式打开
def urlopen 先看它相关的源码:
(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
global _opener
if _opener is None:
_opener = build_opener()
return _opener.open(url, data, timeout)
然后对于返回的页面结果的相关描述是,It opens the URL and returns the results as file-like object. url和请求可能用到的data都在参数列表里面了,还有最后一句代码,可见这里是真正的发送请求和返回页面信息的地方。在这顺便说下 OpenerDirector的open() 中有req = Request(fullurl, data) 一句,可见Request是在这构建的。然后,open()又调用了_open(),_open()又调用了_call_chain()......这些函数还会一层一层的调用下去,这里就不扯了。我们写爬虫要考虑的到 urlopen()这里就够了。等以后看较低层的内容时我再另外写文说明吧。
还有其他的一些就不说了,感觉没必要,如class Request,就是An object that encapsulates the state of a request.
Urllib.py 对于特定url请求的都还是直接用urllib2.py就好了,它有部分内容都是urllib.py 给import过去的,感觉那边的使用方便多了;虽说这里有不少内容都是urllib2.py上没用的,但总感觉可以用别的更易懂的方式替代掉。另外,这个文件总有些莫名其妙的东西(比如突然蹦出一行 ftpcache = {} 老搞得我开始怀疑人生
所以这里只说该文件的一个character set处理的问题。比如它有urlencode(),可将str进行URL编码()——当然是先编码再将data作参整合到Request当中啦。此外,也还有toByte()这样的处理方式。这些都是散的,要用的时候看源码查谷歌就好。
此外,它还有if sys.platform == 'darwin'和elif os.name == 'nt'这样好玩的语句。这个文件,可以说想了解基层的处理的话,一定要读。
Cookielib.py 我对cookie不怎么了解,这里也只挑一点点个人觉得较重要的讲
class Cookie 就只是对一个cookie操作啊,也是__init__ __str__ __repr__这些操作,
也还有直接对它的特定属性进行操作的,比如
set_nonstandard_attr(self, name, value):
self._rest[name] = value
class CookieJar 注释说得很清楚了,Collection of HTTP cookies。至于Cookie的收集来源就是path(好像也有方法支持从request里剥下来?不十分确定)。主要方法有_cookies_for_domain和_cookies_for_request。
在这顺便提下Cookie的 domain和path属性。domain为cookie对象的有效域,可以不是请求生成的访问域。cookie不能直接跨域访问,但能有一定的方法突破这个限制。
path则表示cookie所在目录
另外,有些页面貌似是要附有特定进入页面的cookie信息才有效的样子(至少我是这么理解针对我学校课程信息的爬虫代码的).
sgmllib.py 读这个文件的时候感到十分蛋疼,完全不知道讲的啥。在这种情况下,个人建议还是先上网查查这个文件干嘛的,大概怎么用,理清点结构再回来看,这时就会感到清晰多了。
这文件主要就是一个SGMLParser。它将HTML文档内容根据标签等分解成一个个有用的片段,并根据各片段的特点分别调用自身内对象的方法进行处理,解读各片段时会依照原文档里出现的顺序
在定义解析Hypertext时具体要干嘛时,要先建立一个SGMLParser子类,然后定义在遇到特定标签的行为(如def start_td就是描述遇到<td>的时候这个子类要干嘛,def end_td则是解析到</td>时的行为),至于在两者中间呢...between tags is passed to the parser by calling self.handle_data().另外,它也还能解析自定义标签。据说解析大份文档时,性能上是优于正则的。这个我没测试。
re.py则是python里用来表示正则的。常用的就是reg = re.complie('xxx') 来构建一个正则式,再objs = reg.findall(content) 在content里找到全部的符合reg的内容。然后就可以for obj in objs来遍历处理了。
另外,如果有必要设utf-8编码,最好记得import sys后,再reload(sys) ,然后再设sys.setdefaultencoding( "utf-8" )
然后直接上个最简单的实例吧
url = "http://xxxxxx"
cookiejar = cookielib.CookieJar() # 下面有检查的,没有cookie它也会自己间一个
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
urllib2.install_opener(opener)
response = urllib2.urlopen(url)
content = response.read()
content = content.decode("gb18030")
print content
爬下来了就用sgml或者re找你感兴趣的部分吧。可惜我正则并不算过关,写个麻烦点的都得先看看例子。