urlib库为python3的HTTP内置请求库

urilib的四个模块:

  • urllib.request:用于获取网页的响应内容

  • urllib.error:异常处理模块,用于处理异常的模块

  • urllib.parse:用于解析url

  • urllib.robotparse:用于解析robots.txt,主要用于看哪些网站不能进行爬取,不过少用

1.  urllib.request

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

  • url:为请求网址

  • data:请求时需要发送的参数

  • timeout:超时设置,在该时间范围内返回请求内容就不会报错

from urllib import request
# 请求获取网页返回内容
response = request.urlopen('https://movie.douban.com/')
# 获取网页返回内容
print(response.read().decode('utf-8'))
# 获取状态码
print(response.status)
# 获取请求头
print(response.getheaders())

  

# 对请求头进行遍历
for k, v in response.getheaders():
print(k, '=', v) 

可以使用上面的代码对一些网站进行请求了,但是当需要一些反爬网站时,这就不行了,这时我们需要适当地增加请求头进行请求,这时就需要使用复杂一点的代码了,这时我们需要用到Request对象

# 请求头
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'}
requests = request.Request('https://movie.douban.com/', headers=headers) # 加入自己的请求头更加接近浏览器
# 进行请求,把Request对象传入urlopen参数中
response = request.urlopen(requests)
print(response.read().decode('utf-8'))

  

这个我添加了请求头进行请求,使我发送的请求更加接近浏览器的行为。可以对应一些反爬网站了。如果网站需要进行登陆,这时需要用到post方法,用上面的也是可以的。

from urllib import request, parse
# 使用post方法来进行模拟登陆豆瓣
data = {'source': 'None',
'redir': 'https://www.douban.com/',
'form_email': '*****@qq.com',
'form_password': '***',
'remember': 'on',
'login': '登录'}
# 将data的字典类型转换为get请求方式
data=bytes(parse.urlencode(data),encoding='utf-8')
requests = request.Request('https://accounts.douban.com/login', headers=headers, data=data, method='POST')
response = request.urlopen(requests)
print(response.read().decode('utf-8'))

  

这里我用到了data的参数把登陆需要的参数传进去,还加了个请求方法Method

parse.urlencode()后面有讲

这里还有另外一种添加请求头的方法

Request.add_header(): 参数有两个,分别为请求头对应的键和值,这种方法一次只能添加一个请求头,添加多个需要用到循环或者直接用前面的方法添加多个请求头

在登陆了网站之后,我们需要用到cookie来保存登陆信息,这时就需要获取cookie了。urllib获取cookie比较麻烦

from http import cookiejar
# 获取cookie
cookie = cookiejar.CookieJar()
# 获取助手把cookie传进去
handler = request.HTTPCookieProcessor(cookie)
# 获取opener进行请求网站
opener = request.build_opener(handler)
# 请求网页
response = opener.open('https://movie.douban.com/')
# 打印cookie
for c in cookie:
print(c.name, '=', c.value)

  单纯地打印没什么用,我们需要把他存入文件来保存,下次使用时再次加载cookie来登陆

保存cookie为文件:

from http import cookiejar
#将cookie保存在文件中
filename='cookie.txt'
cookie=cookiejar.MozillaCookieJar(filename)#表示使用Mozilla的cookie方式存储和读取
handler=request.HTTPCookieProcessor(cookie)
opener=request.build_opener(handler)
opener.open('https://movie.douban.com/')
#保存文件
cookie.save(ignore_discard=True,ignore_expires=True)

另一种保存方法:

from http import cookiejar
cookie=cookiejar.LWPCookieJar(filename)#表示Set-Cookie3文件格式存储和读取
handler=request.HTTPCookieProcessor(cookie)
opener=request.build_opener(handler)
opener.open('https://movie.douban.com/')
#保存文件
cookie.save(ignore_discard=True,ignore_expires=True)

这两种保存格式都是不一样的,需要保存的内容一样。

保存可以了,这时就需要用到加载了,当然也可以。代码如下:

from http import cookiejar
# 从cookie文件加载到网页上实现记住登陆
cookie = cookiejar.LWPCookieJar()
# 加载文件
cookie.load(filename, ignore_discard=True, ignore_expires=True)
handler = request.HTTPCookieProcessor(cookie)
opener = request.build_opener(handler)
opener.open('https://movie.douban.com/')

这样就可以实现不用密码进行登陆了。

cookie小总结:在操作cookie时,都是分五步,如下:

  1. 进行导包,至关重要的一步,不导包直接出错。

  2. 获取cookie处理对象,使用cookiejar包

  3. 创建cookie处理器,使用request.HTTPCookieJarProcessor()

  4. 利用cookie处理器构建opener,使用request.build_opener()

  5. 进行请求网站,用opener.open(),这个不能用request.urlopen()

如果有时你在同一ip连续多次发送请求,会有被封ip的可能,这时我们还需要用到代理ip进行爬取,代码如下:

proxy = request.ProxyHandler({'https': 'https://106.60.34.111:80'})
opener = request.build_opener(proxy)
opener.open('https://movie.douban.com/',timeout=1)

  

2. urllib.error

将上面的使用代理ip的请求进行异常处理,如下:

from urllib import request, error
try:
proxy = request.ProxyHandler({
'https': 'https://106.60.34.111:80'
})
opener = request.build_opener(proxy)
opener.open('https://movie.douban.com/', timeout=1)
except error.HTTPError as e:
print(e.reason(), e.code(), e.headers())
except error.URLError as e:
print(e.reason)

因为有时这个ip或许也被封了,有可能会抛出异常,所以我们为了让程序运行下去进而进行捕捉程序

  • error.URLError: 这个是url的一些问题,这个异常只有一个reason属性

  • error.HTTPError:这个是error.URLError的子类,所以在与上面的混合使用时需要将这个异常放到前面,这个异常是一些请求错误,有三个方法,.reason(), .code(), .headers(),所以在捕捉异常时通常先使用这个

3. urllib.parse

解析url:urllib.parse.urlparse(url, scheme='', allow_fragments=True)

简单的使用:

from urllib import request, parse
# 解析url
print(parse.urlparse('https://movie.douban.com/'))
print(parse.urlparse('https://movie.douban.com/', scheme='http'))
print(parse.urlparse('movie.douban.com/', scheme='http'))
#结果
#ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='')
#ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='')
#ParseResult(scheme='http', netloc='', path='movie.douban.com/', params='', query='', fragment='')

可以看出加了scheme参数和没加的返回结果是有区别的。而当scheme协议加了,而前面的url也包含协议,一般会忽略后面的scheme参数

既然有解析url,那当然也有反解析url,就是把元素串连成一个url

from urllib import parse
# 将列表元素拼接成url
url = ['http', 'www', 'baidu', 'com', 'dfdf', 'eddffa'] # 这里至少需要6个元素(我乱写的,请忽视)
print(parse.urlunparse(url))
# 下面是结果
# http://www/baidu;com?dfdf#eddffa

 urlparse()接收一个列表的参数,而且列表的长度是有要求的,是必须六个参数以上,要不会抛出异常 

1Traceback (most recent call last):
2 File "E:/anaconda/python_project/python3_spider/urllib_test.py", line 107, in <module>
3 print(parse.urlunparse(url))
4 File "E:\anaconda\lib\urllib\parse.py", line 454, in urlunparse
5 _coerce_args(*components))
6ValueError: not enough values to unpack (expected 7, got 6)

  urllib.parse.urljoin():这个是将第二个参数的url缺少的部分用第一个参数的url补齐

# 连接两个参数的url, 将第二个参数中缺的部分用第一个参数的补齐
print(parse.urljoin('https://movie.douban.com/', 'index'))
print(parse.urljoin('https://movie.douban.com/','https://accounts.douban.com/login'))
# 下面是结果
#https://movie.douban.com/index
#https://accounts.douban.com/login

  urllib.parse.urlencode():这个方法是将字典类型的参数转为请求为get方式的字符串

data = {'name': 'sergiojuue', 'sex': 'boy'}
data = parse.urlencode(data)
print('https://accounts.douban.com/login'+data)
# 下面是结果
#https://accounts.douban.com/loginname=sergiojuue&sex=boy

  4. 结语

还有个urllib.robotparse库少用,就不说了,留给以后需要再去查文档吧。

上面的只是我在学习过程中的总结,如果有什么错误的话,欢迎在留言区指出,还有就是需要查看更多用法的请查看文档https://docs.python.org/3/library/urllib.html

学习过程中看的大多是崔庆才大佬的视频:https://edu.hellobi.com/course/157

感谢!:https://mp.weixin.qq.com/s?__biz=MzI5NDY1MjQzNA==&mid=2247485940&idx=1&sn=3fabf8c9bb52395675cd71db65cc9109&chksm=ec5ed689db295f9f01f9eb56b95a25fe8221e516969a7ec30794e41fd51fbe582add5002decd&mpshare=1&scene=1&srcid=0329HJXcKhalaWwriIvQ95r7&pass_ticket=jt1ntJmxsOysHtvsCD6R975Ofkvtsc8maZ4Fep%2FuRAov9uL%2Fo%2BMRdbYALU2UxCY0#rd

最新文章

  1. VisualStudio自动编码插件(Autocode——devprojects.net)
  2. asp.net4.0在Global中的Application_Start 中直接或间接使用 HttpUtility.UrlEncode等出现异常Response is not available in this context的解决方法
  3. 线性代数和numpy——黑板客老师课程学习
  4. Ubuntu下基于Nginx实现Tomcat集群负载均衡
  5. android 实现桌面显示内容
  6. Java读取图片并修改像素,创建图片
  7. js的MVC结构设计
  8. 使用线程 在shell上同步动态显示当前系统时间
  9. cocoa编程第4版 8.5 挑战1 解答
  10. 金山WPS一面
  11. linux kettle
  12. javascript中数组总结
  13. .NET并行计算和并发3.2-多线程调用Invoke
  14. [zz]LyX 入门教程
  15. Remote error: VAR and OUT arguments must match parameter type exactly&#39;
  16. 运行msckf_vio
  17. Mac svn使用学习-4-客户端cli命令详解
  18. 【Ubuntu】Ubuntu网络配置DNS失效问题处理
  19. X-Requested-With导致CSRF失败
  20. arcTo

热门文章

  1. C#基础:对委托的简单理解
  2. 7 二分搜索树的原理与Java源码实现
  3. Warning: The Copy Bundle Resources build phase contains
  4. Git之设置对文件名大小写敏感
  5. 第一次运行PHP项目(phpstorm+wampserver)
  6. 3.Python自我修炼(升仙中....整数,布尔值,字符串,for循环)
  7. Hexo搭建博客教程(2) - 博客的简单个性化配置
  8. pycharm 中切换虚拟环境
  9. PHP之session
  10. AKOJ-1695-找素数