Python 爬虫学习稿(二)

来源:互联网 发布:令狐公子 知乎 编辑:程序博客网 时间:2024/05/23 22:50

一、对上篇的补充
urlopen返回的对象提供了如下方法:
read() , readline() ,readlines() , fileno() , close()这些的使用方式与文件对象完全一样
info():返回一个httplib.HTTPMessage对象,表示远程服务器返回的头信息
getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
geturl():返回请求的url

# encoding: utf-8import urllib.requesturl = 'http://weibo.com/277773956'request = urllib.request.Request(url)try:    response = urllib.request.urlopen(request)except urllib.request.HTTPError as e:    if hasattr(e, "code"):        print(e.code)    elif hasattr(e, "reason"):        print(e.reason)print(url)print(response.geturl())

geturl可以返回真正的URL地址,如果遇到重定向后者短网址都可以解析成真正的URL地址,然后我们将geturl()方法改为info()就可以查看header信息

Server: nginxDate: Sun, 10 Jan 2016 03:10:02 GMTContent-Type: text/htmlTransfer-Encoding: chunkedConnection: closeVary: Accept-Encoding

二、有关错误(Error)
通常,URL Error会在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生。
在产生Error的情况下,异常会带有”reason”属性,包含了一个错误号和一个错误信息。

# encoding: utf-8import urllib.requestrequest = urllib.request.Request('http://www.txbis.me')try: urllib.request.urlopen(request)except urllib.request.URLError as e:    print(e.reason)

需要注意的是,在Python 3.X中try ··· except 语句必须写成except as 而不能像之前写成空格分割
可以看到出现错误11001[Errno 11001] getaddrinfo failed
抛出异常这个处理部分就不过多解释了,不知道的先去看异常处理这个部分
我们采用urllib.request.URLError来捕获这个异常,并且打印出错误信息


URL可以产生Error,HTTP部分也会产生Error,比如最常见的404状态码,标定HTTP协议所返回的响应的状态,HTTPErrorshi URLError的一个子类。
各种状态码不再解释,只需要记住最常见的几种,剩下的遇到了现查就可以
值得注意的是,100-299都是标定成功的,400-599都是标定错误的

# encoding: utf-8import urllib.requestrequest = urllib.request.Request('http://blog.csdn.net/tan6600')try: urllib.request.urlopen(request)except urllib.request.HTTPError as e:    print(e.code)    print(e.reason)

可以看到打印出来
403
Forbidden

的信息,我们知道HTTPError是属于URLError大类的,那么如果一个错误的产生并不是在HTTPError中,而是在URLError中的话,我们就必须先判断能否捕捉到抛出的HTTPError,再判断是否抛出URLError

hasattr是Python的一个内置函数,用于确定一个对象是否具有某个属性。其语法为:hasattr(object, name) -> bool
判断object中是否有name属性,返回一个布尔值。

# encoding: utf-8import urllib.requestrequest = urllib.request.Request('http://blog.csdn.net/tan6600')try:    urllib.request.urlopen(request)except urllib.request.HTTPError as e:    if hasattr(e, "code"):        print(e.code)    elif hasattr(e, "reason"):        print(e.reason)

这样就使代码更加健壮

三、Cookie 相关
你在获取一个URL时即使用urlopen,就是使用了一个opener,我们如果要构建更灵活的参数,用这个默认的opener是不够的,需要更加一般的opener进行设置
Cookiejar可以提供可存储Cookie的对象,下面是一个查看Cookie值的程序

# encoding: utf-8import urllib.requestimport http.cookiejarcookie = http.cookiejar.CookieJar()#保存Cookierequest = urllib.request.HTTPCookieProcessor(cookie)#用这个Cookie生成一个HTTPCookieProcessor,这是一个用来处理Cookie的handleropener = urllib.request.build_opener(request)#创建一个自定义的opener,把handler传进去response = opener.open('http://www.baidu.com')#用自定义的opener打开连接for item in cookie:    print('Name = '+item.name)    print('Value = '+item.value)

下面是一个存储Cookie到文件的程序

# encoding: utf-8import urllib.requestimport http.cookiejarcookie = http.cookiejar.LWPCookieJar()#保存Cookierequest = urllib.request.HTTPCookieProcessor(cookie)#用这个Cookie生成一个HTTPCookieProcessor,这是一个用来处理Cookie的handleropener = urllib.request.build_opener(request)#创建一个自定义的opener,把handler传进去response = opener.open('http://www.baidu.com')#用自定义的opener打开连接cookie.save("C:\\Users\\window\Desktop\\cookie.txt")#保存Cookie到本地文件

下面是一个读取本地Cookie的程序

# encoding: utf-8import http.cookiejarcookie = http.cookiejar.LWPCookieJar("C:\\Users\\window\Desktop\\cookie.txt")cookie.load()

Python中共有3种Cookie类,http.cookiejar.CookieJar和http.cookiejar.LWPCookieJar和http.cookiejar.MozillaCookieJar
其中,后两种可以存取Cookie文件,尤以LWPCookieJar可读性最好
下面有一个利用Cookie模拟登录网站的程序

# encoding: utf-8import urllibimport urllib.requestimport http.cookiejarfilename = 'C:\\Users\\window\Desktop\\cookie.txt'# 声明一个MozillaCookieJar对象实例来保存Cookie,之后写入文件cookie = http.cookiejar.MozillaCookieJar(filename)handler = urllib.request.HTTPCookieProcessor(cookie)# 用这个Cookie生成一个HTTPCookieProcessor,这是一个用来处理Cookie的handleropener = urllib.request.build_opener(handler)# 创建一个自定义的opener,把handler传进去value = {'login': '12101110', 'password': '123456', 'submitAuth': '%BD%F8%C8%EB'}# 定义表单body字典。submitAuth值是URL编码,编码格式为GB2312,解码以后是进入的意思,不知道为什么会有这样一个奇怪的值postdata = urllib.parse.urlencode(value).encode(encoding='UTF-8')# 多模式教学网的URL(用Fiddler捕获分析得到)loginUrl = 'http://e.ncut.edu.cn/eclass/index.php?mon_icampus=yes'# 模拟登录,并把Cookie保存到变量result = opener.open(loginUrl, postdata)# 保存Cookie到cookie.txt中cookie.save(ignore_discard = True, ignore_expires = True)# 利用Cookie发出对必须登录才能访问的另一个网址的请求,我选用的网址是本学期的某门课程的URLgradeUrl = 'http://e.ncut.edu.cn/eclass/c_2015A_7241001/'# 访问某门课程的URLresult = opener.open(gradeUrl)# 打印出访问到的网页源码print (result.read())

可以看到,网页下方的2004.8.1 - 2016.1.11版权日期,已经在代码中了,即已经模拟登录成功了!
这个服务器并没有对是否浏览器访问进行限制,否则需要修改header,如果需要,增加如下部分即可

header = {    Accept: text/html, application/xhtml+xml, image/jxr, */*    Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3    User-Agent: Edge/12.10240    Accept-Encoding: gzip, deflate    Host: e.ncut.edu.cn    Connection: Keep-Alive}
0 0
原创粉丝点击