这是第二篇介绍爬虫基础知识的文章,之前的文章【Python爬虫】初识爬虫(1)主要是让大家了解爬虫和爬虫需要的基础知识,今天主要给大家介绍Urllib
的使用。
Urllib
是Python自带的标准库,无需安装,直接可以用,且提供了以下功能:
网页请求
响应获取
代理和cookie设置
异常处理
URL解析
爬虫所需要的功能,基本上在Urllib
中都能找到,学习这个标准库,可以更加深入的理解后面更加便利的requests
库。
我的爬虫环境是基于py3.x
,这里在啰嗦一下py2.x
和py3.x
环境下 Urllib
的区别。
py2.x
环境下有
Urllib
Urlli2
urllib
与urllib2
都是Python
内置的,要实现Http
请求,以urllib2
为主,urllib
为辅.
py3.x
环境下有
Urllib
变化:
import urllib2
使用——-对应的,在Python3.x中会使用import urllib.request,urllib.error
import urllib
——-对应的,在Python3.x中会使用import urllib.request,urllib.error,urllib.parse
import urlparse
——-对应的,在Python3.x中会使用import urllib.parse
import urlopen
——-对应的,在Python3.x中会使用import urllib.request.urlopen
import urlencode
——-对应的,在Python3.x中会使用import urllib.parse.urlencode
import urllib.quote
——-对应的,在Python3.x中会使用import urllib.request.quote
cookielib.CookieJar
——-对应的,在Python3.x中会使用http.CookieJar
urllib2.Request
——-对应的,在Python3.x中会使用urllib.request.Request
Urlopen urlopen的语法:
1urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None) 2#url:访问的网址 3#data:额外的数据,如header,form data
urlopen一般使用三个参数
urlopen(Url,data,timeout)
第一个参数URL必传的,第二个参数data是访问URL时要传送的数据,第三个timeout是设置超时时间,后面两个参数不是必传的。 用法
1# request:GET 2import urllib.request 3response = urllib.request.urlopen('http://www.baidu.com') 4print(response.read().decode('utf-8')) 5 6# request: POST 7# http测试:http://httpbin.org/ 8import urllib.parse 9import urllib.request 10data = bytes(urllib.parse.urlencode({'word':'hello'}),encoding='utf8') 11response = urllib.request.urlopen('http://httpbin.org/post',data=data) 12print(response.read()) 13 14# 超时设置 15import urllib.request 16response = urllib.request.urlopen('http://httpbin.org/get',timeout=1) 17print(response.read())
上面的代码中包含了两个比较常见且重要的请求方式:Get和Post,下面看一下具体的介绍 Get urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应。
1import urllib.request 2response = urllib.request.urlopen('https://www.python.org') 3print(response.read().decode('utf-8'))
Post 以POST发送一个请求,只需要把参数data以bytes形式传入。
1from urllib import request, parse 2 3url = 'http://httpbin.org/post' 4headers = { 5 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', 6 'Host': 'httpbin.org' 7} 8dict = { 9 'name': 'Germey' 10} 11data = bytes(parse.urlencode(dict), encoding='utf8') 12req = request.Request(url=url, data=data, headers=headers, method='POST') 13response = request.urlopen(req) 14print(response.read().decode('utf-8'))
请求头headers处理
如果要模拟浏览器完成特定功能,需要把请求伪装成浏览器。伪装的方法是先监控浏览器发出的请求,再根据浏览器的请求头来伪装,User-Agent
头就是用来标识浏览器的。可以看下面的案例来学习添加一个Headers。
1from urllib import request, parse 2 3url = 'http://httpbin.org/post' 4headers = { 5 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', 6 'Host': 'httpbin.org' 7} 8dict = { 9 'name': 'Germey' 10} 11data = bytes(parse.urlencode(dict), encoding='utf8') 12req = request.Request(url=url, data=data, headers=headers, method='POST') 13response = request.urlopen(req) 14print(response.read().decode('utf-8'))
看完请求我们再看一下响应。
1# 响应类型 2import urllib.open 3response = urllib.request.urlopen('https:///www.python.org') 4print(type(response)) 5# 状态码, 响应头 6import urllib.request 7response = urllib.request.urlopen('https://www.python.org') 8print(response.status) #获取状态码 9print(response.getheaders()) #获取所有响应头 10print(response.getheader('Server')) #获取指定响应头
上面代码中注释里已经对获取响应的方法做了介绍,为了使我们的爬虫性能更加完美我们需要添加Handler。
Handler:处理更加复杂的页面 使用代理的优点: 让服务器以为不是同一个客户段在请求,防止我们的真实地址被泄露,以下是添加一个代理的案例。
1import urllib.request 2 3proxy_handler = urllib.request.ProxyHandler({ 4 'http': 'http://127.0.0.1:9743', 5 'https': 'https://127.0.0.1:9743' 6}) 7opener = urllib.request.build_opener(proxy_handler) 8response = opener.open('http://httpbin.org/get') 9print(response.read())
但是使用一个代理频繁访问服务器的时候也会被判定为是爬虫,这个时候我们可以使用IP池增强我们爬虫的健壮性。 Cookie Cookie,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的。那么我们可以利用Urllib库保存我们登录的Cookie,然后再抓取其他页面就达到目的了。
1import http.cookiejar, urllib.request 2 #获取cookie保存到变量 3cookie = http.cookiejar.CookieJar() 4handler = urllib.request.HTTPCookieProcessor(cookie) 5opener = urllib.request.build_opener(handler) 6response = opener.open("http://www.baidu.com") 7for item in cookie: 8 print(item.name+"="+item.value) 9 10# 保存cooki为文本 11import http.cookiejar, urllib.request 12filename = "cookie.txt" 13# 保存类型有很多种 14## 类型1 15cookie = http.cookiejar.MozillaCookieJar(filename) 16## 类型2 17cookie = http.cookiejar.LWPCookieJar(filename) 18 19handler = urllib.request.HTTPCookieProcessor(cookie) 20opener = urllib.request.build_opener(handler) 21response = opener.open("http://www.baidu.com") 22 23# 使用相应的方法读取 24import http.cookiejar, urllib.request 25cookie = http.cookiejar.LWPCookieJar() 26cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True) 27handler = urllib.request.HTTPCookieProcessor(cookie) 28opener = urllib.request.build_opener(handler) 29response = opener.open("http://www.baidu.com")
异常处理 引入异常处理为了捕获异常,保证程序稳定运行,下面的例子可以教大家如何使用异常处理。
1# 访问不存在的页面,打印异常原因 2from urllib import request, error 3try: 4 response = request.urlopen('http://www.baibai.com/index.htm') 5except error.URLError as e: 6 print(e.reason)
上面的代码中访问了一个不存在的网站,可以打印异常的具体原因,下面的案例
1#捕获的具体异常 2from urllib import request, error 3 4try: 5 response = request.urlopen('http://www.baidu.com') 6except error.HTTPError as e: 7 print(e.reason, e.code, e.headers, sep='\n') 8except error.URLError as e: 9 print(e.reason) 10else: 11 print('Request Successfully')
URL解析 urlparse:拆分URL
1from urllib import urlparse 2result = urlparse("https://edu.hellobi.com/course/157/play/lesson/2580") 3result 4##ParseResult(scheme='https', netloc='edu.hellobi.com', path='/course/157/play/lesson/2580', params='', query='', fragment='')
urlunparse:拼接URL,为urlparse的反向操作
1from urllib.parse import urlunparse 2data = ['http','www.baidu.com','index.html','user','a=7','comment'] 3print(urlunparse(data))
urlencode:字典对象转换成GET请求对象
1from urllib.parse import urlencode 2 3params = { 4 'name': 'germey', 5 'age': 22 6} 7base_url = 'http://www.baidu.com?' 8url = base_url + urlencode(params) 9print(url)
写在最后: 知识点比较多,大家只需要做简单了解,毕竟有更好用的requests等着我们去学习呢。
本文分享自微信公众号 - 程序员小王(PythonLearningCamp),作者:Ahab
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2019-01-16
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句