小白学 Python 爬虫(14):urllib 基础使用(四)

人生苦短,我用 Python
前文传送门:
小白学 Python 爬虫(2):前置准备(一)基本类库的安装
小白学 Python 爬虫(3):前置准备(二)Linux基础入门
小白学 Python 爬虫(4):前置准备(三)Docker基础入门
小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装
小白学 Python 爬虫(10):Session 和 Cookies
小白学 Python 爬虫(11):urllib 基础使用(一)
小白学 Python 爬虫(12):urllib 基础使用(二)
小白学 Python 爬虫(13):urllib 基础使用(三)
Parse 模块
官方文档:https://docs.python.org/zh-cn/3.7/library/urllib.parse.html
前面我们介绍了 urllib 的 Request 模块和 Error 模块,本篇我们接着介绍 Parse 模块。
先看一下官方文档的解释吧:
This module defines a standard interface to break Uniform Resource Locator (URL) strings up in components (addressing scheme, network location, path etc.), to combine the components back into a URL string, and to convert a "relative URL" to an absolute URL given a "base URL."
The module has been designed to match the Internet RFC on Relative Uniform Resource Locators. It supports the following URL schemes: file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss.
The urllib.parse module defines functions that fall into two broad categories: URL parsing and URL quoting.
大意是该模块定义了一个处理 URL 的标准接口,主要用于分解 URL 字符串为组件和将组件组合回 URL 字符串,并且可以将相对 URL 转换为绝对 URL 。
它支持的 URL 协议有:file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss。
urllib.parse 模块定义的函数分为两大类:URL 解析和 URL 引用。
URL 解析
urlparse()
先看最常用的一个方法 urlparse() ,该方法主要用于识别 URL 和将其分段,再来看下 urlparse 对于一个 URL 的定义:
scheme://netloc/path;parameters?query#fragment
可以看到, urlparse() 将一个 URL 拆解成为 6 个部分,分别是 scheme 、 netloc 、 path 、 params 、 query 和 fragment 。
大体上可以看出来,解析时是会有特定的分隔符的。
- scheme:位于
://前面,代表了当前的协议。 - netloc:位于第一个
/之前,代表了域名。 - path:位于第一个
/和;之间,代表了访问路径。 - parameters:位于
;和?之间,代表了路径元素的参数。 - query:位于
?和#之间,代表了查询组件。 - fragment:位于
#之后,代表了片段识别。
一个标准的 URL 应该是由以上部分组成,但是实际上,我们现在看到的大部分的 URL 并不会在链接中包含 ; 。
看个小例子吧,随便在官方文档上找了个连接,我们使用 urlparse() 将它解析一下看下结果:
from urllib.parse import urlparse
result = urlparse('https://docs.python.org/zh-cn/3.7/library/urllib.parse.html#module-urllib.parse')
print(type(result))
print(result)
执行结果:
<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='docs.python.org', path='/zh-cn/3.7/library/urllib.parse.html', params='', query='', fragment='module-urllib.parse')
可以看到, urlparse() 返回的数据类型是 urllib.parse.ParseResult 对象,它实际上是一个元组数据类型,而这个元组则包含了我们上面介绍的那些组件元素。
如果我们想要获取这个链接中的某个值怎么获取呢?比如说我们想获取当前这个链接的域名信息:
print(result.netloc)
结果如下:
docs.python.org
我们可以直接通过这个 urllib.parse.ParseResult 对应的属性将它取出来,而 urlparse() 甚至为我们提供了索引的方式来进行取值,对应关系如下表(以下内容来自官方文档):
| 属性 | 索引 | 描述 | 值(如果不存在) |
|---|---|---|---|
| scheme | 0 | URL 方案说明符 | scheme parameter |
| netloc | 1 | 域名 | 空字符串 |
| path | 2 | 分层路径 | 空字符串 |
| params | 3 | 最后路径元素的参数 | 空字符串 |
| query | 4 | 查询组件 | 空字符串 |
| fragment | 5 | 片段识别 | 空字符串 |
我们再通过索引的方式获取一下刚才我们想获取的域名信息:
print(result[1])
结果如下:
docs.python.org
获取成功。
我们再来看一下 urlparse() 的语法:
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
- urlstring:这是必填项,即待解析的URL。
- scheme:它是默认的协议(比如 http 或 https 等)。假如这个链接没有带协议信息,会将这个作为默认的协议。
- allow_fragments:即是否忽略 fragment 。如果它被设置为 False , fragment 部分就会被忽略,它会被解析为 path 、 parameters 或者 query 的一部分,而 fragment 部分为空。
我们再来写一个示例,连接还是使用刚才上面的链接,我们在这个示例中去掉链接中的 scheme 信息,在参数中指定 scheme 信息,并且将 allow_fragments 设置为 False ,看下片段识别将会被解析成哪一部分:
from urllib.parse import urlparse
result1 = urlparse('docs.python.org/zh-cn/3.7/library/urllib.parse.html#module-urllib.parse', scheme = "https", allow_fragments = False)
print(result1)
运行结果如下:
ParseResult(scheme='https', netloc='', path='docs.python.org/zh-cn/3.7/library/urllib.parse.html#module-urllib.parse', params='', query='', fragment='')
可以从结果中看出, scheme 信息是可以正常识别出来的,而片段识别信息则被解析成为了 path 的一部分。
urlunparse()
有了解析链接的 urlparse() ,那么一定会存在构建链接的 urlunparse() 。
这个方法它接受的参数是一个可迭代对象,但是它的长度必须是 6 ,否则会抛出参数数量不足或者过多的问题。
我们还是通过一个示例了解一下:
from urllib.parse import urlparse, urlunparse
params = ('https', 'www.geekdigging.com', 'index.html', 'people', 'a=1', 'geekdigging')
print(urlunparse(params))
这里的参数使用的数据类型是元组,当然也可以选择其他的可迭代的数据类型,例如列表或者特定的数据结构等等。
运行结果如下:
https://www.geekdigging.com/index.html;people?a=1#geekdigging
这样我们就简单的实现了 URL 的构造,如果其中某些参数在构建的时候不存在,切记不可直接不写,留空字符串即可,如下:
params = ('https', 'www.geekdigging.com', 'index.html', '', '', 'geekdigging')
urlsplit()
urlsplit() 这个方法和 urlparse() 非常像,唯一的区别就是 urlsplit() 不再单独解析 params 这个组件,只会返回 5 个组件的结果,它将 params 合并到了 path 中。还是看一个示例:
from urllib.parse import urlsplit
result_urlsplit = urlsplit("https://www.geekdigging.com/index.html;people?a=1#geekdigging")
print(type(result_urlsplit))
print(result_urlsplit)
结果如下:
<class 'urllib.parse.SplitResult'>
SplitResult(scheme='https', netloc='www.geekdigging.com', path='/index.html;people', query='a=1', fragment='geekdigging')
可以发现,返回结果是 urllib.parse.SplitResult ,它其实也是一个元组类型,既可以用属性获取值,也可以用索引来获取。示例如下:
print(result_urlsplit.netloc)
print(result_urlsplit[1])
结果如下:
www.geekdigging.com
www.geekdigging.com
urlunsplit()
看到这个命名各位同学应该大致上已经可以猜出来 urlunsplit() 它的作用以及用法了。
对的,木有错,它和上面介绍的 urlunparse() 是非常相似的,唯一的区别就是它的参数长度必须为 5 。示例如下:
from urllib.parse import urlunsplit
params_urlunsplit = ('https', 'www.geekdigging.com', 'index.html;people', 'a=1', 'geekdigging')
print(urlunsplit(params_urlunsplit))
结果如下:
https://www.geekdigging.com/index.html;people?a=1#geekdigging
其余的不多做介绍,完全参考上面的 urlunparse() 。
urljoin()
上面我们介绍了 urlunparse() 和 urlunsplit() 两个方法可以合成链接,前提是我们需要有定长的参数可迭代对象,链接的每一个组件都要对应的分开。
而 urllib.parase 中提供的 urljoin() 这个方法就比较有意思了。我们先看下官方的解释:
Construct a full ("absolute") URL by combining a "base URL" (base) with another URL (url). Informally, this uses components of the base URL, in particular the addressing scheme, the network location and (part of) the path, to provide missing components in the relative URL.
其中的大意是:通过基础的 URL 和另一个 URL 来完成组合完成最终的 URL ,它会分析基础的 URL 的 scheme 、 netloc 和 path 这三个内容,并对新连接缺失的部分进行补充,完成最终的组合。
有点没看懂?没关系,我们写几个简单的示例就清楚了:
print(urljoin("https://www.geekdigging.com/", "index.html"))
print(urljoin("https://www.geekdigging.com/", "https://www.geekdigging.com/index.html"))
print(urljoin("https://www.geekdigging.com/", "?a=aa"))
print(urljoin("https://www.geekdigging.com/#geekdigging", "https://docs.python.org/zh-cn/3.7/library/urllib.parse.html"))
结果如下:
https://www.geekdigging.com/index.html
https://www.geekdigging.com/index.html
https://www.geekdigging.com/?a=aa
https://docs.python.org/zh-cn/3.7/library/urllib.parse.html
不知各位同学看懂了没?
只有在第二个参数链接缺失 scheme 、 netloc 和 path 这三个内容的时候,才会从第一个参数中获取对应的内容进行组合。
parse_qs()
这个方法可以让我们将一串 GET 请求中的参数转换成为字典。
我们在百度搜索的时候,像百度发送的请求其实是 GET 请求,例如我在百度搜索 Python ,这时浏览器上的链接显示为:https://www.baidu.com/s?ie=UTF-8&wd=python 。这里的 GET请求参数实际上是 ? 后面这部分 ie=UTF-8&wd=python 。我们还是用 parse_qs() 来写个示例看一下:
from urllib.parse import parse_qs
print(parse_qs("ie=UTF-8&wd=python"))
执行结果如下:
{'ie': ['UTF-8'], 'wd': ['python']}
可以看到,参数成功的转换成了字典。
parse_qsl()
还有一个parse_qsl()方法,它用于将参数转化为元组组成的列表,示例如下:
from urllib.parse import parse_qsl
# parse_qsl 示例
print(parse_qsl("ie=UTF-8&wd=python"))
执行结果如下:
[('ie', 'UTF-8'), ('wd', 'python')]
可以看到,参数成功的转换成了元组组成的列表。
URL 引用
urlencode()
我们接着介绍一个比较常用的方法: urlencode() 。
这个方法是用来构造 GET 请求参数的,例如我们上面示例中所使用到的百度搜索的参数,它可以将一个字典转换成为 GET 请求参数。示例如下:
from urllib.parse import urlencode
# urlencode 示例
dict = {
"name": "极客挖掘机",
"age": 18
}
print("https://www.geekdigging.com/" + urlencode(dict))
结果如下:
https://www.geekdigging.com/name=%E6%9E%81%E5%AE%A2%E6%8C%96%E6%8E%98%E6%9C%BA&age=18
执行结果中有一串看不懂是什么的字符串,这个是 URL 编码,因为参数中含有中文参数时,可能会导致乱码,可以看到 urlencode() 这个方法,自动的帮我们对中文进行了 URL 编码。
quote()
这个方法是 urllib.parse 中专门为我们提供的 URL 转码的方法,我们还是拿上面一个示例的中文进行转码,各位同学可以看下结果是否相同:
from urllib.parse import quote
# quote 示例
print(quote("极客挖掘机"))
结果如下:
%E6%9E%81%E5%AE%A2%E6%8C%96%E6%8E%98%E6%9C%BA
好像是一样的对吧,说明我们测试成功。
unquote()
有了 quote() 的方法,当然会搞一个专门逆向的方法咯~~~
我们把刚才经过 URL 编码后的字符串拿出来做测试,看看能不能转回去:
from urllib.parse import unquote
# unquote 示例
print(unquote("%E6%9E%81%E5%AE%A2%E6%8C%96%E6%8E%98%E6%9C%BA"))
结果如下:
极客挖掘机
可以看到,经过我们 URL 编码后的字符串逆向成功。
本篇的内容就到这里了,内容有些又臭又长,不过还是希望各位同学可以亲自动手练习一下。
毕竟,自己不敲代码是永远学不会代码的。
示例代码
本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。
参考
https://www.cnblogs.com/zhangxinqi/p/9170312.html
小白学 Python 爬虫(14):urllib 基础使用(四)的更多相关文章
- 小白学 Python 爬虫(15):urllib 基础使用(五)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(11):urllib 基础使用(一)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(12):urllib 基础使用(二)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(13):urllib 基础使用(三)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(16):urllib 实战之爬取妹子图
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(17):Requests 基础使用
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(30):代理基础
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
随机推荐
- 清华大学教学内核ucore学习系列(1) bootloader
ucore是清华大学操作系统课程的实验内核,也是一个开源项目,是不可多得的非常好的操作系统学习资源 https://github.com/chyyuu/ucore_lab.git, 各位同学可以使用g ...
- 手写一个简易的IOC
这个小项目是我读过一点Spring的源码后,模仿Spring的IOC写的一个简易的IOC,当然Spring的在天上,我写的在马里亚纳海沟,哈哈 感兴趣的小伙伴可以去我的github拉取代码看着玩 地址 ...
- js的ajax请求
1 js原生get请求 <script> window.onload = function(){ var oBtn = document.getElementById('btn'); oB ...
- dp的林林总总(持续更新,dp骚气解法等等)
写在前面: 本人dp较弱,所以总结了一些坑点,转化思路以供复习使用,勿喷,甚至一些不是dp的题(贪心等等)也会放在这. 每个点后面会有我自己的题解,如果没有链接,向下找第一个链接,可能会有多题. 1. ...
- 分享一份关于Hadoop2.2.0集群环境搭建文档
目录 一,准备环境 三,克隆VM 四,搭建集群 五,Hadoop启动与测试 六,安装过程中遇到的问题及其解决方案 一,准备环境 PC基本配置如下: 处理器:Intel(R) Core(TM) i5-3 ...
- unittest使用总结
unittest简介 Unittest是python内置的一个单元测试框架,主要用于自动化测试用例的开发与执行 简单的使用如下 import unittest class TestStringMeth ...
- 实验:基于http的yum源
实验:基于http的yum源 selinux,firewalld已经关闭',系统为CentOS7 repodata所在的目录就是yum源 下面介绍了如何把本地光盘通过httpd服务器变成yum源:多个 ...
- git回退之git reset
参考 https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86 https: ...
- iOS蓝牙--CoreBluetooth基本使用
蓝牙使用步骤: 1. 扫描外设 2. 连接外设 3. 连上外设后,获取指定外设的服务 4. 获取服务后,遍历服务的特征,得到可读,可写等特征,然后与中心管理者进行数据交互 附上代码 一:导入框架 #i ...
- PHPExcel数据导入(含图片)
PHPExcel是一个PHP类库,用来帮助我们简单.高效实现从Excel读取Excel的数据和导出数据到Excel. 首先下载压缩包: https://codeload.github.com/PHPO ...