Python--网络爬虫之基础篇

来源:互联网 发布:百合 知乎 编辑:程序博客网 时间:2024/05/23 21:20

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 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 二建拿到证书原单位不解锁怎么办 凯云软件清单锁定只读了怎么办 苹果笔记本鼠标触摸板没反应怎么办 苹果笔记本键盘和触摸板失灵怎么办 苹果手机输入密码显示已停用怎么办 苹果7p手机刷机黑屏了怎么办 苹果5s来电接听屏幕卡顿怎么办? 手机摔了一下触屏失灵怎么办 小米手机摔了一下触屏失灵怎么办 苹果6sp触摸ic坏了怎么办 苹果4s屏幕摔裂了怎么办 新换的手机内屏颜色太亮怎么办 苹果手机摔了一下屏幕失灵怎么办 苹果手机6s屏幕坏了怎么办 苹果6s屏幕摔坏了怎么办 苹果手机屏幕进油了屏幕变暗怎么办 苹果手机不小心屏幕进油了怎么办 苹果6充电插口螺丝口坏了怎么办 苹果5s手机安装屏幕翘边怎么办 苹果手机摔了一下触摸屏失灵怎么办 苹果手机摔了下触摸屏失灵怎么办 苹果6老是屏幕失灵或者闪屏怎么办 华为荣耀8手触摸屏乱跳失灵怎么办 苹果5s屏幕有半边竖纹怎么办 苹果5s电源键坏了怎么办 苹果6s手机触屏失灵怎么办 不能取电池的手机触屏不灵怎么办? 7p主板触摸ic坏了怎么办 小米六手机摔了一下屏幕失灵怎么办 魅蓝5s触屏失灵怎么办 苹果手机键盘字母顺序乱了怎么办 红米手机进水后屏幕失灵怎么办 苹果7plus主屏按键坏了怎么办 苹果六手机上的红色变成粉色怎么办 苹果手机出现闪屏和手感不灵怎么办 荣耀6plus后开不了机怎么办 苹果手机touch id密码忘了怎么办 苹果7摔出了一个裂缝怎么办 屏幕摔坏了下键盘失灵怎么办 苹果4s手机按健失灵怎么办 金立手机摔了一下黑屏了怎么办