当前位置: 首页 > 后端技术 > Python

小白学Python爬虫(十二):urllib的基本使用(二)

时间:2023-03-25 21:44:04 Python

人生苦短,我用Python上一篇传送门:小白学Python爬虫(一):入门小白学Python爬虫(二):前期准备(一)基础类库的安装小白学习Python爬虫(三):前期准备(二)Linux基础介绍小白学习Python爬虫(四):前期准备(三)Docker基础介绍小白学习Python爬虫(五):前期准备准备工作(四)数据库基础小白学习Python爬虫(六):前期准备(五)爬虫框架安装小白学习Python爬虫(七):HTTP基础小白学习Python爬虫(八):网页基础学习Python爬虫(9):爬虫基础知识Python爬虫新手学习(十):Session和CookiePython爬虫新手学习(十一):urllib的基本使用(一)简介上一篇我们讲了urlopen的基本手势使用,但是这几个简单的参数不足以构建一个comp请求。对于复杂的请求,比如需要添加请求头是无能为力的,那么我们可以选择使用Request。请求官方文档:https://docs.python.org/zh-cn...先看Request的使用语法:classurllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)url:请求的地址链接,只有这个是必选参数,其余都是可选参数。data:如果需要传这个参数,必须是bytes类型(字节流)。headers:请求头信息,是一个字典,可以在构造请求时在headers之间构造,也可以调用add_header()添加。origin_req_host:请求方的主机名或ip地址。unverifiable:指请求是否不可验证,默认为False。这意味着用户没有足够的权限来选择接收这个请求的结果。比如我们在HTML文档中请求一张图片,但是我们没有自动抓取图片的权限,那么unverifiable的值为True。method:请求方法,如GET、POST、PUT、DELETE等。先看一个简单的例子,使用Request爬取一个博客站点:print(response.read().decode('utf-8')),可以看到这里还是使用urlopen()发起请求,只是参数不再是之前的URL、Data、timeout等信息,但改成了Request类型的对象。让我们构建一个稍微复杂一点的请求。importurllib.request,urllib.parseimportjsonurl='https://httpbin.org/post'headers={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,like壁虎)Chrome/78.0.3904.108Safari/537.36','Content-Type':'application/json;encoding=utf-8','Host':'geekdigging.com'}data={'name':'geekdigging','hello':'world'}data=bytes(json.dumps(data),encoding='utf8')req=urllib.request.Request(url=url,data=data,headers=headers,method='POST')resp=urllib.request.urlopen(req)print(resp.read().decode('utf-8'))结果如下:{"args":{},"data":"{\"name\":\"geekdigging\",\"hello\":\"world\"}","files":{},"form":{},"headers":{"Accept-Encoding":"identity","Content-Length":"41","Content-Type":"application/json;encoding=utf-8","Host":"geekdigging.com","User-Agent":"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,如Gecko)Chrome/78.0.3904.108Safari/537.36"},"json":{"hello":"world","name":"geekdigging"},"origin":"116.234.254.11,116.234.254.11","url":"https://geekdigging.com/post"}这里我们构建一个Request对象,有4个参数,通过url指定访问的链接,或者上篇文章提到的测试链接。User-Agent,Content-Type和Host3个参数。使用json。data中的dumps()将一个dict转为json格式,最后通过bytes()转为字节流,最后指定访问方式为POST,从最后的结果可以看出我们之前的设置都成功了在进阶操作之前,我们使用Request来完成请求头的添加,如果我们要处理Cookies,使用代理访问,就需要用到更强大的Handler,Handler可以简单理解为各个这样的函数处理器,使用它,几乎可以为我们做所有关于HTTP请求的事情,urllib.request为我们提供了BaseHandler类,它是所有o的父类therHandlers,它提供了以下方法供直接使用:add_parent():将director添加为父类。close():关闭其父类。parent():使用不同的协议打开或处理错误。default_open():捕获所有的URL和子类,在协议打开前调用。接下来就是集成了这个BaseHandler类的各种Handler子类:HTTPDefaultErrorHandler:用于处理http响应错误,会抛出HTTPError类的异常。HTTPRedirectHandler:用于处理重定向。ProxyHandler:用于设置代理,默认代理为空。HTTPPasswordMgr:用于管理密码,维护用户名和密码表。AbstractBasicAuthHandler:用于获取用户/密码对,然后重试请求以处理认证请求。HTTPBasicAuthHandler:用于重试身份验证信息请求。HTTPCookieProcessor:用于处理cookies。等等,urllib为我们提供了很多BaseHandler的子类,这里就不一一列举了。您可以通过访问官方文档来检查它们。官方文档地址:https://docs.python.org/zh-cn...在介绍如何使用Handler之前,先介绍一个进阶类:OpenerDirector。OpenerDirector是用于处理URL的高级类。它分三个阶段打开URL:在每个阶段调用这些方法的顺序由处理程序实例的顺序决定;每个使用此类方法的程序都会调用protocol_request()方法对请求进行预处理,然后调用protocol_open()来处理请求;最后调用protocol_response()方法来处理响应。我们可以调用OpenerDirectorOpener。我们之前使用过urlopen()方法,其实就是urllib为我们提供的一个Opener。Opener的方法包括:add_handler(handler):向链接添加处理程序open(url,data=None[,timeout]):打开给定的URL与urlopen()方法相同从网站获取cookies:importhttp.cookiejar,urllib.request#实例化cookiejar对象cookie=http.cookiejar.CookieJar()#使用HTTPCookieProcessor构建处理程序handler=urllib.request.HTTPCookieProcessor(cookie)#BuildOpeneropener=urllib.request.build_opener(handler)#发起请求response=opener.open('https://www.baidu.com/')print(cookie)foritemincookie:print(item.name+"="+item.value)代码中的具体含义小编就不解释了,注释都写的比较好了。Thefinalprintresultisasfollows:,,,]>BAIDUID=48EA1A60922D7A30F711A420D3C5BA22:FG=1BIDUPSID=48EA1A60922D7A30DA2E4CBE7B81D738PSTM=1575167484BD_NOT_HTTPS=1这里产生一个问题,cookie既然可以打印,那么我们能不能将cookie的输出保存tothefile?Theanswerisofcourseyes,becauseweknowthatthecookieitselfisstoredinthefile.#Cookies保存Mozilla类型的文件Examplefilename='cookies_mozilla.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)print('cookies_mozillasavedsuccessful')这里需要将之前的CookieJar修改为MozillaCookieJar,生成文件时会用到,是CookieJar的子类,可以用来处理Cookies和文件相关的事件,比如读取和保存Cookies,可以将Cookies保存为Mozilla类浏览器的Cookies格式。运行完成后,我们可以看到在当前程序目录下生成了一个cookies.txt文件。具体内容如下:#NetscapeHTTPCookieFile#http://curl.haxx.se/rfc/cookie_spec.html#这是生成的文件!Donotedit..baidu.comTRUE/FALSE1606703804BAIDUID0A7A76A3705A730B35A559B601425953:FG=1.baidu.comTRUE/FALSE3722651451BIDUPSID0A7A76A3705A730BE64A1F6D826869B5.baidu.comTRUE/FALSEH_PS_PSSID1461_21102_30211_30125_26350_30239.baidu.comTRUE/FALSE3722651451PSTM1575167805.baidu.comTRUE/FALSEdelPer0www.baidu.comFALSE/FALSEBDSVRTM0www.baidu.comFALSE/FALSEBD_HOME0小编比较懒,就不截图了,直接贴结果。当然,除了以Mozilla类浏览器的格式保存cookies外,我们还可以以libwww-perl(LWP)Cookies文件的格式保存cookies。以LWP格式保存cookie,需要在声明时改为LWPCookieJar:#cookiessaveLWPfileexamplefilename='cookies_lwp.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)print('cookies_lwp保存成功')执行结果如下:#LWP-Cookies-2.0Set-Cookie3:BAIDUID="D634D45523004545C6E23691E7CE3894:FG=1";路径=“/”;域名=".baidu.com";路径规范;域名点;expires="2020-11-3002:45:24Z";评论=bd;版本=0Set-Cookie3:BIDUPSID=D634D455230045458E6056651566B7E3;路径=“/”;域名=".baidu.com";路径规范;域名点;expires="2087-12-1905:59:31Z";版本=0Set-Cookie3:H_PS_PSSID=1427_21095_30210_18560_30125;路径=“/”;域名=".baidu.com";路径规范;域名点;丢弃;版本=0Set-Cookie3:PSTM=1575168325;路径=“/”;域名=".baidu.com";路径规范;域名点;expires="2087-12-1905:59:31Z";版本=0设置-Cookie3:delPer=0;路径=“/”;域名=".baidu.com";路径规范;域名点;丢弃;version=0Set-Cookie3:BDSVRTM=0;路径=“/”;domain="www.baidu.com";路径规范;丢弃;version=0Set-Cookie3:BD_HOME=0;路径=“/”;域名="www.baidu.com";路径规范;丢弃;version=0可以看到两种cookie的文件格式差别还是很大的。cookie文件已生成。下一步是在请求时添加cookie。示例代码如下:#请求使用Mozilla类型的文件cookie=http.cookiejar.MozillaCookieJar()cookie.load('cookies_mozilla.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'))这里我们使用load()方法读取本地的Cookies文件,获取Cookies的内容。前提是我们需要提前生成一个Mozilla格式的cookie文件,读取Cookies后用同样的方法构建Handler和Opener。请求正常的时候,首页的源码可以相应的摆渡,但是小编就不贴了,说的有点长。本文内容到此结束。希望大家记得自己写代码~~~示例代码本系列所有代码编辑器都会放在代码管理仓库Github和Gitee上,方便大家使用。示例代码-Github示例代码-Gitee参考https://www.cnblogs.com/zhang...https://cuiqingcai.com/5500.html如果我的文章对您有帮助,请扫码关注作者公众号:获取最新干货推送:)