初识 Python 网络请求库 urllib

urllib 是 Python 自带的网络请求标准库,包含了多个处理 URL 功能的模块。

  • urllib.request 用于请求和读取 URL『包含网页认证、重定向、cookies 等等』,可以方便的获取 URL 内容。
  • urllib.error 用于 urlib.request 的异常处理。
  • urllib.parse 用于 urls 解析。
  • urllib.robotparse 用于 robot.txt 文件解析。

urllib.request 和 urllib.error 是我们常用的两个库,这两个库也是在爬虫程序中使用频繁的库。

urllib.request

通过 urllib.request 模块可以发送 http 请求,并读取请求结果。

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

参数信息如下:

  • url 是网页网址,可以是域名也可以是 IP 地址。
  • data 是发往服务器的数据,当无数据发送时可省略该参数,是 bytes 类型的内容,可通过 bytes()函数转为化字节流
  • timeout 用于设置请求超时时间;单位是秒。
  • cafile 和 capath 代表 CA 证书和 CA 证书的路径。如果使用HTTPS则需要用到。
  • cadefault 目前已弃用。
  • context 参数必须是 ssl.SSLContext 类型,用来指定 SSL 设置

抓取网页内容

使用 urllib.request.urlopen 可以很方便的获取网页内容,我们以获取 httpbin.org 内容为例,介绍 urlopen 的使用方法

from urllib import request

response = request.urlopen('http://httpbin.org')
data = response.read()
print("HTTP Status:", response.status, response.reason)
for k, v in response.headers:
    print("%s %s" % (k, v))

运行结果如下:

HTTP Status: 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Date: Thu, 28 Feb 2019 08:17:13 GMT
Server: nginx
Content-Length: 9593
Connection: Close


DATA:  <!DOCTYPE html>
<html lang="en">
.....
</body>

</html>

网络请求难免会遇到长时间无法正常连接的问题,此时可以通过设置超时时间「timeout」,使 urlopen 方法在一定时间内无法连接时自动退出,以免影响整个程序的运行。我们可以通过以下方式来设置超时时间

request.urlopen("http://httpbin.org", timeout = 5)

以上代码设置 5 秒钟内无法正常连接,则退出 urlopen 方法。

向服务器提交数据

向服务器提交数据或请求某些需要携带数据的网页时,需要用到 POST 请求,此时只需要将数据以 bytes 的格式传入参数 data 即可。

使用 POST 提交数据的示例如下

# -*- coding:utf-8 -*-

from urllib import request, parse

data = parse.urlencode([
    ('name', 'keinYe'),
    ('age', '30'),
])

response = request.urlopen('http://httpbin.org/post', data = data.encode('utf-8'))
print('HTTP Status:', response.status, response.reason)
print('HTTP Headers:', response.headers)
print('Data:', response.read().decode('utf-8'))

执行结果如下

HTTP Status: 200 OK
HTTP Headers: Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Thu, 28 Feb 2019 13:53:58 GMT
Server: nginx
Content-Length: 417
Connection: Close


Data: {
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "age": "30",
    "name": "keinYe"
  },
  "headers": {
    "Accept-Encoding": "identity",
    "Content-Length": "18",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "Python-urllib/3.7"
  },
  "json": null,
  "origin": "121.35.186.172, 121.35.186.172",
  "url": "https://httpbin.org/post"
}

模拟浏览器请求

在前面使用 urlopen 方法完成了简单的 get 和 post 请求,但是仅仅 urlopen 方法中的几个参数不足以构建完整的请求,完整的请求通常包含有 header 等信息,我们可以使用 urllib.request.Request 类来构建含有 header 以及请求方法的网络请求。

一个完整的 HTTP 请求通常包含以下内容:

  • :用来说明请求方法(request method)、要访问的资源(URL)以及使用的HTTP版本;
  • /r:用来说明服务器要使用的附加信息(/r用于标记结束);
  • [/r]:根据需要可在头部信息结束之后增加主体数据,(可选;如果请求方法是GET,则没有这个部分;/r用于标记结束);

以下是 urllib.request.Request 的定义:

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

参数信息如下:

  • url 参数是请求链接,这个是必传参数,其他的都是可选参数。
  • data 参数跟 urlopen() 中的 data 参数用法相同。
  • headers 参数是指定发起的 HTTP 请求的头部信息。headers 是一个字典。它除了在 Request 中添加,还可以通过调用 Reques t实例的 add_header() 方法来添加请求头。
  • originreqhost 参数指的是请求方的 host 名称或者 IP 地址。
  • unverifiable 参数表示这个请求是否是无法验证的,默认值是False。意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,我们就要将 unverifiable 的值设置成 True。
  • method 参数指的是发起的 HTTP 请求的方式,有 GET、POST、DELETE、PUT等

现在我们使用 urllib.request 模拟使用 mac 上的 chrome 浏览器。

# -*- coding:utf-8 -*-

from urllib import request

url = 'https://httpbin.org/get'
headers = {
    'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
}
req = request.Request(url=url, headers=headers)
response = request.urlopen(req)
print('HTTP Status:', response.status, response.reason)
print('HTTP Headers:', response.headers)
print('Data:', response.read().decode('utf-8'))

运行结果

HTTP Status: 200 OK
HTTP Headers: Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Fri, 01 Mar 2019 07:09:14 GMT
Server: nginx
Content-Length: 324
Connection: Close


Data: {
  "args": {},
  "headers": {
    "Accept-Encoding": "identity",
    "Host": "httpbin.org",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
  },
  "origin": "119.137.3.11, 119.137.3.11",
  "url": "https://httpbin.org/get"
}

从运行结果中可以看出,httpbin.org 的放回数据中包含有我们提交给 httpbin.org 的浏览器信息。

urllib.error

网络通信是一个异步的通信过程,不可避免的会出现异常,此时就要用到 urllib.error 来处理错误『若不处理错误会造成程序中断执行』,这个会增加程序的健壮性。

urlib.error 中有三个异常处理类,分别是 URLError、HTTPError 和 ContentToolShortError。

URLError 是 urllib.error 异常的类的基类,URLError 是 OSError 的子类,当程序在运行过程中出现错误时会触发该异常。URLError 类带有一个 reason 属性,返回异常的原因,reason 是一个消息字符串或者是一个异常实例。

URLError 示例代码:

from urllib import request
from urllib import error

url = "http://www.google.com"
try:
    response = request.urlopen(url, timeout = 5)
    print(response.read().decode('utf-8'))
except error.URLError as e:
    print("Exception: ", e.reason)

HTTPError 是专门用于处理 http 和 https 请求错误的异常类,HTTPError 也可以作为一个特殊的文件返回值「它与 URLopen 的返回相同」。HTTPError 是 URLError 的子类,它有 code、reason 和 headers 三个属性,code 是 HTTP 请求的返回吗,reason 同 URLError 中相同是一个表示异常原因的消息字符串,headers 是 HTTP 请求返回的请求头信息。

HTTPError 示例代码:

# -*- coding:utf -*-

from urllib import request
from urllib import error

url = "http://www.keinye.com/122323b"
try:
    response = request.urlopen(url, timeout = 5)
    print(response.read().decode('utf-8'))
except error.HTTPError as e:
    print("Exception code:", e.code)
    print("Exception reason:", e.reason)
    print("Exception headers:", e.headers)

由于 HTTPError 是 URLError 的子类,因此在 HTTPError 和 URLError 混合使用时要将 HTTPError 放在 URLError 前面。

ContentToolShortError 是用于处理下载异常的异常类,当 urlretrieve 下载文件不完整时会抛出该异常。

本文分享自微信公众号 - keinYe(keinYe_zh)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏浪子编程走四方

十分钟搞定mac下的phpstorm增加xdebug调试

xdebug 版本需要与php匹配,匹配地址 :https://xdebug.org/wizard.php

9220
来自专栏伪架构师

Istio 限流的正确姿势

Istio 的限流功能和路由不同,关系到 Istio 的 Mixer 适配器模型,因此这里从这一模型的角度来进行限流方面的测试。

41310
来自专栏钻芒博客

纯代码实现WordPress文章设置隐藏内容公众号可见

网上找了一圈找到了龙笑天下博主写的一篇文章:WordPress 文章部分内容关注微信公众号后可见

13020
来自专栏浪子编程走四方

求求你,记住这些基本的Git命令吧!!!

写这篇文章主要是最近在和开发一个项目中所遇到的一个问题.团队中的一个成员对git完全不熟悉,这里终结一些常用的命令操作.当然我们都知道git作为一个分布式的代码...

7630
来自专栏VB小源码

VB6 通过IP判断局域网主机是否在线!

'************************************************************

18330
来自专栏汇智网教程

适合钱包应用开发的ERC20代币数据集

Erc20Tokens数据集包含超过1000种主流的以太坊ERC20代币的描述数据清单和图标,可用于钱包等区块链应用的开发,支持使用Java、Python、Ph...

10410
来自专栏信息安全小学生

ADT Plugin for eclipse 最新下载地址(2015年10月)

7510
来自专栏钻芒博客

wordpress纯代码生成sitemap.xml网站地图

wordpress默认不带xml网站地图,钻芒博客之前一直使用的是Google xml插件,今天帖一下纯代码生成xml网站地图,能少用一款插件就少用一款插件。

35650
来自专栏浪子编程走四方

Swoole学习一之TCP协议

Swoole是一个高性能的网络通信引擎,提供了多种的网络通信协议。例如UDP、TCP、Http和WebSocket等各种通信协议。可以使完全同步的代码实现异步执...

6630
来自专栏浪子编程走四方

PHP入门必看:主流PHP框架的优缺点评比

PHP语言是比较常用到的一门计算机高级语言。这篇文章为大家介绍主流PHP框架相关优缺点评比,供使用时作为参考:

12820

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励