Handler处理器 和 自定义Opener

opener是 urllib2.OpenerDirector 的实例,其中urlopen是模块默认构建的opener。 但是基本的urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高级功能。如果要支持这些功能,可以使用相关的 Handler处理器来创建特定功能的处理器对象,然后通过 urllib2.build_opener()方法使用这些处理器对象,创建自定义opener对象,最后 使用自定义的opener对象,调用open()方法发送请求。

自定义一个简单的opener()

 -*- coding: utf-8 -*-
import urllib2 # 构建一个HTTPHandler 处理器对象,支持处理HTTP请求
http_handler = urllib2.HTTPHandler() # 构建一个HTTPHandler 处理器对象,支持处理HTTPS请求
# http_handler = urllib2.HTTPSHandler() # 调用urllib2.build_opener()方法,创建支持处理HTTP请求的opener对象
opener = urllib2.build_opener(http_handler) # 构建 Request请求
request = urllib2.Request("http://www.baidu.com/") # 调用自定义opener对象的open()方法,发送request请求
response = opener.open(request) # 获取服务器响应内容
print response.read() # 开启Debug Log程序在执行的时候,会把收包和发包的报头在屏幕上自动打印出来
# 构建一个HTTPHandler 处理器对象,支持处理HTTP请求,同时开启Debug Log,debuglevel 值默认 0
# http_handler = urllib2.HTTPHandler(debuglevel=1) # 构建一个HTTPHSandler 处理器对象,支持处理HTTPS请求,同时开启Debug Log,debuglevel 值默认 0
# https_handler = urllib2.HTTPSHandler(debuglevel=1)

使用ProxyHandler处理器设置代理

使用代理IP,这也是爬虫/反爬虫的有效方式,很多网站会检测某一段时间某个IP的访问次数,如果访问频率过高,就有可能被禁止访问。这时可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。

在urllib2中可以通过ProxyHandler来设置使用代理服务器:

# -*- coding: utf-8 -*-
import urllib2 # 构建了两个代理Handler,一个有代理IP,一个没有代理IP
httpproxy_handler = urllib2.ProxyHandler({"http" : "124.88.67.81:80"})
nullproxy_handler = urllib2.ProxyHandler({}) proxySwitch = True #定义一个代理开关 # 通过 urllib2.build_opener()方法使用这些代理Handler对象,创建自定义opener对象
# 根据代理开关是否打开,使用不同的代理模式
if proxySwitch:
opener = urllib2.build_opener(httpproxy_handler)
else:
opener = urllib2.build_opener(nullproxy_handler) request = urllib2.Request("http://www.baidu.com/") # 只有使用opener.open()方法发送请求才使用自定义的代理,而urlopen()则不使用自定义代理。
response = opener.open(request) # 将opener应用到全局,之后不管是opener.open()还是urlopen() 发送请求,都将使用自定义代理。
# urllib2.install_opener(opener)
# response = urlopen(request) print response.read()

免费的开放代理很容易获取,有不少这样的网站,可以多收集一些代理IP,这样可以像随机获取User-Agent一样,随机选择一个代理去访问网站:

# -*- coding: utf-8 -*-
import urllib2
import random proxy_list = [
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"}
] # 随机选择一个代理
proxy = random.choice(proxy_list)
# 使用选择的代理构建代理处理器对象
httpproxy_handler = urllib2.ProxyHandler(proxy) opener = urllib2.build_opener(httpproxy_handler) request = urllib2.Request("http://www.baidu.com/")
response = opener.open(request)
print response.read()

免费代理不稳定,如果要求高就购买私密代理,购买私密代理后会得到一个账户和密码作为认证,具体使用如下:

# -*- coding:utf-8 -*-
import urllib2 # 私密代理授权的账户
user = "xxxx"
# 私密代理授权的密码
passwd = "****" # 授权的代理账户密码拼接
authproxy_handler = urllib2.ProxyHandler({"http" : user+":"+passwd+"@114.215.104.49:16816"}) # 构建一个自定义的opener
opener = urllib2.build_opener(authproxy_handler) # 构建请求
request = urllib2.Request("http://www.baidu.com/") # 获取响应
response = opener.open(request) # 打印内容
print response.read()

为避免账户密码泄露可以将其写入环境变量中。

HTTPBasicAuthHandler处理器(Web客户端授权验证)

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import urllib
import urllib2 # 用户名
user = "xxxx"
# 密码
passwd = "****"
# Web服务器 IP
webserver = "http://192.168.12.33" # 构建一个密码管理对象,用来保存需要处理的用户名和密码
passwdmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() # 添加账户信息,第一个参数realm是与远程服务器相关的域信息,一般没人管它都是写None,后面三个参数分别是 Web服务器、用户名、密码
passwdmgr.add_password(None, webserver, user, passwd) # 构建一个HTTP基础用户名/密码验证的HTTPBasicAuthHandler处理器对象,参数是创建的密码管理对象
httpauth_handler = urllib2.HTTPBasicAuthHandler(passwdmgr) # 通过 build_opener()方法使用这些代理Handler对象,创建自定义opener对象,参数包括构建的 proxy_handler
opener = urllib2.build_opener(httpauth_handler) # 可以选择通过install_opener()方法定义opener为全局opener
urllib2.install_opener(opener) # 构建 Request对象
request = urllib2.Request("http://192.168.199.107") # 定义opener为全局opener后,可直接使用urlopen()发送请求
response = urllib2.urlopen(request) # 打印响应内容
print response.read()

这种网站比较少,遇到时我们可以使用requests库来爬取会方便很多,这种方法过于繁琐。

Cookie

Cookie 是指某些网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持登录信息到用户下次与服务器的会话。

Cookies在爬虫方面最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续。

通过抓包获取一个有登录信息的Cookie来模拟登陆:

# -*- coding: utf-8 -*-
import urllib2 # 构建一个已经登录过的用户的headers信息
headers = {
"Host":"www.renren.com",
"Connection":"keep-alive",
"Upgrade-Insecure-Requests":"",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language":"zh-CN,zh;q=0.8,en;q=0.6",
# 这个Cookie是保存了密码无需重复登录的用户的Cookie,通过抓包获取(这里只是一部分)
"Cookie": "anonymid=efrna3fysufnwv; depovince=GW; _r01_=1; "
} # 通过headers里的报头信息(主要是Cookie信息),构建Request对象
urllib2.Request("http://www.renren.com/", headers = headers) # 直接访问renren主页,服务器会根据headers报头信息(主要是Cookie信息),判断这是一个已经登录的用户,并返回相应的页面
response = urllib2.urlopen(request) # 打印响应内容
print response.read()

cookielib库 和 HTTPCookieProcessor处理器

1、获取Cookie,并保存到CookieJar()对象中
# -*- coding: utf-8 -*-
import urllib2
import cookielib # 构建一个CookieJar对象实例来保存cookie
cookiejar = cookielib.CookieJar() # 使用HTTPCookieProcessor()来创建cookie处理器对象,参数为CookieJar()对象
handler=urllib2.HTTPCookieProcessor(cookiejar) # 通过 build_opener() 来构建opener
opener = urllib2.build_opener(handler) # 4. 以get方法访问页面,访问之后会自动保存cookie到cookiejar中
opener.open("http://www.baidu.com")
2. 访问网站获得cookie,并把获得的cookie保存在cookie文件中
# -*- coding: utf-8 -*-
import cookielib
import urllib2 # 保存cookie的本地磁盘文件名
filename = 'cookie.txt' # 声明一个MozillaCookieJar(有save实现)对象实例来保存cookie,之后写入文件
cookiejar = cookielib.MozillaCookieJar(filename) # 使用HTTPCookieProcessor()来创建cookie处理器对象,参数为CookieJar()对象
handler = urllib2.HTTPCookieProcessor(cookiejar) # 通过 build_opener() 来构建opener
opener = urllib2.build_opener(handler) # 创建一个请求,原理同urllib2的urlopen
response = opener.open("http://www.baidu.com") # 保存cookie到本地文件
cookiejar.save()
3. 从文件中获取cookies,做为请求的一部分去访问
# -*- coding: utf-8 -*-
import cookielib
import urllib2 # 创建MozillaCookieJar(有load实现)实例对象
cookiejar = cookielib.MozillaCookieJar() # 从文件中读取cookie内容到变量
cookie.load('cookie.txt') # 使用HTTPCookieProcessor()来创建cookie处理器对象,参数为CookieJar()对象
handler = urllib2.HTTPCookieProcessor(cookiejar) # 通过 build_opener() 来构建opener
opener = urllib2.build_opener(handler) response = opener.open("http://www.baidu.com")

urllib2 的异常错误处理

在我们用urlopen或opener.open方法发出一个请求时,如果urlopen或opener.open不能处理这个response,就产生错误。主要有URLError和HTTPError。
URLError 产生的原因主要有:没有网络连接、服务器连接失败、找不到指定的服务器。
HTTPError是URLError的子类,我们发出一个请求时,服务器上都会对应一个response应答对象,其中它包含一个数字"响应状态码"。如果urlopen或opener.open不能处理的,会产生一个HTTPError,对应相应的状态码,HTTP状态码表示HTTP协议所返回的响应的状态。

异常处理程序:

# -*- coding: utf-8 -*-

# 1、URLError
import urllib2
# 访问一个不存在的域名
requset = urllib2.Request('http://www.ajkfhafwjqh.com')
try:
urllib2.urlopen(request, timeout=5)
except urllib2.URLError, err:
print err # 2、HTTPError
import urllib2
requset = urllib2.Request('http://blog.baidu.com/zhihu')
try:
urllib2.urlopen(requset)
except urllib2.HTTPError, err:
# 打印状态码
print err.code
print err #3、由于HTTPError的父类是URLError,所以父类的异常应当写到子类异常的后面,所以上述的代码可以这么改写: import urllib2 requset = urllib2.Request('http://blog.baidu.com/zhihu') try:
urllib2.urlopen(requset) except urllib2.HTTPError, err:
print err.code except urllib2.URLError, err:
print err else:
print "OK"

Python爬虫基础(三)urllib2库的高级使用的更多相关文章

  1. Python爬虫入门之Urllib库的高级用法

    1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 首先,打开我们的浏览 ...

  2. Python爬虫入门:Urllib库的高级使用

    1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 首先,打开我们的浏览 ...

  3. PYTHON 爬虫笔记三:Requests库的基本使用

    知识点一:Requests的详解及其基本使用方法 什么是requests库 Requests库是用Python编写的,基于urllib,采用Apache2 Licensed开源协议的HTTP库,相比u ...

  4. 芝麻HTTP: Python爬虫入门之Urllib库的高级用法

    1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 首先,打开我们的浏览 ...

  5. python爬虫,使用urllib2库报错

    urllib2发生报错URLError: <urlopen error [Errno 10061]:首先检查网址是否正确其次如果报这种错误,是因为ie里设置了代理,取消即可, 步骤: 打开IE浏 ...

  6. 3.Python爬虫入门三之Urllib和Urllib2库的基本使用

    1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...

  7. python 3.x 爬虫基础---常用第三方库(requests,BeautifulSoup4,selenium,lxml )

    python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 python 3.x 爬虫基础---常用第三方库 ...

  8. 转 Python爬虫入门三之Urllib库的基本使用

    静觅 » Python爬虫入门三之Urllib库的基本使用 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器 ...

  9. python 爬虫基础知识一

    网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 网络爬虫必备知识点 1. Python基础知识2. P ...

  10. Python爬虫基础

    前言 Python非常适合用来开发网页爬虫,理由如下: 1.抓取网页本身的接口 相比与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简洁:相比其他动态脚本语言,如perl ...

随机推荐

  1. nodejs基础 -- NPM 使用介绍

    npm:是nodejs的包管理工具,随NodeJS一起安装的,能解决NodeJS代码部署上的很多问题,如: 1.允许用户从NPM服务器下载别人编写的第三方包到本地使用. 2.允许用户从NPM服务器下载 ...

  2. php -- realpath($path) 函数

    PHP realpath路径函数会检测$path指向的目标文件(或文件夹)是否真实存在,相当于调用了file_exists($path). 1.如果目标文件存在且不是符号连接(linux下俗称“软链接 ...

  3. js身份证验证类

    var IDCard = function () { //---------------------------------------------------------- // 功能:根据身份证号 ...

  4. 【Java面试题】59 Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

    Math类中提供了三个与取整有关的方法:ceil.floor.round,这些方法的作用与它们的英文名称的含义相对应,例如,ceil的英文意义是天花板,该方法就表示向上取整,Math.ceil(11. ...

  5. 【Java面试题】12 内部类可以引用它的包含类的成员吗?有没有什么限制?

    完全可以.如果不是静态内部类,那没有什么限制! 如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码: class Ou ...

  6. mac Virtualbox Ubuntu 设置共享目录

    如果要用VirtualBox自带的共享文件夹功能,必须先安装Guest Additions.安装方法:置顶的菜单条->devices->Install Guest Additions.点击 ...

  7. linux常用命令-tar,scp,du

    tar 打包排除指定目录 tar -zcvf afish.tar.gz * --exclude=file1 --exclude=dir1 排除目录注意: 1.--exclude=file1 而不是 - ...

  8. CUGBACM Codeforces Tranning 1 题解

    链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=61581#overview 描写叙述:非常老的CF题,题不错,拿来训练正好. 做的时 ...

  9. Linux基本监控项目

    1.网卡流量 (统计网卡TX(发送)RX(接受)流量脚本) 使用 Nagios 来监控网卡流量 2013/01/31 Nagios, 网卡 监控统计与日志分析 评论 2,272   下载地址为:che ...

  10. 基于51的串行通讯原理及协议详解(uart)

    串行与并行通讯方式并行:控制简单,传输速度快.线多,长距离成本较高且同时接受困难.串行:将数据字节分成一位一位的行驶在一条传输线上进行传输.如图:   同步与异步串行通讯方式同步串行通讯方式:同步通讯 ...