运维学python之爬虫基础篇(四)Cookie

在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。给客户端们颁发一个通行证,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容,登陆前与登陆后是不同的,或者不允许的。

1 opener

基本的urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高级功能。所以要支持这些功能,使用相关的 Handler处理器来创建特定功能的处理器对象,然后通过 urllib.request.build_opener()方法使用这些处理器对象,创建自定义opener对象使用自定义的opener对象,调用open()方法发送请求。

2 http.cookiejar

http.cookiejar模块定义了用于自动处理HTTP cookie的类。通过web服务器的HTTP响应设置储存在客户机机器上,然后在稍后的HTTP请求中返回到服务器。
而创建一个带有cookie的自定义opener,在访问登录的URL时,将登录后的cookie保存下来,然后利用这个cookie来访问其他网址。查看登录之后才能看到的信息。就是利用http.cookiejar爬取登陆登录后信息的原理。
下面用代码举例http.cookiejar通常用法:

    import http.cookiejar, urllib.request ①

    cj = http.cookiejar.CookieJar() ②
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)③) ④
    r = opener.open("http://example.com/")

① 导入模块

② 创建空的cookie实例

③ 使用HTTPCookieProcessor类创建一个HTTP cookie处理器来处理cj

④ 重新自定义opener,加入cookie等信息后打开网页

3 测试

    # -*- coding: utf-8 -*-
    from http import cookiejar
    from urllib import request

    if __name__ == '__main__':
        # 创建一个cookie实例
        cookie = cookiejar.CookieJar()
        # 创建一个http cookie处理器处理cookie
        handler = request.HTTPCookieProcessor(cookie)
        # 重新自定义opener,加入handler
        opener = request.build_opener(handler)
        # 用自定义的opener打开网页
        response = opener.open('https://www.baidu.com')
        # 打印cookie信息
        for item in cookie:
            print('Name: %s' % item.name)
            print('Value: %s' % item.value)

运行结果如下:
运维学python之爬虫基础篇(四)Cookie

上面的例子可以实现通过循环获取cookie内容,接下来我们通过FileCookieJar类把cookie储存到本地磁盘的文件中,代码如下:

    # -*- coding: utf-8 -*-
    from urllib import request
    from http import cookiejar

    if __name__ == '__main__':
        # 设置保存cookie的文件
        cookie_file = 'cookie.txt'
        # 创建一个MozillaCookerjar对象实例来保存cookie
        cookie = cookiejar.MozillaCookieJar(cookie_file)
        # 创建处理handler
        handler = request.HTTPCookieProcessor(cookie)
        # 创建自定义opener
        opener = request.build_opener(handler)
        response = opener.open('https://www.baidu.com')
        # 保存cookie到文件
        cookie.save(ignore_discard=True, ignore_expires=True)

参数说明:
运维学python之爬虫基础篇(四)Cookie
filename:要保存cookie的文件名
ignore_discard:即使cookie被丢弃依然保存
igore_expires:即使cookie已有缓存依然覆盖
执行结果如下:
运维学python之爬虫基础篇(四)Cookie

上一节中我们已经将cookie存储到本地磁盘文件中,那如何使用本地保存的cookie呢?我们继续:

    # -*- coding: utf-8 -*-
    from urllib import request
    from http import cookiejar

    if __name__ == '__main__':
        # 定义保存的cookie文件名
        cookie_file = 'cookie.txt'
        # 创建实例对象
        cookie = cookiejar.MozillaCookieJar()
        # 从文件加载cookie_file内容到变量
        cookie.load(cookie_file, ignore_expires=True, ignore_discard=True)
        # 创建处理handler
        handler = request.HTTPCookieProcessor(cookie)
        # 创建自定义opener
        opener = request.build_opener(handler)
        # 打开网页
        response = opener.open('https://www.baidu.com')
        # 打印内容
        print(response.read().decode('utf-8'))

通过 cookie.load(cookie_file, ignore_expires=True, ignore_discard=True)将保存本地的 cookie文件加载,加到request请求中。

4 开始干活

养兵千日,用兵一时,写了这么多了,该实际操作了,下面我们就拿登录豆瓣为例子讲解一下实际使用效果,发现找了好多网站,多数都是要验证码的,那个后面才会搞,没有合适的,这里只是找个网站做例子,供大家参考,大家可以试试登陆自己公司的网站、OA、或其他不需要验证码的网址,首先先了解一下一个抓包小工具

4.1 Fiddler

下载地址:https://www.telerik.com/download/fiddler(需要输入邮箱)
或者直接到我网盘下载也可以:链接:https://pan.baidu.com/s/1i5H4uED 密码:lmfy
因为测试用的是公司OA,测试成功,但不大方便,就拿北京市保障性住房的网站来截图说明,记住要注册后登陆一次之后才会知道具体传了哪些参数,访问的网址是哪个:
运维学python之爬虫基础篇(四)Cookie
打开fiddler,输入登陆信息后打开网址,fiddler获取的信息如下:
运维学python之爬虫基础篇(四)Cookie
可以看到头信息,请求地址等信息,最底下是用户名密码和验证码,再看一张图,更清晰
运维学python之爬虫基础篇(四)Cookie
可以看到传的信息很少,只有三个,idCard(用户名), password(密码),code(验证码)
我们想要看到的页面是下面这个页面:
运维学python之爬虫基础篇(四)Cookie
挑转这个页面后,也可以通过fiddler查看跳转的连接,提交的参数,分析过程就是这样,具体代码如下:

    # -*- coding: utf-8 -*-
    from urllib import request, parse, error
    from http import cookiejar

    if __name__ == '__main__':
        # 登陆地址
        dl_url = 'http://www.bphc.com.cn/front/member/toLogin'
        # 建立一个空字典,用来存储data传输的参数
        dl_data = {}
        # 添加参数
        dl_data['idCard'] = 'xxxxxxxx'
        dl_data['password'] = '123456789'
        dl_data['code']='xxxxxx'

        # 通过parse格式化数据
        dl_data = parse.urlencode(dl_data).encode('utf-8')
        # 声明一个cookie实例来保存cookie
        cookie = cookiejar.CookieJar()
        # 创建handler处理器
        handler = request.HTTPCookieProcessor(cookie)
        # 自定义opener
        opener = request.build_opener(handler)
        # 添加头信息
        head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0', 'Connection': 'keep-alive'}
        # 打开url
        req = request.Request(url=dl_url, data=dl_data, headers=head)

        # 要获取信息的页面地址
        lc_url = 'http://www.bphc.com.cn/article/list/b02e7e29e33642f789e4d1e41db08b7d.html'
        lc_data = {}
        # 格式化数据
        lc_data = parse.urlencode(lc_data).encode('utf-8')
        req2 = request.Request(url=lc_url, data=lc_data, headers=head)

        try:
            # 打开网址
            response = opener.open(req)
            response2 = opener.open(req2)
            html = response2.read().decode('utf-8')
            # 保存到文件
            # with open('test7.html', 'w') as f:
            #     f.write(html)
            print(html)
        except error.URLError as e:
            if hasattr(e, 'code'):
                print("HTTPError: %d" % e.code)
            elif hasattr(e, 'reason'):
                print("URLError: %s" % e.reason)

代码示例如上,这个因为涉及到验证码问题,而我的OA系统又因为不能公开,所以具体执行就没法演示,大家可以跟着这个思路区做,我也会找找不需要验证码的网址,后续替换一下。

原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/54644.html

(0)
上一篇 2021年8月7日
下一篇 2021年8月7日

相关推荐

发表回复

登录后才能评论