Python--网络爬虫之基础篇

1.      网页抓取:就是将URL地址中指定的网络资源从网络流中读取出来,保存到本地,类似于使用程序模拟IE浏览器的功能,把URL作为HTTP请求的内容发送到服务器端,然后读取服务器端的响应资源;

2.      python中,使用urllib2组件实现来抓取网页,其以urlopen函数的形式提供了一个非常简单的接口,简单的urllib2的代码如下:

import urllib2

response = urllib2.urlopen('http://www.baidu.com/')

html = response.read()

print html

以上四行代码实现的是将百度浏览器收到的代码全都打印出来了

注意:在传送HTTP请求时允许做的两件事请如下:

(1)     发送data表单数据

有时希望发送一些数据到URL,在HTTP中通常使用熟知的POST请求来发送,但一般的HTTP表单,data需要编码成标准形式,然后作为data参数传送到Request对象,编码工作采用urllib的函数而非urllib2,可采用以下编码方式:

方式一、data 数据的POST传送方式

import urllib

import urllib2

 

url = 'http://www.baidu.com/'

 

values ={'name':'WHY',

          'location':'SDU',

          'language':'Python'}

 

data =urllib.urlencode(values) """编码工作"""

req  = urllib2.Request(url,data)"""发送请求的同时传data"""

response =urllib2.urlopen(req) """接受反馈的信息"""

the_page =response.read() """读取反馈的内容"""

注意:如果没有传送data参数,urllib2使用GET方式的请求,但在方式一中采用的是POST发送请求。GETPOST请求的不同之处在于POST请求通常有“副作用”,它们会由于某种途径改变系统状态(例如提交成堆垃圾到你门口)。Data同样可以通过在Get请求的URL本身上面编码来传送,见方式二

方式二、data 数据的Get传送

import urllib

import urllib2

 

data = {}

 

data['name']=  'WHY'

data['location']= 'SDU',

data['language']== 'Python'

 

url_values =urllib.urlencode(data)

print url_values

 

name =Somebidy+Here&language=Python&location=Northampton

url ='http://www.baidu.com/'

 

full_url = url +'?' + url_values

 

data =urllib2.open(full_url)

(2)     设置HeadersHTTP请求---通过设置Headers可以实现python的程序像浏览器发送相同的报文格式

默认的urllib2把自己作为“Python-urllib/x.y(xypython主版本和次版本号,例如:Python-urllib/2.7)这个身份可能会让站点迷惑,或者干脆不工作,浏览器确认自己身份是通过User-Agent头,当创建了一个请求对象,可以给它一个包含头数据的字典,代码如下:

import urllib

import urllib2

 

url ='http://www.baidu.com'

 

user_agent ='Mozilla/4.0(compatible;MSIE 5.5;Windows NT)'

values ={'name':'WHY',

          'location':'SDU',

          'language':'Python'}

 

headers ={'User-Agent':user_agent}  “””设置header中的User-Agent的字段”””

data =urllib.urlencode(values)

req =urllib2.Request(url,data,headers)

response =urllib2.urlopen(req)

the_page =response.read()

3.      异常的处理和HTTP状态码的分类

urlopen不能处理一个response时,产生urlError。不过通常的Python APIs异常诸如:ValueErrorTypeError等也会同时产生。HTTPErrorurlError的子类,通常在HTTP URLs中产生

(1)      URLError

通常,该异常实在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生,这种情况下,异常同样会带有“reason”属性,它是一个tuple(可以理解为不可变的数组),包含了一个错误号和一个错误信息,代码如下:

import urllib2

 

req =urllib2.Request('http://www.baibai.com')

 

try:

   urllib2.urlopen(req)

 

except urllib2.URLError,e:

print e.reason

 

输出结果:

[Errno 11002] getaddrinfo failed

(2)      HTTPError

服务器上每一个HTTP应答对象reponse包含一个数字“状态吗”,有时状态码之处服务器无法完成请求,默认的处理器会为你处理一部分这种应答。例如:加入response是一个“重定向”,需要客户端从别的地址获取文档,urllib2将为你处理。其他不能处理的,urlopen会产生一个HTTPError。典型的错误包含“404(页面无法找到),403(请求禁止),和401(待验证请求)”。HTTP状态码表示HTTP协议所返回的响应的状态。比如客户端向服务器发送请求,如果成功地获得请求的资源,则返回状态码:200,表示相应成功,如果请求的资源不存在,则通常返回404错误。HTTP的状态码通常分为5中类型,分别以1-5五个数字开头,由三位整数组成,HTTP的各状态码如下所示:

200:请求成功处理方式:获得响应的内容,进行处理

201:请求成功,结果是创建了资源。新创建资源的URL可在响应的实体中得到处理方式:爬虫中不会遇到

202:请求被接受,但处理尚未完成处理方式:阻塞等待

204:服务器端已经实现了请求,但是没有返回心得信息。如果客户是用户代理,则无须为此更新自身的文档视图。处理方式:丢弃

302:请求到的资源在一个不同的URL处临时保存处理方式:重定向到临时的URL

400:非法请求处理方式:丢弃

404:没有找到处理方式:丢弃

5XX:回应代码以“5”开头的状态码表示服务器端发现自己出现错误,不能继续执行请求处理方式:丢弃

等等

 

注意:

第一、  默认的处理器重定向(300以外号码),并且100-299范围的号码指示成功,所以用户只能看到400-599的错误号码;

第二、  BaseHTTPServer.BaseHTTPRequestHandler.response是一个很有用的应答号码字典,显示了HTTP协议使用的所有应答号;

第三、  当一个错误号产生后,服务器返回一个HTTP错误号,和一个错误页面,可以使用HTTPError实例作为页面返回的应答对象response。这表示和错误属性一样,同样包含了readgeturlinfo方法,代码如下:

importurllib2

req =urllib2.Request('http://bbs.csdn.net/callmewhy')

 

try:

    urllib2.urlopen(req)

 

excepturllib2.URLError,e:

print e.code

     输出:403

(3)      Wrapping:捕获HTTPErrorURLError异常的方法

推荐使用第二种方法

方法一、

from urllib2 importRequest,urlopen,URLError,HTTPError

 

req =Request('http://bbs.csdn.net/callmewhy')

 

try:

   response = urlopen(seq)

 

except HTTPError,e: """注意此处exceptHTTPError必须在第一个,否则URLError将同样接收到HTTPError,因为HTTPERoorURLError的子类,故如果URLError在前面能接受到所有的URLError,包括HTTPError"""

   print 'The server couldn\'t fulfill the request.'

   print 'Error code: ',e.code

 

except URLError,e:

   print 'We failed to reach a server.'

   print 'Reason: ',e.reason

 

else:

   print 'No exception was raised.'

方法二、

from urllib2 importRequest,urlopen,URLError,HTTPError

 

req =Request('http://bbs.csdn.net/callmewhy')

 

try:

   response = urlopen(seq)

 

except URLError,e:

   if hasatrr(e,'reason'):

       print 'We failed to reach a server.'

       print 'Reason: ',e.reason

   elif hasatrr(e,'code'):

       print 'The server couldn\'t fulfill the request.'

       print 'Error code:',e.code

       

else:

print 'Noexception was raised.'

 

注意: hasattr用于确定一个对象是否具有某个属性。语法: hasattr(object, name)-> bool

判断object中是否有name属性,返回一个布尔值

4.      OpenerHandler的介绍和实例应用

(1)      urlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl()

geturl()

返回获取真正的URL,鉴于urlopen(或者opener对象使用的)或许会有重定向。获取的URL或许跟请求的URL不同。

代码:

from urllib2 importRequest,urlopen,URLError,HTTPError

 

old_url = 'http://rrurl.cn/b1UZup11111'

req = Request(old_url)

response = urlopen(req)

print 'Old url: ' + old_url

print 'Real url: '+ response.geturl()

运行结果:

Old url: http://rrurl.cn/b1UZup

Real url: http://rrurl.cn/b1UZup

此处并未产生重定向

info()

返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头headers。目前是httplib.HTTPMessage实例。经典的headers包含“Content-length”,“Content-type”,和其他内容

代码:

from urllib2 importRequest,urlopen,URLError,HTTPError

 

old_url = 'http://www.baidu.com'

req = Request(old_url)

response = urlopen(req)

print 'Info():'

print response.info()

运行结果:

(2)      Openers

当获取一个URL使用一个opener(一个urllib2.OpenerDirector的实例),正常情况下,使用默认opener:通过urlopen,当可创建个性的openers

(3)      Handles

Openers使用处理器handlers处理所有繁重的工作,每个handlers知道如何通过特定协议打开URLs,或者处理URL打开时的各个方面,例如:HTTP重定向,HTTP cookies

(4)      创建opener的方法

方法一、创建一个opener,可以实例化一个OpenerDirector,然后用.add_handle(some_handler_instance)

方法二、使用函数build_opener来创建opener对象,build_opener默认添加几个处理器,但提供快捷的方法来添加或更新默认处理器

注意:

第一、  install_opener用来创建(全局)默认opener,这表示调用urlopen将使用你安装的opener

第二、  opener对象的方法—open

该方法可以像urlopen函数那样直接用来获取urls,通常不必调用install_opener,除了为了方便

(5)      基本认证的内容(即openerhandler的应用)

Basic Authentication基本验证

第一、  创建和安装一个handler,以下将使用:HTTPBasicAuthHandler

第二、  当需要基础验证时,服务器发送一个header401错误码)请求验证,这个指定scheme和一个“realm,看起来如同:Www-authenticate:SCHEME realm=”REALM”,例如:Www-authenticate:Basicrealm=”cPanel Users”

第三、  客户端必须使用新的请求,并在请求里包含正确的姓名和密码

(6)      HTTPBasicAuthHandler使用一个密码管理的对象来处理URLsrealms来映射用户名和密码,如果知道realm(从服务器而来的头里)是什么,就能使用HTTPPasswordMgr。通常不关心realm是什么,就能用方便的HTTPPasswordMgrWithDefaultRealm。这个将为我们指定一个你默认的用户名和密码。

(7)      实例代码

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

import urllib2

 

"""创建一个密码管理者"""

password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

 

"""添加用户名和密码"""

top_level_url ="http://example.com/foo/" """可以是完整URL(包含"http",以及主机名和端口号,如:http://example.com/,也可以是一个"authority"(即主机名和可选的包含端口号,例如:"example.com"或者"example.com:8080""""

 

"""如果知道realm,可以使用其代替None"""

"""password_mgr.add_password(None,top_level_url,username,password)"""

password_mgr.add_password(None,top_level_url,'why','123')

 

 

""""创建一个新的handler"""

handler =urllib2.HTTPBasicAuthHandler(password_mgr)

 

"""创建openerOpenerDirector实例)"""

opener = urllib2.build_opener(handler)

 

 

a_url = 'http://www.baidu.com/'

 

"""使用opener获取一个url"""

opener.open(a_url)

 

"""安装opener"""

"""现在所调用urllib2.urlopen将用我们的opener""""

urllib2.install_opener(opener)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值