一、urllib 简介

urllib 是 Python3 中自带的 HTTP 请求库,无需复杂的安装过程即可正常使用,十分适合爬虫入门

urllib 中包含四个模块,分别是

  • request:请求处理模块
  • parse:URL 处理模块
  • error:异常处理模块
  • robotparser:robots.txt 解析模块

以下我们将会分别讲解 urllib 中各模块的使用方法,但是由于篇幅问题,本文只会涉及模块中比较常用的内容

详细内容可以参考官方文档:https://docs.python.org/3.7/library/urllib.html

二、urllib 使用

在开始讲解前,先给大家提供一个用于测试的网站,http://www.httpbin.org/

这个网站可以在页面上返回所发送 请求 的相关信息,十分适合练习使用

好了,下面正式开始!

1、request 模块

request 模块是 urllib 中最重要的一个模块,一般用于 发送请求和接收响应

(1)urlopen 方法

urllib.request.urlopen()

urlopen 方法无疑是 request 模块中最常用的方法之一,常见的参数说明如下:

  • url:必填,字符串,指定目标网站的 URL

  • data:指定表单数据

    该参数默认为 None,此时 urllib 使用 GET 方法 发送请求

    当给参数赋值后,urllib 使用 POST 方法 发送请求,并在该参数中携带表单信息(bytes 类型)

  • timeout:可选参数,用来指定等待时间,若超过指定时间还没获得响应,则抛出一个异常

该方法始终返回一个 HTTPResponse 对象,HTTPResponse 对象常见的属性和方法如下:

  • geturl():返回 URL
  • getcode():返回状态码
  • getheaders():返回全部响应头信息
  • getheader(header):返回指定响应头信息
  • read():返回响应体(bytes 类型),通常需要使用 decode('utf-8') 将其转化为 str 类型

例子1:发送 GET 请求

>>> import urllib.request
>>> url = 'http://www.httpbin.org/get'
>>> response = urllib.request.urlopen(url)
>>> type(response)
# <class 'http.client.HTTPResponse'>
>>> response.geturl()
# 'http://www.httpbin.org/get'
>>> response.getcode()
# 200
>>> response.getheaders()
# [('Connection', 'close'), ('Server', 'gunicorn/19.9.0'), ('Date', 'Sat, 11 Aug 2018 01:39:14 GMT'), ('Content-Type', 'application/json'), ('Content-Length', '243'), ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Credentials', 'true'), ('Via', '1.1 vegur')]
>>> response.getheader('Connection')
# 'close'
>>> print(response.read().decode('utf-8'))
# {
# "args": {},
# "headers": {
# "Accept-Encoding": "identity",
# "Host": "www.httpbin.org",
# "User-Agent": "Python-urllib/3.7"
# },
# "origin": "183.6.159.80, 183.6.159.80",
# "url": "https://www.httpbin.org/get"
# }

例子2:发送 POST 请求

urllib.parse.urlencode():进行 URL 编码,实际上是将 dict 类型数据转化成 str 类型数据

encode('utf-8'):将 str 类型数据转化成 bytes 类型数据

>>> import urllib.request
>>> import urllib.parse
>>> url = 'http://www.httpbin.org/post'
>>> params = {
'from':'AUTO',
'to':'AUTO'
}
>>> data = urllib.parse.urlencode(params).encode('utf-8')
>>> response = urllib.request.urlopen(url=url,data=data)
>>> html = response.read().decode('utf-8')
>>> print(html)
# {
# "args": {},
# "data": "",
# "files": {},
# "form": { # 这是我们设置的表单数据
# "from": "AUTO",
# "to": "AUTO"
# },
# "headers": {
# "Accept-Encoding": "identity",
# "Connection": "close",
# "Content-Length": "17",
# "Content-Type": "application/x-www-form-urlencoded",
# "Host": "www.httpbin.org",
# "User-Agent": "Python-urllib/3.6"
# },
# "json": null,
# "origin": "116.16.107.180",
# "url": "http://www.httpbin.org/post"
# }

(2)Request 对象

实际上,我们还可以给 urllib.request.open() 方法传入一个 Request 对象作为参数

为什么还需要使用 Request 对象呢?因为在上面的参数中我们无法指定 请求头部,而它对于爬虫而言又十分重要

很多网站可能会首先检查请求头部中的 USER-AGENT 字段来判断该请求是否由网络爬虫程序发起

但是通过修改请求头部中的 USER_AGENT 字段,我们可以将爬虫程序伪装成浏览器,轻松绕过这一层检查

这里提供一个查找常用的 USER-AGENT 的网站:

urllib.request.Request()

参数说明如下:

  • url:指定目标网站的 URL
  • data:发送 POST 请求时提交的表单数据,默认为 None
  • headers:发送请求时附加的请求头部,默认为 {}
  • origin_req_host:请求方的 host 名称或者 IP 地址,默认为 None
  • unverifiable:请求方的请求无法验证,默认为 False
  • method:指定请求方法,默认为 None
>>> import urllib.request
>>> url = 'http://www.httpbin.org/headers'
>>> headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
>>> req = urllib.request.Request(url, headers=headers, method='GET')
>>> response = urllib.request.urlopen(req)
>>> html = response.read().decode('utf-8')
>>> print(html)
# {
# "headers": {
# "Accept-Encoding": "identity",
# "Connection": "close",
# "Host": "www.httpbin.org",
# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 这是我们设置的 User-Agent
# }
# }

(3) 使用 Cookie

什么是 Cookie?

Cookie 是指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据

① 获取 Cookie

>>> import urllib.request
>>> import http.cookiejar
>>> cookie = http.cookiejar.CookieJar()
>>> cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
>>> opener = urllib.request.build_opener(cookie_handler)
>>> response = opener.open('http://www.baidu.com')
>>> for item in cookie:
print(item.name + '=' + item.value) # BAIDUID=486AED46E7F22C0A7A16D9FE6E627846:FG=1
# BDRCVFR[RbWYmTxDkZm]=mk3SLVN4HKm
# BIDUPSID=486AED46E7F22C0A7A16D9FE6E627846
# H_PS_PSSID=1464_21106_26920
# PSTM=1533990197
# BDSVRTM=0
# BD_HOME=0
# delPer=0

② 使用 Cookie

>>> import urllib.request
>>> import http.cookiejar
>>> # 将 Cookie 保存到文件
>>> cookie = http.cookiejar.MozillaCookieJar('cookie.txt')
>>> cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
>>> opener = urllib.request.build_opener(cookie_handler)
>>> response = opener.open('http://www.baidu.com')
>>> cookie.save(ignore_discard=True,ignore_expires=True)
>>> # 从文件读取 Cookie 并添加到请求中
>>> cookie = http.cookiejar.MozillaCookieJar()
>>> cookie = cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True)
>>> cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
>>> opener = urllib.request.build_opener(cookie_handler)
>>> response = opener.open('http://www.baidu.com')
>>> # 此时已经得到带有 Cookie 请求返回的响应

(4)使用代理

对于某些网站,如果同一个 IP 短时间内发送大量请求,则可能会将该 IP 判定为爬虫,进而对该 IP 进行封禁

所以我们有必要使用随机的 IP 地址来绕开这一层检查,这里提供几个查找免费的 IP 地址的网站:

注意,免费的代理 IP 基本上十分不稳定,而且还可能随时更新,所以最好自己写一个爬虫去维护

>>> import urllib.request
>>> import random
>>> ip_list = [
{'http':'61.135.217.7:80'},
{'http':'182.88.161.204:8123'}
]
>>> proxy_handler = urllib.request.ProxyHandler(random.choice(ip_list))
>>> opener = urllib.request.build_opener(proxy_handler)
>>> response = opener.open('http://www.httpbin.org/ip')
>>> print(response.read().decode('utf-8'))
# {
# "origin": "61.135.217.7"
# }

2、parse 模块

parse 模块一般可以用于处理 URL

(1)quote 方法

当你在 URL 中使用中文时,你会发现程序会出现莫名其妙的错误

>>> import urllib.request
>>> url = 'https://www.baidu.com/s?wd=爬虫'
>>> response = urllib.request.urlopen(url)
# UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-11: ordinal not in range(128)

这时,quote 方法就可以派上用场了,它使用转义字符替换特殊字符,从而将上面的 URL 处理成合法的 URL

>>> import urllib.parse
>>> url = 'https://www.baidu.com/s?wd=' + urllib.parse.quote('爬虫')
>>> url
# 'https://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB'

(2)urlencode 方法

urlencode 方法在上面的文章中曾经用到过,不知道大家还有没有印象,这里我们再重新回顾一遍

简单来说,urlencode 方法就是将 dict 类型数据转化为符合 URL 标准的 str 类型数据,请看演示:

>>> import urllib.parse
>>> params = {
'from':'AUTO',
'to':'AUTO'
}
>>> data = urllib.parse.urlencode(params)
>>> data
# 'from=AUTO&to=AUTO'

(3)urlparse 方法

urlparse 方法用于解析 URL,返回一个 ParseResult 对象

该对象可以认为是一个六元组,对应 URL 的一般结构:scheme://netloc/path;parameters?query#fragment

>>> import urllib.parse
>>> url = 'http://www.example.com:80/python.html?page=1&kw=urllib'
>>> url_after = urllib.parse.urlparse(url)
>>> url_after
# ParseResult(scheme='http', netloc='www.example.com:80', path='/python.html', params='', query='page=1', fragment='urllib')
>>> url_after.port
# 80

3、error 模块

error 模块一般用于进行异常处理,其中包含两个重要的类:URLErrorHTTPError

注意,HTTPError 是 URLError 的子类,所以捕获异常时一般要先处理 HTTPError,常用的格式如下:

>>> import urllib.request
>>> import urllib.error
>>> import socket
>>> try:
response = urllib.request.urlopen('http://www.httpbin.org/get', timeout=0.1)
except urllib.error.HTTPError as e:
print("Error Code: ", e.code)
print("Error Reason: ", e.reason)
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print('Time out')
else:
print('Request Successfully') # Time out

【参考资料】

【爬虫系列相关文章】

爬虫系列(三) urllib的基本使用的更多相关文章

  1. Java爬虫系列三:使用Jsoup解析HTML

    在上一篇随笔<Java爬虫系列二:使用HttpClient抓取页面HTML>中介绍了怎么使用HttpClient进行爬虫的第一步--抓取页面html,今天接着来看下爬虫的第二步--解析抓取 ...

  2. 爬虫系列(四) 用urllib实现英语翻译

    这篇文章我们将以 百度翻译 为例,分析网络请求的过程,然后使用 urllib 编写一个英语翻译的小模块 1.准备工作 首先使用 Chrome 浏览器打开 百度翻译,这里,我们选择 Chrome 浏览器 ...

  3. 爬虫系列(六) 用urllib和re爬取百度贴吧

    这篇文章我们将使用 urllib 和 re 模块爬取百度贴吧,并使用三种文件格式存储数据,下面先贴上最终的效果图 1.网页分析 (1)准备工作 首先我们使用 Chrome 浏览器打开 百度贴吧,在输入 ...

  4. 爬虫系列(九) xpath的基本使用

    一.xpath 简介 究竟什么是 xpath 呢?简单来说,xpath 就是一种在 XML 文档中查找信息的语言 而 XML 文档就是由一系列节点构成的树,例如,下面是一份简单的 XML 文档: &l ...

  5. 爬虫系列(二) Chrome抓包分析

    在这篇文章中,我们将尝试使用直观的网页分析工具(Chrome 开发者工具)对网页进行抓包分析,更加深入的了解网络爬虫的本质与内涵 1.测试环境 浏览器:Chrome 浏览器 浏览器版本:67.0.33 ...

  6. 爬虫系列(五) re的基本使用

    1.简介 究竟什么是正则表达式 (Regular Expression) 呢?可以用下面的一句话简单概括: 正则表达式是一组特殊的 字符序列,由一些事先定义好的字符以及这些字符的组合形成,常常用于 匹 ...

  7. 爬虫系列(七) requests的基本使用

    一.requests 简介 requests 是一个功能强大.简单易用的 HTTP 请求库,可以使用 pip install requests 命令进行安装 下面我们将会介绍 requests 中常用 ...

  8. 爬虫系列(八) 用requests实现天气查询

    这篇文章我们将使用 requests 调用天气查询接口,实现一个天气查询的小模块,下面先贴上最终的效果图 1.接口分析 虽然现在网络上有很多免费的天气查询接口,但是有很多网站都是需要注册登陆的,过程比 ...

  9. 爬虫系列(十) 用requests和xpath爬取豆瓣电影

    这篇文章我们将使用 requests 和 xpath 爬取豆瓣电影 Top250,下面先贴上最终的效果图: 1.网页分析 (1)分析 URL 规律 我们首先使用 Chrome 浏览器打开 豆瓣电影 T ...

随机推荐

  1. 如何在 webpack 项目中使用绝对路径

    react 小白编程 本项目是使用 create-react-app 脚手架构建的react项目 找到 config 配置文件下的 webpack.config.dev.js 和 webpack.co ...

  2. 通达OA 小飞鱼老师OA工作流设计课程教学网络公开课之HTML基础(一)

    通达OA网络教学公开课開始了.有须要的小伙伴们抓住机会奥. 8月29号晚8点不见不散.本次课程的主要内容是通达OA工作流设计课程中须要用到的Html部分学习. 帮忙转发的朋友加送一节VIP课程.

  3. Ajax之XMLHttpRequst对象

    XMLHttpRequest对象提供客户端与Http服务器异步通信的协议.通过该协议,Ajax可以使页面像桌面应用程序一样,只同服务器进行数据层的交换,而不用每次都刷新页面,也不用每次将数据处理工作提 ...

  4. NodeJs函数式编程

    虽然标题是NodeJS函数式编程,但实际上NodeJS 是一个框架,不是一种语言,其采用的语言是 JavaScript.而JavaScript是一种典型的多范式编程语言,算不上是函数式语言,但它有函数 ...

  5. Luogu1275魔板

    https://zybuluo.com/ysner/note/1136271 题面 有这样一种魔板:它是一个长方形的面板,被划分成\(n\)行\(m\)列的\(n*m\)个方格.每个方格内有一个小灯泡 ...

  6. HDU3487 Play with Chain splay 区间反转

    HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...

  7. Win7 + VS2015 + CMake3.6.1-GUI + Makefile 编译开源库

    CMake生成Unicode版本VC工程 Just add this line in your top CMakeLists.txt file:     add_definitions(-DUNICO ...

  8. HTML--使用提交按钮,提交数据

    在表单中有两种按钮可以使用,分别为:提交按钮.重置.这一小节讲解提交按钮:当用户需要提交表单信息到服务器时,需要用到提交按钮. 语法: <input type="submit" ...

  9. ex41习题 41: 来自 Percal 25 号行星的哥顿人(Gothons)

    ex41习题 41: 来自 Percal 25 号行星的哥顿人(Gothons) 学习到本题卡住了,遇到一点费解的地方,mark一下.本题主要是介绍函数在字典这种数据类型中的应用,本实验在python ...

  10. [ BZOJ 4318 & 3450 / CodeForces 235 B ] OSU!

    \(\\\) \(Description\) 一共进行\(N\)次操作,生成一个长度为\(N\)的\(01\)序列,成功对应\(1\),失败对应\(0\),已知每一次操作的成功率\(p_i\). 在这 ...