爬虫基础 之(三) --- urllib模块

urllib.request模块 方法

  从urllib中导入请求模块 编写url

1 from urllib import request      # 导入request模块
2 # 或者 import urllib.request
3 url = "http://www.baidu.com/"   # 编写 url 

1. urlopen( ) 方法

  用于打开一个远程的url连接,并且向这个连接发出请求,获取响应结果。返回的结果是一个http响应对象,这个响应对象中记录了本次http访问的响应头和响应体

  urllib.request.urlopen 参数介绍:urllib.request.urlopen(url,   data=None,   [timeout, ]*,  cafile=None, capath=None, cadefault=False, context=None)

  • url参数使用
 1 response = request.urlopen(url=url)
 2 
 3 print(response)    # 获取响应,结果为:<http.client.HTTPResponse object at 0x10be801d0>
 4 # 获取响应头
 5 print(response.headers)   # 获取响应头
 6 print(response.url)       # 获取响应url 
 7 print(response.status)    # 获取响应状态码
 8 # 获取响应体
 9 print(response.read())                  # 获取响应体 二进制字符串  
10 print(response.read().decode("utf-8"))  # 对响应体进行解码
11 # 按行读取
12 print(response.readline())      # 读取一行
13 print(response.readline())      # 读取下一行
14 print( response.readlines())    # 读取多行。得到一个列表 每个元素是一行 
  •  data参数使用

  上述例子是通过 get请求 获得百度,下面使用urllib的 post请求。添加data参数的时候就是以post请求方式请求,若没有data参数就是get请求方式

1 import urllib.request
2 import urllib.parse  # urllib.parse模块,后面有介绍
3 #或者 from urllib import request, parse
4 data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8') 5 # 用urllib.parse模块,通过bytes(urllib.parse.urlencode())可以将post数据进行转换并放到urllib.request.urlopen的data参数中。这样就完成了一次post请求。 6 7 response = urllib.request.urlopen('http://httpbin.org/post', data=data) 8 print(response.read())
  • timeout参数使用

  在某些网络情况不好或者服务器端异常会出现请求慢或者请求异常等情况,所以这个时候需要给请求设置一个超时时间,而不是让程序一直在等待结果。使用timeout参数设置超时时间

1 import urllib.request
2 
3 response = urllib.request.urlopen('http://httpbin.org/get', timeout=1)
4 print(response.read())   # 正常结束,控制台显示:socket.time : timed out
5 
6 response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
7 print(response.read())   # 超时,控制台显示:urllib.error.URLErrot : <urlopen error timed out>

2. urlretrieve(url =”xxx“, filename = ”xxx“) 方法

  打开url这个连接 并且发起请求,获得响应并把响应结果保存到filename文件中

1 res3 = request.urlretrieve(url=url,filename="./baidu.html") 
2 print(res3)     # 获取url 保存到baidu.html文件中 并打印

3. Request(url=url, data=data, method='POST') 方法

  web开发中,同一个url往往可以对应若干套不同的数据(或者界面,如手机、电脑),后台可以根据发起请求的前端的用户代理的不同,

  而决定应该给前端做出什么样的响应,如果检测到没有用户代理可以拒绝访问。有很多网站为了防止程序爬虫爬网站造成网站瘫痪,

  会需要携带一些headers头部信息才能访问,最长见的有user-agent参数所以需要伪装请求头,去访问目标站。

  urllib.ruquest.Request 参数介绍:urllib.ruquest.Request(url=url,headers=headers,data=data,method='POST')

  • headers 参数使用

  给请求添加头部信息,定制自己请求网站时的头部信息,使得请求伪装成浏览器等终端

1 req = request.Request(url=url,headers={'UserAgent':'Mozilla/5.0 (Windows NT 10.0; Win64;x64)AppleWebKit/537.36 (KHTML, likeGecko)Chrome/71.0.3578.80Safari/537.36'})
2 
3 res = request.urlopen(req)  # 用加入了请求头的请求对象发起请求
4 print(res.status)           # 打印状态码           

  添加请求头的post请求方式

 1 from urllib import request, parse
 2 
 3 url = 'http://httpbin.org/post'
 4 headers = {
 5     'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
 6     'Host': 'httpbin.org'}
 7 dict = { 'name': 'taotao'}
 8 
 9 data = bytes(parse.urlencode(dict), encoding='utf8')
10 req = request.Request(url=url, data=data, headers=headers, method='POST')
11 response = request.urlopen(req)
12 print(response.read().decode('utf-8')

  添加请求头的第种post方式, 好处是自己可以定义一个请求头字典,然后循环进行添加

 1 from urllib import request, parse
 2 
 3 url = 'http://httpbin.org/post'
 4 dict = {'name': 'Germey'}
 5 
 6 data = bytes(parse.urlencode(dict), encoding='utf8')
 7 req = request.Request(url=url, data=data, method='POST')
 8 req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')
 9 response = request.urlopen(req)
10 print(response.read().decode('utf-8'))

 4. rulllib.request.ProxyHandler( ) 方法。高级用法:各种handler代理

     rulllib.request.ProxyHandler( ) 方法设置代理

  urllib.request.build_opener(handler)  创建一个opener携带handler

  opener.open(req) 用opener发起请求

  设置代理,网站它会检测某一段时间某个IP 的访问次数,如果访问次数过多它会禁止访问,所以这个时候需要通过设置代理来爬取数据 

 1 import urllib.request,urllib.parse
 2 
 3 url = "https://www.baidu.com/s?wd=ip"
 4 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36'}
 5 
 6 req = urllib.request.Request(url=url,headers=headers) # 创建一个请求对象
 7 handler = urllib.request.ProxyHandler(                # 创建一个handler
 8         {"http":'122.241.88.79:15872'  
 9          "https":'122.241.88.79:15872'})  
10 
11 opener = urllib.request.build_opener(handler)  # 创建一个opener携带handler
12 res = opener.open(req)                         # 用opener发起请求
13 
14 with open("ip.html",'wb') as fp:
15     fp.write(res.read())            

会话处理机制

  cookie中保存中我们常见的登录信息,有时候爬取网站需要携带cookie信息访问,这里用到了http.cookijar,用于获取cookie以及存储cookie

  「采用handler+opener机制处理会话问题」导入cookie初始化工具,处理cookie的时候这个对象就可以存储cookie信息

1 from urllib import request,parse
2 from http import cookiejar
3 
4 cookie = cookiejar.CookieJar()             # 初始化一个cookie对象
5 handler = request.HTTPCookieProcessor(cookie)    # 创建一个handler对象,携带上cookie
6 opener = request.build_opener(handler)        # 创建一个opener对象携带上handler 
7 
8 response = opener.open('http://www.baidu.com')   # 用opener来发起请求
9 print(response.read().decode('utf-8'))           # 此时发起的请求结束以后,相关的cookie信息就会被opener的handler通过cookiejar对象保存

cookie写入到文件中保存

方式一: http.cookiejar.MozillaCookieJar( )方式

 1 import http.cookiejar, urllib.request
 2 
 3 filename = "cookie.txt"
 4 cookie = http.cookiejar.MozillaCookieJar(filename)
 5 
 6 handler = urllib.request.HTTPCookieProcessor(cookie)
 7 opener = urllib.request.build_opener(handler)
 8 response = opener.open('http://www.baidu.com')
 9 
10 cookie.save(ignore_discard=True, ignore_expires=True)

方式二: http.cookiejar.LWPCookieJar( )方式

 1 import http.cookiejar, urllib.request
 2 
 3 filename = 'cookie.txt'
 4 cookie = http.cookiejar.LWPCookieJar(filename)
 5 
 6 handler = urllib.request.HTTPCookieProcessor(cookie)
 7 opener = urllib.request.build_opener(handler)
 8 response = opener.open('http://www.baidu.com')
 9 
10 cookie.save(ignore_discard=True, ignore_expires=True)

cookie从文件中读取,用哪种方式写入的,就用哪种方式读取

方法三:cookie.load( )方式 

1 import http.cookiejar, urllib.request
2 
3 cookie = http.cookiejar.LWPCookieJar()
4 cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
5 
6 handler = urllib.request.HTTPCookieProcessor(cookie)
7 opener = urllib.request.build_opener(handler)
8 response = opener.open('http://www.baidu.com')
9 print(response.read().decode('utf-8'))


urllib.parse模块 

url解析模块

1. urlparse( ) 方法 拆分url

  URL解析函数侧重于将URL字符串拆分为其组件,或者将URL组件组合为URL字符串

  拆分的时候协议类型部分就会是scheme=“ ”指定的部分。如果url里面已经带了协议,scheme指定的协议不会生效

  urllib.parse.urlparse(urlstring, scheme=" ", allow_fragments=True)

  urlparse("www.baidu.com/index.html;user?id=5#comment",scheme="https")

1 from urllib.parse import urlparse
2 
3 # 对传入的url地址进行拆分; 可以用 scheme=“ ” 指定协议类型:
4 result = urlparse("http://www.baidu.com/index.html;user?id=5#comment")
5 print(result)  

  结果:

2. urlunparse( ) 方法  拼接url  功能和urlparse的功能相反,它是用于拼接 

1 from urllib.parse import urlunparse
2 
3 data = ['http','www.baidu.com','index.html','user','a=123','commit']
4 print(urlunparse(data))

3. urljoin( ) 方法  拼接url  拼接的时候后面的优先级高于前面的url

 1 from urllib.parse import urljoin
 2 
 3 print(urljoin('http://www.baidu.com', 'FAQ.html'))
 4 # 结果 :http://www.baidu.com/FAQ.html
 5 print(urljoin('http://www.baidu.com', 'https://pythonsite.com/FAQ.html'))
 6 # 结果 :https://pythonsite.com/FAQ.html
 7 print(urljoin('http://www.baidu.com/about.html', 'https://pythonsite.com/FAQ.html'))
 8 # 结果 :https://pythonsite.com/FAQ.html
 9 print(urljoin('http://www.baidu.com', '?category=2#comment'))
10 # 结果 :http://www.baidu.com?category=2#comment
11 print(urljoin('www.baidu.com#comment', '?category=2'))
12 # 结果 :www.baidu.com?category=2

 4. urlencode( ) 方法 

  这个方法可以将字典转换为url参数,对url进行编码,因为urllib这个框架中的url中不能出现汉字,只能出现ascii码字符

 1 from urllib import parse
 2 url = "https://www.baidu.com/s?"
 3 
 4 # 把参数写成字典的形式
 5 dic= {"ie":"utf-8","wd":"奔驰"}
 6 # 用parse的urlencode方法编码
 7 parames = parse.urlencode(dic)
 8 # 将编码以后的参数拼接到url中
 9 url += parames
10 print(request.urlopen(url=url))

urllib.error模块 方法

  有时候通过程序访问页面的时候,有的页面可能会出现类似404,500等错误。这时就需要我们捕捉异常,

  在urllb异常中有两个异常错误:URLErrorHTTPError。 HTTPError 是 URLError 的子类

1. error.URLError 异常  URLError里只有一个属性:reason,即抓异常的时候只能打印错误信息

1 from urllib import request,error
2 
3 try:
4     response = request.urlopen("http://pythonsite.com/1111.html")
5 except error.URLError as e:
6     print(e.reason)

2. error.HTTPError 异常  HTTPError里有三个属性:code,reason,headers,即抓异常的时候可以获得code,reson,headers三个信息

 1 from urllib import request,error
 2 try:
 3     response = request.urlopen("http://pythonsite.com/1111.html")
 4 except error.HTTPError as e:
 5     print(e.code)
 6     print(e.reason)
 7     print(e.headers)
 8 except error.URLError as e:
 9     print(e.reason)
10 else:
11     print("reqeust successfully")

 

posted @ 2019-05-08 20:38  Tom's  阅读(553)  评论(0编辑  收藏  举报