爬虫:基本解析库的介绍urllib

目录

1、发送请求 

 data参数

 timeout 参数

其他参数 

 urlopen和Request比较

使用Request来实现灵活的配置

高级用法

密码验证

代理的使用

Cookies处理


Python2中,有urllib和urllib两个库来实现请求的发送,而在Python3中,已经不存在urllib2这个库了,统一为urllib库,他是Python内置的HTTP的请求库主要有4个模块

Request:它是最基本的 HTTP 请求模块,可以用来模拟发送请求 就像在浏览器里输入网挝 然后回车 样,只需要给库方法传入 RL 及额外的 数,就可以模拟实现这个过程了

Error:异常处理模块,如果出现请求错误 可以捕获这些异常,然后进行重试或 作以保证程序不会意外终止

Parse:一个工具模块,提供了许多 URL 处理方法,比如拆分、解析 合并

Robotparser:主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站 可以爬,它其实用得 较少

1、发送请求 

def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            *, cafile=None, capath=None, cadefault=False, context=None):

urllib request 模块提供了最基本的构造 HTTP 求的方法, 利用它可以 拟浏览器的 个请求 发起过程, 同时它还带有处理授权验证( authenticaton )、重定向( redirection 、浏览器 Cookies 及其 他内容。

import urllib.request

response_data = urllib.request.urlopen("https://www.baidu.com")
print(type(response_data))    #  <class ’ http.client.HTTPResponse ’ >
print(response_data.read().decode("utf-8"))   #这里得到的是整个源代码网页
print(response_data.status)    #获取状态值
print(response_data.getheaders())    #获取header,类型为list
print(response_data.getheader("Server"))    #获取header中的数据信息
print(dir(response_data))                    #查看class中所有的对象和属性

 data参数

data 参数是可选的 如果要添加该参数,并且如果它是字节流编码格式的内容,即 bytes 类型, 则需要通过 bytes ()方法转化

import urllib.request
import urllib.parse

data = bytes(urllib.parse.urlencode({"word":"hello"}),encoding="utf-8")
response_data = urllib.request.urlopen("http://httpbin.org/post",data=data)
print(response_data.read())

们传递了一个参数 word ,值是 hello 它需要被转码成 bytes (字节流)类型 其中转字节流采用了 bytes ()方法,该方法的第一个参数需要是 str (字符串)类型,需要用 urllib.parse 模块里的 urencode ()方法来将参数字典转化为字符串;第 个参数指定编码格式,这里指定为 utf8

 timeout 参数

timeout 参数用于设置超时时间,单位为秒,意思就是如果请求超 了设置的这个时间, 还没有得 到响应 就会抛出异常

import urllib.request
import urllib.parse

response_data = urllib.request.urlopen("http://httpbin.org/get",timeout=0.1)
print(response_data.read())

结果会抛出:urllib.error.URLError: <urlopen error timed out>

抛出异常后,可使用:tyr except语句来实现

import urllib.request
import socket
import urllib.error
import urllib.parse

try:
    response_data = urllib.request.urlopen("http://httpbin.org/get",timeout=0.1)
    print(response_data.read())
except urllib.error.URLError as e:
    if isinstance(e.reason,socket.timeout):
        print("TIME OUT")

socket.timeout 类型(意思就是超时异常)

其他参数 

除了data参数和timeout参数外,还有context参数,它必须是ssl.SSLContext类型,用来指定SSL设置

此外,cafile和capath这两个参数分别指定CA证书和它的路径的,这个在请求HTTPS连接时会用到

cadefault参数已经弃用了,其默认值为False

 urlopen和Request比较

urlopen ()方法可以实现最基本请求的发起,但这几个简单的参数并不足以构建 一个完整的请求

果请求中需要加入 Headers 等信息,就可以利用更强大的 Request 类来构建

urlopen:只是简单的发送请求,并不能对请求头做任何的处理

Request:可以对发送的请求头信息做更改,所以使用很广范

使用Request来实现灵活的配置

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

URL:用于请求 URL 这是必传参数,其他都是可选参

Data:data 如果要传,必须传 bytes (字节流)类型的 如果它是字典,可以先用 urllib.parse 模块里的 urlencode ()编码

 Headers: 是一个字典,它就是请求头,我们可以在构造请求时通过 headers 参数直 接构造,也可以通过调用请求实例的 add_header ()方法添加 添加请求头最常用的用法就是通过修改 User-Agent 来伪装浏览器,默认的 User-Agent是 Python-urllib ,我们可以通过修改它来伪装浏览器 比如要伪装火狐浏览器,你可以把它设 置为: Mozilla/s.o (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11

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

Unverifiable :这个请求是否是无法验证的,默认是 False ,意思就是说用户没 有足够权限来选择接收这个请求的结果 例如,我们请求 HTML 文档中的图片,但是我 们没有自动抓取图像的权限,这时 unverifiable 的值就是 True

Method: 一个字符串 ,用来指示请求使用的方法,比如 GET \POST\ PUT等

import urllib.request,parse

url = "http://httpbin.org/post"
headers = {
    "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
    "Host": "httpbin.org"
}
dict = {
    "name" : "zhangsan"
}

data = bytes(urllib.parse.urlencode(dict),encoding="utf-8")
requse_data = urllib.request.Request(url=url,data=data,headers=headers,method="POST")
respnse_data = urllib.request.urlopen(requse_data)
print(respnse_data.read().decode("utf-8"))

另外, headers 也可以用 add_header ()方法来添加:

req = request.Request(url=url, data=data, method= ' POST ’) 
req .add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36') 

高级用法

对Cookies处理,代理设置等等 urllib.request 模块里的 BaseHandler 类,它是所有其他 Handler 的父类,它提 供了最基本的方法,例如 default_open()、 protocol_request ()等   

HITPDefaultErrorHandler :用于处理 响应错误,错误都会抛出 HTTP Error 类型的异常HTTPRedirectHandler :用于处理重定向
HTTPCookieProcessor :用于处理 Cookies
ProxyHandler :用于设置代理 默认代理为空
HTTPPasswordMgr :用于管理密码,它维护了用户名和密码的表
HTTPBasicAuthHandler :用于管理认证,如果一个链接打开时需要认证,那么可以用它来解 决认证问题

另一个比较重要的类就是 OpenerDirector ,我们可以称为 Opener 我们之前用过 urlopen()这 方法,实际上它就是 urllib 为我们提供的一个 Opener;

Opener 可以使用 open()方法,返回的类型和 urlopen()如出一辙。 那么,它和 Handler 有什么 系呢?简而言之,就是利用 Handler 来构建 Opener

密码验证

有些网站在打开时就会弹出提示框,直接提示你输入用户名和密码,验证成功后才能查看页面

from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError

user_name = "username"
password = "password"
url = 'http://localhost:5000/'
p = HTTPPasswordMgrWithDefaultRealm()
p.add_password(None,url,user_name,password)
auth_handler = HTTPBasicAuthHandler(p)
opener = build_opener(auth_handler)

try:
    result =opener.open(url)
    html = result.read().decode("utf-8")
    print(html)
except URLError as e:
    print(e.reason)
    

1、这里首先实例化HTTPBasicAuthHandler对象,其参数是HTTPPasswordMgrWithDefaultRealm对象,他利用add_password()添加进去用户名和密码,这样就建立一个处理验证的Handler

2、利用这个Handler并使用build_opener() 方法构建一个Opener,这个Opener在发送请求时就相对于已经验证成功了

3、利用Opener的open() 方法打开链接,就可以完成验证了,这里获取到的结果就是验证后的页面源码内容

代理的使用

在做爬虫的时候,免不了要使用代理,如果要添加代理,可以这里做

from urllib.error import URLError
from urllib.request import ProxyHandler,build_opener

proxy_handler = ProxyHandler({
 "http":"http://127.0.0.1:9743",
 "https":"https://127.0.0.1:9743"
})
opener = build_opener(proxy_handler)
try:
    response = opener.open("https://www.baidu.com")
    print(response.read().decode("utf-8"))
except URLError as e:
    print(e.reason)

1、这里我们本地搭建了一个代理,它运行在了9743端口上。

2、使用ProxyHandler,其参数是一个字典,键名时协议类型(比如:HTTP或者HTTPS等)键值是是代理链接,可以添加多个代理

3、利用这里Handler及build_opener()方法构造一个Opener,之后发送请求即可

Cookies处理

Cookies处理我们也需要相关的handler了

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)
    

我们显示声明了一个CookieJar对象,接下来,就需要利用HTTPCookieProcessor来构建一个Handler,最后利用build_opener() 方法构建出Opener,执行open() 函数即可

#运行结果:
BAIDUID=30172F7439FC0FEED244E455C6D8204E:FG=1
BIDUPSID=30172F7439FC0FEE227F1F995DE95884
H_PS_PSSID=35292_34442_35104_35240_35048_35096_34584_34504_35167_35318_26350_35145_35301
PSTM=1638079765
BDSVRTM=0
BD_HOME=1

Cookies实际上也是以 文本形式保存的

import http.cookiejar,urllib.request

filename = "cookies.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)

CookieJar就需要换成MozillaCookieJar,它在生成文件时会用到,时CookieJar的子类,可以用来出来Cookies和文件相关的事件,比如读取和保存Cookies,可以将Cookies保存成Mozilla型浏览器的Cookie格式。运行执行发现生成了cookies.txt文件,其内容如下

 LWPCookieJar同样可以读取和保存Cookies,但是保存的格式和MozillaCookieJar不一样,他会保存成libwww-perl(LWP)格式的Cookies文件。

filename = "cookies.txt"
cookie = http.cookiejar.LWPCookieJar(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)

Cookies格式文件内容

 读取Cookies文件

import http.cookiejar,urllib.request

cookie = http.cookiejar.LWPCookieJar()
cookie.load("cookies.txt",ignore_expires=True,ignore_discard=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"))

这里调用load()方法来读取本地的Cookies文件,获取到了Cookies的内容,不过前提时我们首先生成了LWPCookies格式的文件,并保存成文件,然后读取Cookies之后使用同样的方法构建Handler和Opener即可完成操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值