python 3.x 爬虫基础---Urllib详解

前言

  爬虫也了解了一段时间了希望在半个月的时间内结束它的学习,开启python的新大陆,今天大致总结一下爬虫基础相关的类库---Urllib

Urllib

 官方文档地址:https://docs.python.org/3/library/urllib.html

urllib提供了一系列用于操作URL的功能。

Python3中将python2.7的urllib和urllib2两个包合并成了一个urllib库,其主要包括一下模块:

urllib.request 请求模块

urllib.error 异常处理模块

urllib.parse url解析模块

urllib.robotparser robots.txt解析模块

urllib.request

urllib.request.urlopen

通过案例可以看出urlopen,会返回一个二进制的对象,对这个对象进行read()操作可以得到一个包含网页的二进制字符串,然后用decode()解码成一段html代码。

urlopen参数如下:

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

常用参数:

  url:访问的地址,一般不只是地址。

  data:此参数为可选字段,特别要注意的是,如果选择,请求变为post传递方式,其中传递的参数需要转为bytes,如果是我们只需要通过 urllib.parse.urlencode 转换即可:

import urllib.parse
import urllib.request
data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding=  'utf8')
response = urllib.request.urlopen('http://xxxxx', data=data)
print(response.read().decode('utf-8'))

  timeout:设置网站的访问超时时间

其他参数:

  context 参数:它必须是 ssl.SSLContext 类型,用来指定 SSL 设置。

  cafile 和 capath 两个参数:是指定CA证书和它的路径,这个在请求 HTTPS 链接时会有用。

  cadefault 参数:现在已经弃用了,默认为 False 

urlopen返回对象提供方法:

  read() , readline() ,readlines() , fileno() , close() :对HTTPResponse类型数据进行操作。

  info():返回HTTPMessage对象,表示远程服务器返回的头信息。

  getcode():返回Http状态码。

  geturl():返回请求的url。

import urllib.request
response = urllib.request.urlopen('http://python.org/')
print("查看 response 的返回类型:",type(response))
print("查看反应地址信息: ",response)
print("查看头部信息1(http header):\n",response.info())
print("查看头部信息2(http header):\n",response.getheaders())
print("输出头部属性信息:",response.getheader("Server"))
print("查看响应状态信息1(http status):\n",response.status)
print("查看响应状态信息2(http status):\n",response.getcode())
print("查看响应 url 地址:\n",response.geturl())
page = response.read()
print("输出网页源码:",page.decode('utf-8'))

urllib.request.Request

import urllib.request
headers = {'Host': 'www.xicidaili.com',
           'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
           'Accept': r'application/json, text/javascript, */*; q=0.01',
           'Referer': r'http://www.xicidaili.com/', }
req = urllib.request.Request(r'http://www.xicidaili.com/nn/', headers=headers)
response = urllib.request.urlopen(req)
html = response.read().decode('utf-8')
print(html)

通过代码我们可以看出urlopen不再是传递url了,而是一个 request。这样一来我们不带把请求独立成一个对象,而且能更加灵活方便的配置访问参数,这是爬虫http必不可少的一步。

Request参数如下:

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

常用参数:  

  url:访问的地址。

  data:此参数为可选字段,其中传递的参数需要转为bytes,如果是字典我们只需要通过 urllib.parse.urlencode 转换即可:

    headers:http相应headers传递的信息,构造方法:headers 参数传递,通过调用 Request 对象的 add_header() 方法来添加请求头。python 3.x 爬虫基础---http headers详解,可参考此文章。

其他参数:

  origin_req_host :指的是请求方的 host 名称或者 IP 地址。

  unverifiable :用来表明这个请求是否是无法验证的,默认是 False 。意思就是说用户没有足够权限来选择接收这个请求的结果。如果没有权限,这时 unverifiable 的值就是 True 。

  method :用来指示请求使用的方法,比如 GET , POST , PUT 等

urllib.request.ProxyHandler(ip代理)

以上做些简单的demo是没有问题的,但是如果想让你的爬虫更加强大,那么 rulllib.request.ProxyHandler 设置代理你一定要知道,网站它会检测某一段时间某个IP 的访问次数,如果访问次数过多,它会禁止你的访问,所以这个时候需要通过设置代理来爬取数据

ef Proxy_read(proxy_list, user_agent_list, i):
    proxy_ip = proxy_list[i]
    print('当前代理ip:%s'%proxy_ip)
    user_agent = random.choice(user_agent_list)
    print('当前代理user_agent:%s'%user_agent)
    sleep_time = random.randint(1,3)
    print('等待时间:%s s' %sleep_time)
    time.sleep(sleep_time)
    print('开始获取')
    headers = {'User-Agent': user_agent,'Accept': r'application/json, text/javascript, */*; q=0.01',
                'Referer': r'https://www.cnblogs.com'
                }
    proxy_support = request.ProxyHandler({'http':proxy_ip})
    opener = request.build_opener(proxy_support)
    request.install_opener(opener)
    req = request.Request(r'https://www.cnblogs.com/kmonkeywyl/p/8409715.html',headers=headers)
    try:
        html = request.urlopen(req).read().decode('utf-8')
    except Exception as e:
        print('******打开失败!******')
    else:
        global count
    count +=1
    print('OK!总计成功%s次!'%count)

以上代码是前段时间写的刷新页面的但是没有达到想要的效果,不过里面有用到 request.ProxyHandler({'http':proxy_ip}) 。其中 urllib.request.build_opener()  方法来利用这个处理器构建一个 Opener ,那么这个 Opener 在发送请求的时候就具备了认证功能了。 request.install_opener(opener) 方法打开链接,就可以完成认证了。

urllib.request.HTTPCookieProcessor(cookie操作)

网站中通过cookie进行判断权限是很常见的。那么我们可以通过 urllib.request.HTTPCookieProcessor(cookie)  来操作cookie。使用Cookie和使用代理IP一样,也需要创建一个自己的opener。在HTTP包中,提供了cookiejar模块,用于提供对Cookie的支持。 http.cookiejar功能强大,我们可以利用本模块的CookieJar类的对象来捕获cookie并在后续连接请求时重新发送,比如可以实现模拟登录功能。该模块主要的对象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

获取cookie( CookieJar)

import http.cookiejar, urllib.request
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
for item in cookie:
   print(item.name+"="+item.value)

保存cookie(MozillaCookieJar)

filename = 'cookie.txt'  
cookie = http.cookiejar.MozillaCookieJar(filename)  
handler = urllib.request.HTTPCookieProcessor(cookie)  
opener = urllib.request.build_opener(handler)  
response = opener.open('http://www.baidu.com')  
cookie.save(ignore_discard=True, ignore_expires=True)

使用cookie

import http.cookiejar, urllib.request
cookie = http.cookiejar.MozillaCookieJar()
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

 其中FileCookieJar、MozillaCookieJar、LWPCookieJar约为保存cookie信息,只是保存格式不同。我们在进行操作cookie时使用对应的格式即可。

urllib.error

  用 try-except来捕捉异常,主要的错误方式就两种 URLError(错误信息)和HTTPError(错误编码).

try:
    data=urllib.request.urlopen(url)
    print(data.read().decode('utf-8'))
except urllib.error.HTTPError as e:
    print(e.code)
except urllib.error.URLError as e:
    print(e.reason)

urllib.parse

urllib.parse.urlparse

将对应的URL解析成六部分,并以元组的数据格式返回来。

import urllib.parse
o = urllib.parse.urlparse('http://www.cnblogs.com/kmonkeywyl/')
print(o)

参数

result = urlparse('url',scheme='https')解析协议 可以去掉http://

result = urlparse('url',scheme='http')

result = urlparse('url',allow_fragments=False) url带有查询参数

result = urlparse('url',allow_fragments=False) url不带有查询参数

urllib.parse.urlunparse

拼接url

from urllib.parse 
data = ['http','www.baidu.com','index.html','user','a=1','comment']
print(urllib.parse.urlunparse(data))

urllib.parse.urljoin

用来拼接url的方法 或者叫组合方法,url必须为一致站点,否则后面参数会覆盖前面的host

from urllib.parse import urljoin
print(urljoin('http://www.baidu.com','FAQ.html'))
print(urljoin('http://www.badiu.com','https://www.baidu.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html','http://www.baidu.com/FAQ.html'))
print(urljoin('www.baidu.com#comment','?category=2'))

这个在这个就不过多的介绍了,有兴趣的可以去看资料。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逆向技术

win32进程概念之句柄表,以及内核对象.

我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候.内核中会新建一个EPROCE...

762
来自专栏风中追风

java类的加载过程和类加载器的分析

我们知道,我们写的java代码保存的格式是 .java, java文件被编译后会转换为字节码,字节码可以在任何平台通过java虚拟机来运行,这也是java能够跨...

5378
来自专栏北京马哥教育

python线程笔记

豌豆贴心提醒,本文阅读时间5分钟 来源:伯乐在线 原文:http://python.jobbole.com/87498/ 引言&动机 考虑一下...

2495
来自专栏闪电gogogo的专栏

Python初学——多线程Threading

接着上篇继续跟着沫凡小哥学Python啦 1.1 什么是多线程 Threading 多线程可简单理解为同时执行多个任务。 多进程和多线程都可以执行多个任务,线程...

2035
来自专栏数据库

详解Redis内部运作机制

纯手工打造每一篇开源资讯与技术干货,数十万程序员和Linuxer已经关注。 Linux技术交流QQ群:2659793(十二月最新!!) Redis数据库(Red...

2127
来自专栏Java成神之路

JavaWeb_常用功能_01_文件上传

 一个功能完善的JavaWeb应用,必不可少的一个功能就是文件的上传。无论是用户的头像等,还是用户需要上传的一系列资料,都是通过文件的上传功能实现的。

1073
来自专栏依乐祝

.NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入

上篇文章我给大家讲解了ASP.NET Core的概念及为什么使用它,接着带着你一步一步的配置了.NET Core的开发环境并创建了一个ASP.NET Core的...

730
来自专栏大内老A

WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[上篇]

服务调用的目的体现在对某项服务功能的消费上,而功能的实现又定义在相应的服务类型中。不论WCF服务端框架处理服务调用请求的流程有多么复杂,最终都落实在服务实例的激...

2388
来自专栏炸天帮5

win32进程概念之句柄表,以及内核对象.

我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候.内核中会新建一个EPROCE...

711
来自专栏跟着阿笨一起玩NET

.NET简谈静态事件链

在我们日常开发过程中经常会遇到多个类实例之间的关联,不管是B/S还是C/S的项目,在对实例的使用是一样的;只不过C/S的项目比较好控制,不管是UI层的对象都能很...

561

扫码关注云+社区