9

Python爬虫编程思想(11):用urllib请求基础验证页面

 3 years ago
source link: https://blog.csdn.net/nokiaguy/article/details/118945854
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Python爬虫编程思想(11):用urllib请求基础验证页面

专栏收录该内容
11 篇文章 0 订阅 ¥99.00 ¥29.90

        有一些页面并不是我们想访问就能访问的,这些页面都会将各种验证,例如,在第一次访问网页之前,会先弹出如图1所示的登录对话框,只有正确输入用户名和密码才能访问页面,否则会直接跳到错误页面。

        这种验证被称为基础验证,是HTTP验证的一种。输入的用户名和密码会通过Authorization请求头字段发送给服务端,在访问给页面时,如果服务端检测到HTTP请求头中没有Authorization字段时,会设置名为WWW-Authenticate的HTTP响应头字段,同时返回401响应码。WWW-Authenticate字段值的格式如下:

'Basic realm=需要验证的范围'

        其中Basic表示基础验证,也就是需要输入用户名和密码。realm部分表示需要验证的范围,是一个字符串,详细的用法在本节后面的部分介绍。

        当浏览器遇到401状态码,并检测到是基础验证时就会弹出如图3-8所示的验证对话框,正确输入用户名和密码后,浏览器会向服务端发送Authorization请求头字段,该字段的值是Basic encode,其中encode是用户名和密码的Base64编码。由于基础验证的用户名和密码都是以明文发送(尽管被进行了Base64编码,但Base64编码是可逆的)的,所以建议该页面使用HTTPS,这样传输的数据就会使用SSL加密,以保证数据传输过程的安全。

        下面的例子使用Flask编写了一个Web服务器,用于模拟基础验证页面。并使用普通设置HTTP请求头的方式和Handler方式请求这个基础验证页面。

        Flask是基于Python的Web框架,可以用于编写Web应用程序,在使用之前需要使用如下的命令安装。

pip install flask        

本例编写的第一个程序是这个支持基础验证的Web服务器,代码如下:

        本例为了方便,将用户名和密码分别固定为bill和1234,现在运行AuthServer.py,然后在浏览器中输入http://127.0.0.1:5000,就会弹出如图3-8所示的验证对话框,正确输入用户名和密码后,浏览器会输出success。当再次访问http://127.0.0.1:5000时,浏览器会使用刚才输入的用户名和密码通过Authorization请求头字段发送给服务端,所以不管用户名和密码输入的是否正确,只要单击了“登录”按钮,下次再访问给页面时都不会再弹出如图3-8所示的登录验证对话框。由于用户名和密码都是通过临时Cookie保存的,所以一旦浏览器关闭,再次打开后,访问http://127.0.0.1:5000仍然会弹出如图3-8所示的登录验证对话框。

        由于用户名和密码是通过HTTP请求头的Authorization字段发送给服务端的,所以在访问该页面时可以直接设置Authorization字段。

        执行这段代码后,会在Console中输出success。AuthServer在Console中也会输出如图2所示的信息。

        urllib中提供了一些Handler类,这些类可以用来处理各种类型的页面请求,这些类通常都是BaseHandler的子类,例如,HTTPBasicAuthHandler用于处理管理认证,HTTPCookieProcessor用于处理Cookie。本例会使用HTTPBasicAuthHandler处理页面的基础验证。

        使用HTTPBasicAuthHandler的关键是build_opener函数,该函数与urlopen类似,只是可以完成更复杂的工作。实际上,urlopen函数相当于类库为你封装好了及其常用的请求方法,利用它们可以完成基本的请求,但如果要完成更复杂的请求,就需要使用build_opener函数。除此之外,还需要使用HTTPPasswordMgrWithDefaultRealm对象封装请求字段数据,也就是用户名、密码和realm。

运行程序,在Console中会输出success。在AuthServer的Console中会输出如图3所示的信息。

        从图3的输出内容可以看出,客户端发送了两次HTTP请求,第1次没有Authorization字段,这是服务端会返回401错误,如果客户端是浏览器,那么就会弹出如图1所示的验证对话框,但现在客户端是爬虫,所以干脆直接提供现成的用户名和密码,这就是第2次HTTP请求的目的。

add_password函数的第1个参数是realm,如果指定这个参数,那么必须与服务端设置WWW-Authenticate字段时指定的realm相同,本例是localhost。如果add_password函数的第1个参数是None,那么服务端会忽略realm。如果指定的realm不一致,就会抛出如图4所示的异常。

        所以为了安全起见,在发送HTTP请求时可以用try...except语句,以避免程序崩溃。 


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK