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

人生苦短,我用 Pythonhtml

前文传送门:python

小白学 Python 爬虫(1):开篇git

小白学 Python 爬虫(2):前置准备(一)基本类库的安装github

小白学 Python 爬虫(3):前置准备(二)Linux基础入门数据库

小白学 Python 爬虫(4):前置准备(三)Docker基础入门浏览器

小白学 Python 爬虫(5):前置准备(四)数据库基础数据结构

小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装框架

小白学 Python 爬虫(7):HTTP 基础ssh

小白学 Python 爬虫(8):网页基础ide

小白学 Python 爬虫(9):爬虫基础

小白学 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 个部分,分别是 schemenetlocpathparamsqueryfragment

大致上能够看出来,解析时是会有特定的分隔符的。

  • 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 的 schemenetlocpath 这三个内容,并对新链接缺失的部分进行补充,完成最终的组合。

有点没看懂?不要紧,咱们写几个简单的示例就清楚了:

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复制代码

不知各位同窗看懂了没?

只有在第二个参数连接缺失 schemenetlocpath 这三个内容的时候,才会从第一个参数中获取对应的内容进行组合。

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 上,方便你们取用。

示例代码-Github

示例代码-Gitee

参考

https://www.cnblogs.com/zhangxinqi/p/9170312.html

若是个人文章对您有帮助,请扫码关注下做者的公众号:获取最新干货推送:)
相关文章
相关标签/搜索