六星源课堂:Python网络爬虫基础——Urllib库
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库不同的、特别的用处,这里也简单介绍一下。
发送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
模拟浏览器发送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()
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的数据。
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的完整路径。
以上为本次分享的全部内容,如果对编程想获得更多了解,请前往六星源课堂,开启你的编程之旅~