Urllib库是Python中的一个功能强大、用于操作URL,并在做爬虫的时候经常要用到的库。在Python2.x中,分为Urllib库和Urllin2库,Python3.x之后都合并到Urllib库中了。实际开发中,用Requests多余urllib.
这里介绍使用的python3中的urllib库包括以下模块
urllib和urllib2库中模块的主要变化有:
学习的官方文档地址:urllib的官网学习文档地址
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())
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
'''
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'))
有很多网站为了防止程序爬虫爬网站造成网站瘫痪,会需要携带一些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.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'))
统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。