Python 爬虫学习稿(二)

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

# encoding: utf-8

import urllib.request

url = '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: nginx
Date: Sun, 10 Jan 2016 03:10:02 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding

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

# encoding: utf-8

import urllib.request

request = 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-8

import urllib.request

request = 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-8

import urllib.request

request = 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-8

import urllib.request
import http.cookiejar

cookie = http.cookiejar.CookieJar()
#保存Cookie
request = urllib.request.HTTPCookieProcessor(cookie)
#用这个Cookie生成一个HTTPCookieProcessor,这是一个用来处理Cookie的handler
opener = 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-8

import urllib.request
import http.cookiejar

cookie = http.cookiejar.LWPCookieJar()
#保存Cookie
request = urllib.request.HTTPCookieProcessor(cookie)
#用这个Cookie生成一个HTTPCookieProcessor,这是一个用来处理Cookie的handler
opener = 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-8

import http.cookiejar

cookie = 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-8

import urllib
import urllib.request
import http.cookiejar

filename = 'C:\\Users\\window\Desktop\\cookie.txt'
# 声明一个MozillaCookieJar对象实例来保存Cookie,之后写入文件
cookie = http.cookiejar.MozillaCookieJar(filename)

handler = urllib.request.HTTPCookieProcessor(cookie)
# 用这个Cookie生成一个HTTPCookieProcessor,这是一个用来处理Cookie的handler
opener = 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发出对必须登录才能访问的另一个网址的请求,我选用的网址是本学期的某门课程的URL
gradeUrl = 'http://e.ncut.edu.cn/eclass/c_2015A_7241001/'
# 访问某门课程的URL
result = 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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值