2.3 爬虫基础 - Urllib 库基础
2.3.1 Urllib 库简介
Urllib 库是 Python 的标准库,提供了一系列用于操作 URL 的功能,其大部分功能与 Requests 库类似,也有一些特别的用法。它的 API 并不像 Requests 那样直观简洁,所以在这里只简要地介绍一下 Urllib 库的使用方法,让读者知道这个库的用法,后面的爬虫实例还是以 Requests 库作为编写简单爬虫的主要工具。
Urllib 库是 Python 标准库提供的一个用户操作 URL 的模块,Python 3 把原来 Python 2 的 Urilib 库和 Urllib 2 库合并成了一个 Urllib 库,现在讲解的就是 Python 3 中的 Urllib 库。
Urllib 库含有 4 个模块,主要作用如下:urllib.request - 打开和读取 URL;urllib.error - 包含 Urllib.request 各种错误的模块;urlib.parse - 解析 URL;urllib.robotparse - 解析网站 robots.txt 文件。
urllib.request 模块用得最多,这里将着重讲解。urllib.parse 模块拥有与 Requests 库不同的、特别的用处,这里也简单介绍一下。
2.3.2 发送 GET 请求
下面来看如何使用 Urllib 库发送 GET 请求。例如,要抓取豆瓣的首页并打印响应内容。
>>>from urllib.request import urlopen >>>html = urlopen('https://www.douban.com/') >>>response = html.read() >>>print(response)
这里首先从 urllib.request 模块引入 urlopen 函数,然后使用这个函数向豆瓣首页发送请求,它会返回一个二进制的对象 html,对这个 html 对象进行 read() 操作,可以得到一个包含网页内容的二进制响应(response),最后打印出这个 response。也可以对返回响应解码(decode),打印响应的文本内容。
>>>print(response.decode('utf-8'))
这里对 response 使用 utf-8 解码,获取到了它的文本内容。
也可以像 Requests 库那样传递 URL 参数,例如,还是要在豆瓣的书籍栏目中查询与 Python 相关的内容,可以使用如下代码。
>>>import urllib.request >>>import urllib.parse >>>payload = {'q': 'python', 'cat': '1001'} #这里需要对传递的 URL 参数进行编码 >>>payload_encode = urllib.parse.urlencode(payload) >>>request_url = 'https://www.douban.com/search' #构造请求的 URL 地址,添加参数到 URL 后面 >>>request_url += '?' + payload_encode #发起请求 >>>response = urllib.request.urlopen(request_url) #使用 UTF-8 解码并打印响应的文本 >>>print(response.read().decode('utf-8'))
注意这里与 Requests 不同,要对传递的 URL 参数进行编码,所以需要引入 urllib.parse 模块对 payload 进行编码,然后构造请求的 URL 地址。可以打印出刚刚构造的 URL 看一下。
>>>print(request_url) https://www.douban.com/search?q=python&cat=1001
从上面传递 URL 参数发起请求的过程不难看出,Urllib 库在使用方面没有 Requests 库那么直观和简单,需要编写更多的代码才能达到与 Requests 相同的结果。
也可以在 response 上使用 geturl() 获取当前所爬取的 URL 地址。
>>>print(response.geturl()) https://www.douban.com/search?q=python&cat=1001
还可以使用 getcode() 查看爬取网页的状态码。
>>>print(response.getcode()) 200
2.3.3 模拟浏览器发送 GET 请求
与 Requests 库一样,Urllib 库允许设置一些 Headers 信息,模拟成浏览器去访问网站,从而避免被服务器反爬虫禁止。如果想伪装成浏览器发送 GET 请求,就需要使用 Request 对象,通过往 Request 对象添加 HTTP 请求头部,就可以把请求伪装成浏览器。伪装成 Chrome 浏览器爬取豆瓣首页的示例如下。
>>>import urllib.request >>>import urllib.parse >>>url = 'https://www.douban.com/' #定义 headers >>>headers = {'User-Agent': 'Mozilla/5.0 (Windows NT \ 10.0;WOW64) AppleWebKit/537.36 (KHTML, like \ Gecko) Chrome/46.0.2490.80 Safari/537.36'} #创建 request 对象并添加 headers >>>request = urllib.request.Request(url, headers = headers) >>>response = urllib.request.urlopen(request).read()
上面的代码首先设置要爬取的网址和请求头部,然后调用 urllib.request.Request() 函数创建一个 request 对象,该函数传入请求 URL 和请求头部,请求头部使用参数 headers,它有默认值,默认是不传任何头部。这时已经成功设置好报头,然后使用 urlopen 方法打开该 Request 对象即可打开对应的网址。这里为了防止网页长时间未响应,可以设置超时的时间值。可以在 urllib.request.urlopen 打开网址的时候,通过添加 timeout 字段进行设置。
>>>response = urllib.request.urlopen(request, timeout=3).read()
2.3.4 POST 发送一个请求
如果要 POST 发送一个请求,只需要把参数 data 以 bytes 形式传入即可。例如这里向 http://httpbin.org/post 这个网址 POST 一个 dict 数据,然后查看它的响应。
>>>from urllib import request, parse #首先对数据进行转码 >>>post_data = parse.urlencode([('key1', 'value1'), ('key2', 'value2')]) #创建 request 对象 >>>url = request.Request('http://httpbin.org/post') #添加 headers >>>url.add_header('User-Agent','Mozilla/5.0 (Windows NT \ 10.0;WOW64) AppleWebKit/537.36 (KHTML, \ like Gecko) Chrome/46.0.2490.80 Safari/537.36') >>>response = request.urlopen(url, data=post_data.encode('utf-8')).read()
可以打印 response 查看,会发现它返回了刚刚 POST 的数据。
2.3.5 URL 解析
Urllib.parse 提供了几个可以用来为爬虫提供 URL 解析的工具,这几个工具是 Requests 库所没有的。
1. urlparse:拆分 URL
urlparse 模块会将一个普通的 URL 解析为 6 个部分,返回的数据类型都是元组。返回的 6 个部分分别是 scheme(机制)、netloc(网络位置)、path(路径)、params(路径段参数)、query(查询)、fragment(片段)。
示例如下。
>>>from urllib.parse import urlparse >>>urlparse('https://www.douban.com/search?cat=1001&q=python') ParseResult(scheme='https', netloc='www.douban.com', path='/search', params='', query='cat=1001&q=python', fragment='')
2. urlunparse:拼接 URL
urlunparse 可以拼接 URL,为 urlparse 的反向操作,它可以将已经分解后的 URL 再组合成一个 URL 地址,示例如下。
>>>from urllib.parse import urlunparse >>>data = ['https', 'www.douban.com', '/search', '', 'cat=1001&q=python', ''] >>>print(urlunparse(data)) https://www.douban.com/search?cat=1001&q=python
3. urljoin:拼接两个 URL
urljoin 这个函数可以很方便地拼接 URL,示例如下。
>>>from urllib.parse import urljoin >>>urljoin('https://www.douban.com', 'accounts/login') https://www.douban.com/accounts/login >>>urljoin('https://www.douban.com', '/accounts/login') https://www.douban.com/accounts/login >>>urljoin('https://www.douban.com/accounts/', '/accounts/login') https://www.douban.com/accounts/login
可以看到,urljoin 这个函数会自行判断两个 URL 之间是否有/或重复的路径,从而拼接成正确的 URL。在构造爬虫 URL 时,有时候会用到 urljoin 这个函数构造爬虫 URL 的完整路径。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论