【崔庆才-python爬虫与项目实战】urllib介绍 01

希望一起沟通,韩梅梅和李雷和你一起学习。

关于urllib库的使用

urllib库是python内置的HTTP请求库,也就是说我们是不需要进行安装的。
其中urllib包括以下四个模块
1. request:用以模拟发送请求,就像我们浏览器的输入框,其中可以加入一些额外参数用以模拟浏览器
2.error
3.parse
4.robotparser

request 发送请求

urlopen()

urllib.request()可以实现最基本的HTTP访问。
下面以一个实例爬取python官网进行展示
import urllib.request
response = urllib.request.urlopen('http://www.python.org')
print(response.read().decode('utf-8'))

可以看到python程序已经成功获取了网页源代码,但是发现在获取的response中的类型需要通过
response.read().decode(‘utf-8’)
才能进行展示,检查一下response的数据类型为

type(response)
http.client.HTTPResponse

发现response的数据类型为http.client.HTTPResponse
该类型的对象主要有read() readinto() getheader(name) getheaders() fileno() 等方法
以及msg/version/status/reason/debuglecel/closed等属性

如 通过response.read()方法可以获取读取结果,通过response.status属性可以获取response的状态

response.status
200

目前status属性为200,即是联通状态
可以对其他方式进行调用测试

print(response.getheaders())
[('Connection', 'close'), ('Content-Length', '50897'), ('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), ('Via', '1.1 vegur, 1.1 varnish, 1.1 varnish'), ('Accept-Ranges', 'bytes'), ('Date', 'Fri, 05 Mar 2021 11:22:01 GMT'), ('Age', '1919'), ('X-Served-By', 'cache-bwi5125-BWI, cache-hnd18721-HND'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '1, 3182'), ('X-Timer', 'S1614943322.979393,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]
print(response.getheader('Content-length'))
50897

我觉得我有必要区别以下getheader()和getheaders():
所以很明显的是,getheaders()方法用于输出全部的响应头的信息,而getheader(name) 则对应的输出响应值

urlopen()还有许多的参数,首先看一下urlopen的API

urllib.request.urlopen(
url,
data=None,
timeout=<object object at 0x000001F385D1F160>,
*,
cafile=None,
capath=None,
cadefault=False,
context=None,
)
下面分别从不同参数理解整个函数

  • data

下面通过一个实例来介绍data的用法
这里urlopen()方法中,data的类型必须是byte类型,所以输入的字典{'word':'hello'},必须通过bytes()方法转换成byte类型,而bytes()方法只接受string类型,通过urllib.parse.urlencode()方法将字典转换成string,再转换成byte类型
这里我用的是jupyter lab,所以在后面response.read().decode(‘utf-8’)让换行符消失

import urllib.parse
import urllib.request

data = bytes(urllib.parse.urlencode({'word':'hello'}),encoding='utf-8')
response = urllib.request.urlopen('http://httpbin.org/post',data=data)
print(response.read().decode('utf-8'))
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "word": "hello"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "10", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/3.7", 
    "X-Amzn-Trace-Id": "Root=1-60423d57-04ac587026fe33de2ccee34f"
  }, 
  "json": null, 
  "origin": "183.246.30.52", 
  "url": "http://httpbin.org/post"
}

form中,出现了输入的字典,则表示url的请求方式为post方式,这里简单介绍一下post方式和get方式的差异:

  1. 在安全性方面
    • get方式会让信息暴露在url中,可能导致密码泄露
    • post方式以表单的形式上传,能更好地保护信息安全
  2. 在传输数据量方面
    • get请求提交最多只有1024个字节
    • post请求无限制
  • timeout

timeout参数用于设置限定时间,即在限定的时间内如果没有获得服务器响应即报错。
通过下面的实例进行演示

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:
# print(response.read().decode('utf-8'))
    if isinstance(e.reason,socket.timeout):
        print('TIME OUT')
        
TIME OUT

由于时间超时,输出的错误类型是URLerror是属于urllib.error类型,所以导入相关库进行抓取错误。
timeout 类型错误是属于超市错误属于socket类型的错误

request类

介绍以下request的API内容
urllib.request.Request(
url,
data=None,
headers={},
origin_req_host=None,
unverifiable=False,
method=None,
)

  1. 其中url是必选参数,其他都是可选参数
  2. data必须传bytes类型
  3. headers传入的内容是字典,作为请求头,可通过修改User-Agent伪装浏览器
  4. origin_req_host是指请求方的host地址或IP地址
  5. unverifiable表示的是这个请求是否是无法验证的??
  6. method传入的书请求方法,有get和post两种

以下通过一个实例来展示request类

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'
}
# 构造输入的表单数据
dic ={
    'name':'Atu'
}
# 构造data数据
data = bytes(parse.urlencode(dic),encoding='utf-8')
# 构造了request类,即是一个伪装后的url
req = request.Request(
    url=url,
    data=None,
    headers=headers,
    origin_req_host=None,
    unverifiable=False,
    method='POST'
)
response = request.urlopen(req)
print(response.read().decode('utf-8'))

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "0", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/4.0(compatible; MSIE 5.5; Windows NT)", 
    "X-Amzn-Trace-Id": "Root=1-60430595-3161f57a0ee7913f60b742a4"
  }, 
  "json": null, 
  "origin": "223.104.247.132", 
  "url": "http://httpbin.org/post"
}

高级用法

对于更加高级的如cookie处理,代理设置等,我们可以选择强大的handler工具。
首先介绍urllib.request模块里面的BaseHandler父类,各个子类都继承了BaseHandler的属性:

  • HTTPDefaultErrorHandler: 用于处理HTTP相应错误,抛出的HTTPError错误
  • HTTPRedirectHandler:处于处理重定向[mark,重定向是指什么]
  • HTTPCookieProcessor:用于处理Cookies
    还有其他handler类可以参考官方文档

另一个比较重要的类是OpenerDirector,我们称之为Opener,前面使用的urlopen()方法实际上就是一个urllib配置好的opener,为了实现更加高级的方法,这里使用Opener进行底层配置:
下面通过实例来检验相关用法:

  • 验证
from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError

username = 'username'
password = 'password'

url='http://localhost:5000/'

p =  HTTPPasswordMgrWithDefaultRealm()
p.add_password(None,url,username,password)
auth_handler =HTTPBasicAuthHandler(p)  # auth_handler是由HTTPBasicAtuthHandler实例化的Handler对象,其输入额参数为 HTTPPasswordMgrWithDefaultRealm对象
opener = build_opener(auth_handler)

try:
    result = opener.open(url)  #使用open打开的对象就是需要的结果
    html = result.read().decode('utf-8')
    print(html)
except URLError as e:
    print(e.reason)
[WinError 10061] 由于目标计算机积极拒绝,无法连接。
  • 代理
    做爬虫时间,大多数时候为了隐藏自身的真实ip都会选择代理,以以下实例进行展示:
    proxyHandler是用来做代理类,其参数是字典
from urllib.error import URLError
from urllib.request import ProxyHandler,build_opener

proxy_handler = ProxyHandler({
    'http':'http://127.0.0.1:9743',
    'http':'http://127.0.0.1:9743'
})
opener = build_opener(proxy_handler)
try:
    response = opener.open('https://www.baidu.com')
    print(response.read().decode('utf-8'))
except URLError as e:
    print(e.reason)
<html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
  • Cookie
    下面通过实例介绍,保存cookie的Handler
  1. 声明CookieJar对象,把CookieJar对象进行实例化
  2. 使用HTTPCookieProcessor构建handler,其输入的参数为CookieJar
  3. 利用build_opener构建出Opener
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=9871F8DE5C415A182773408756D8CCB7:FG=1
BIDUPSID=9871F8DE5C415A1867D1295E303CB06F
H_PS_PSSID=33517_33637_33261_33273_31660_33594_33605_33590_26350_22158
PSTM=1615017612
BDSVRTM=0
BD_HOME=1

考虑将Cookie内容本地保存,可以使用MozillaCookieJar方法.
保存文件的时候应当保存cookie文件,cookie文件的格式是[http.cookiejar.MozillaCookieJar],而response的格式是[http.client.HTTPResponse],

filename='cookie.txt'
cookie = http.cookiejar.MozillaCookieJar(filename=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)

也可以采用LWPCookieJar的格式保存,即声明:
cookie = http.cookiejar.LWPCookieJar(),生成了文件格式有所不同

在看一下怎么读取文件中的Cookie

cookie = http.cookiejar.MozillaCookieJar()
cookie.load(filename="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')

以上代码可以输出百度首页的源代码,urllib的request用法到这里介绍为止,其他内容可以参考官网文档,然后后面继续是urllib的其他问题

已标记关键词 清除标记
相关推荐
<p> <b><span style="background-color:#FFE500;">【超实用课程内容】</span></b> </p> <p> <br /> </p> <p> <br /> </p> <p> 本课程内容包含讲解<span>解读Nginx的基础知识,</span><span>解读Nginx的核心知识、带领学员进行</span>高并发环境下的Nginx性能优化实战,让学生能够快速将所学融合到企业应用中。 </p> <p> <br /> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><br /> </b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><span style="background-color:#FFE500;">【课程如何观看?】</span></b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"><span id="__kindeditor_bookmark_start_21__"></span></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程永久有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <strong><span style="background-color:#FFE500;">【学员专享增值服务】</span></strong> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b>源码开放</b> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a>,播放页面右侧点击课件进行资料打包下载 </p> <p> <br /> </p> <p> <br /> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页