Python常用库urllib中urllib.request模块使用详解

 1.urllib2和urllib库的区别     

     Urllib库是Python中的一个功能强大、用于操作URL,并在做爬虫的时候经常要用到的库。在Python2.x中,分为Urllib库和Urllin2库,Python3.x之后都合并到Urllib库中了。实际开发中,用Requests多余urllib.

   这里介绍使用的python3中的urllib库包括以下模块

  1. urllib.request 请求模块
  2. urllib.error 异常处理模块
  3. urllib.parse url解析模块
  4. urllib.robotparser robots.txt   解析模块

    urllib和urllib2库中模块的主要变化有:

  1. 在Pytho2.x中使用import urllib2=====>在Python3.x中会使用import urllib.request,urllib.error。
  2. 在Pytho2.x中使用import urllib=====>在Python3.x中会使用import urllib.request,urllib.error,urllib.parse。
  3. 在Pytho2.x中使用import urlparse=====>在Python3.x中会使用import urllib.parse。
  4. 在Pytho2.x中使用import urlopen=====>在Python3.x中会使用import urllib.request.urlopen。
  5. 在Pytho2.x中使用import urlencode=====>在Python3.x中会使用import urllib.parse.urlencode。
  6. 在Pytho2.x中使用import urllib.quote=====>在Python3.x中会使用import urllib.request.quote。
  7. 在Pytho2.x中使用cookielib.CookieJa=====>在Python3.x中会使用http.CookieJar。
  8. 在Pytho2.x中使用urllib2.Request——-对应的,在Python3.x中会使用urllib.request.Request。

2. python3中的urllib的使用详解

     学习的官方文档地址:urllib的官网学习文档地址

3.urllib.request 请求模块的使用详解

 3.1 urllib.request.urlopen的用法

    urlopen使用格式与参数解释:

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

  1.urlopen()只有一个参数url

import urllib.request

response = urllib.request.urlopen('http://www.baidu.com')
print(response.read().decode('utf-8'))
注意如果在pycharm非命令行模式直接用print(response.read())即可。

使用response对象的read()方法读取网页内容,然后打印出来,因为读取的网页内容字节流,所以要打印时要转成utf-8格式
读取内容常见的有3种方式,其用法是: 
1. read()读取文件的全部内容,与readlines()不同的是,read()会把读取到的内容赋给一个字符串变量。 
2. readlines()读取文件的全部内容,readlines()会把读取到的内容赋值给一个列表变量。 
3. readline()读取文件的一行内容。
--------------------- 

1.这是时候可以将爬取的网页内容保存到本地
#注意这里response对象的内容只能读取一次,使用一次read(),再次read()是空值,跟一般文件读取一样。

'''方法1:将爬取的网页内容存储到本地
f = open('./a.html','wb')
f.write(t)
f.close()'''

#方法2:保存为html文件,可以直接使用浏览器打开验证。
with open('./b.html','wb') as f:
    f.write(t)
    f.close()

2.可以指定显示爬取的网页中部分信息
print(response.info())
print(response.geturl())
print(response.getcode())

 如上:可以看出,urlopen中的参数除了请求网页url是必须的,其余都是可选择的参数,同样如下:

from urllib import request

with request.urlopen('https://baidu.com') as f:
    data = f.read()  #读取响应的数据
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():  #遍历打印响应头数据,json格式,跟浏览器格式一样
        print('%s: %s' % (k, v))
    print('Data:', data)  #如果在交互模式下,需要是用decode()进行转换

'''程序运行结果如下:
Status: 200 OK
Date: Thu, 20 Dec 2018 08:10:48 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: Close
Vary: Accept-Encoding
Set-Cookie: BAIDUID=348DA5244A4C87E823EE2DC9D5659A14:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=348DA5244A4C87E823EE2DC9D5659A14; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1545293448; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: delPer=0; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=26525_1423_21078_18560_28132_26350_27750_28140; path=/; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Cxy_all: baidu+02d0ae63f27832db9f1ff400b8273995
Cache-Control: private
Expires: Thu, 20 Dec 2018 08:10:40 GMT
Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
BDPAGETYPE: 1
BDQID: 0x8b38ae5c0005a450
Data: b'\n\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n        \r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\t\t    \r\n\r\n\t\r\n        \r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\t\t    \r\n\r\n\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    \n    \n    \n\t\n    \n    \n    \n    \n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n    \n    \xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b\xef\xbc\x8c\xe4\xbd\xa0\xe5\xb0\xb1\xe7\x9f\xa5\xe9\x81\x93\n    \n\n\n\n\n\n\n\n\n\n    \n\n\n\n\n    \n\n\n\n\t\n    \n    
\n \n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\r\n\n\n\r\n' '''

2.urlopen的参数timeout

#设置超时时间为1s.
import urllib.request
response = urllib.request.urlopen('http://httpbin.org/get', timeout=1)
print(response.read())

#超时异常处理,设置超时0.1s
import socket
import urllib.request
import urllib.error

try:
    response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
except urllib.error.URLError as e:
    if isinstance(e.reason, socket.timeout):
        print('TIME OUT') #结果是TIME OUT

3.urlopen中data参数的使用

import urllib.parse
import urllib.request

data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
response = urllib.request.urlopen('http://httpbin.org/post', data=data)
print(response.read())

3.2urllib.request请求模块中关于响应的使用

1.响应类型

import urllib.request
import  os

response = urllib.request.urlopen('http://www.baidu.com',timeout=1)
print(type(response)) 
'''
正常结果: 
如果超时,则报错,需要捕捉异常urllib.error.URLError: 

2.状态码、响应头

import urllib.request
import  os

response = urllib.request.urlopen('http://www.baidu.com',timeout=1)

print(response.status)  #响应状态,200正常。
print(response.getheaders())  #响应头
print(response.getheader('Server'))
'''结果如下:
200
[('Server', 'styx'), ('Date', 'Wed, 19 Dec 2018 13:57:19 GMT'), ('Content-Type', 'text/html; charset=UTF-8'), ('Transfer-Encoding', 'chunked'), ('Connection', 'close'), ('Vary', 'Accept-Encoding'), ('Expires', 'Wed, 19 Dec 2018 13:56:33 GMT'), ('Last-Modified', 'Wed, 19 Dec 2018 13:56:33 GMT'), ('Pragma', 'Pragma'), ('Cache-Control', 'max-age=300'), ('X-Cache', 'Suning-HIT_94'), ('X-Cache-Hits', '7'), ('Age', '0'), ('Via', '1.1 Xcache_baidu_94')]
styx

'''

3.3 urlopen.request.Request

  Request就是为了模拟浏览器发送GET请求,通过往Request对象添加HTTP头,我们就可以把请求伪装成浏览器,最终还是通过urlopen()进行发送请求。

1.如下代码演示Request发送get请求

from urllib import request

#封装一个请求,给请求添加一个请求头,伪装成iphone手机访问淘宝,返回的淘宝界面就是手机版的

req = request.Request('http://www.taobao.com/')
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
response = request.urlopen(req)
with open("./taobao.html",'wb')  as f1:
    f1.write(response.read())
    f1.close()

'''或者直接将网页内容打印出来,发现返回的是淘宝触屏版,适应iphone尺寸。
with request.urlopen(req) as f:
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    print('Data:', f.read().decode('utf-8'))
'''

2.Request发送post请求

from urllib import request, parse

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

'''测试结果如下:
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "name": "Germey"
  },
  "headers": {
    "Accept-Encoding": "identity",
    "Connection": "close",
    "Content-Length": "11",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"
  },
  "json": null,
  "origin": "180.111.83.197",
  "url": "http://httpbin.org/post"
}
'''
-------------------------------------------------------------------------
2.发送post请求方式2.这种添加方式有个好处是自己可以定义一个请求头字典,然后循环进行添加
from urllib import request, parse

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

3.4Hander的使用

有很多网站为了防止程序爬虫爬网站造成网站瘫痪,会需要携带一些headers头部信息才能访问,最长见的有user-agent参数等参数,演示如下:

1.添加普通Hander

1.如下是对python官网的请求访问,什么参数也不带
import urllib.request

request = urllib.request.Request('https://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

2.对上面的请求添加伪装请求头
from urllib import request, parse

url = 'http://httpbin.org/post'
headers = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
    'Host': 'httpbin.org'
}
dict = {
    'name': 'zhaofan'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

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

import urllib.request

proxy_handler = urllib.request.ProxyHandler({
    'http': 'http://127.0.0.1:9743',
    'https': 'https://127.0.0.1:9743'
})
opener = urllib.request.build_opener(proxy_handler)
response = opener.open('http://httpbin.org/get')
print(response.read())

3.5cookie,HTTPCookiProcessor的使用

3.51获取与保存cookie

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

import http.cookiejar, urllib.request
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
for item in cookie:
    print(item.name+"="+item.value)

'''测试结果如下:
BAIDUID=9B2F476BF55C3D00E14C6487B27DCAF9:FG=1
BIDUPSID=9B2F476BF55C3D00E14C6487B27DCAF9
H_PS_PSSID=1443_21098_28132_26350_27750_28140_22159
PSTM=1545493654
delPer=0
BDSVRTM=0
BD_HOME=0
'''

同时cookie可以写入到文本文件中保存,有两种方式http.cookiejar.MozillaCookieJar和http.cookiejar.LWPCookieJar(),当然你自己用哪种方式都可以。比如:http.cookiejar.MozillaCookieJar()方式和http.cookiejar.LWPCookieJar()方式分别演示将cookie保存为文本文件cookie.txt:

1.使用http.cookiejar.MozillaCookieJar()方式
import http.cookiejar, urllib.request
filename = "cookie.txt"
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

2.http.cookiejar.LWPCookieJar()方式
import http.cookiejar, urllib.request
filename = 'cookie.txt'
cookie = http.cookiejar.LWPCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

3.52加载使用已经存在的cookie文件

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

统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。

你可能感兴趣的:(python编程与爬虫开发系列,Python人工智能开发系列)