[Python]网络爬虫(三):使用cookiejar管理cookie 以及 模拟登录知乎

来源:互联网 发布:app软件开发参考文献 编辑:程序博客网 时间:2024/06/05 18:44

大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用。

为什么要使用Cookie呢?

Cookie,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)

比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的。那么我们可以利用python3的cookiejar模块来保存cookie信息,然后模拟登录。

在此之前呢,我们必须先介绍一个opener的概念。

1.Opener

当你获取一个URL你使用一个opener。在前面,我们都是使用的默认的opener,也就是urlopen。它是一个特殊的opener,可以理解成opener的一个特殊实例,传入的参数仅仅是url,data,timeout。

如果我们需要用到Cookie,只用这个opener是不能达到目的的,所以我们需要创建更一般的opener来实现对Cookie的设置。

2.Cookiejar

cookiejar模块的主要作用是提供可存储cookie的对象,以便于与urllib模块配合使用来访问Internet资源。Cookiejar模块非常强大,我们可以利用本模块的CookieJar类的对象来捕获cookie并在后续连接请求时重新发送,比如可以实现模拟登录功能。该模块主要的对象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

它们的关系:CookieJar —-派生—->FileCookieJar  —-派生—–>MozillaCookieJar和LWPCookieJar

1)获取Cookie保存到变量

首先,我们先利用CookieJar对象实现获取cookie的功能,存储到变量中,先来感受一下








我们使用以上方法将cookie保存到变量中,然后打印出了cookie中的值,运行结果如下






2)保存Cookie到文件

在上面的方法中,我们将cookie保存到了cookie这个变量中,如果我们想将cookie保存到文件中该怎么做呢?这时,我们就要用到

FileCookieJar这个对象了,建立LWPCookieJar实例,可以存Set-Cookie3类型的文件。而MozillaCookieJar类是存为'.txt'格式的文件.在这里我们使用它的子类MozillaCookieJar来实现Cookie的保存











关于最后save方法的两个参数在此说明一下:

官方解释如下:

ignore_discard: save even cookies set to be discarded. 

ignore_expires: save even cookies that have expiredThe file is overwritten if it already exists

由此可见,ignore_discard的意思是即使cookies将被丢弃也将它保存下来,ignore_expires的意思是如果在该文件中cookies已经存在,则覆盖原文件写入,在这里,我们将这两个全部设置为True。运行之后,cookies将被保存到cookie.txt文件中,我们查看一下内容,附图如下

QQ截图20150215215136

使用LWPCookieJar来保存cookie:

filename = 'cookie'

cookie = cookiejar.LWPCookieJar(filename)

使用的时候直接load。

 3)从文件中获取Cookie并访问

那么我们已经做到把Cookie保存到文件中了,如果以后想使用,可以利用下面的方法来读取cookie并访问网站,感受一下








设想,如果我们的 cookie.txt 文件中保存的是某个人登录百度的cookie,那么我们提取出这个cookie文件内容,就可以用以上方法模拟这个人的账号登录百度。

 4)利用cookie模拟网站登录

下面我们以知乎为例,利用cookie实现模拟登录,来感受一下cookie大法吧!

#!/usr/bin/env/python#encoding: UTF-8import reimport requestsimport http.cookiejarfrom PIL import Imageimport timeimport jsonheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 '                         '(KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36',           "Host": "www.zhihu.com",           "Referer": "https://www.zhihu.com/",           }# 建立一个会话,可以把同一用户的不同请求联系起来;直到会话结束都会自动处理cookiessession = requests.Session()# 建立LWPCookieJar实例,可以存Set-Cookie3类型的文件。# 而MozillaCookieJar类是存为'/.txt'格式的文件session.cookies = http.cookiejar.LWPCookieJar("cookie")# 若本地有cookie则不用再post数据了try:    session.cookies.load(ignore_discard=True)except IOError:    print('Cookie未加载!')def get_xsrf():    """    获取参数_xsrf    """    response = session.get('https://www.zhihu.com', headers=headers)    html = response.text    get_xsrf_pattern = re.compile(r'<input type="hidden" name="_xsrf" value="(.*?)"')    _xsrf = re.findall(get_xsrf_pattern, html)[0]    return _xsrfdef get_captcha():    """    获取验证码本地显示    返回你输入的验证码    """    t = str(int(time.time() * 1000))    captcha_url = 'http://www.zhihu.com/captcha.gif?r=' + t + "&type=login"    response = session.get(captcha_url, headers=headers)    with open('cptcha.gif', 'wb') as f:        f.write(response.content)    # Pillow显示验证码    im = Image.open('cptcha.gif')    im.show()    captcha = input('本次登录需要输入验证码: ')    return captchadef login(username, password):    """    输入自己的账号密码,模拟登录知乎    """    # 检测到11位数字则是手机登录    if re.match(r'\d{11}$', username):        url = 'http://www.zhihu.com/login/phone_num'        data = {'_xsrf': get_xsrf(),                'password': password,                'remember_me': 'true',                'phone_num': username                }    else:        url = 'https://www.zhihu.com/login/email'        data = {'_xsrf': get_xsrf(),                'password': password,                'remember_me': 'true',                'email': username                }    # 若不用验证码,直接登录    result = session.post(url, data=data, headers=headers)    # 打印返回的响应,r = 1代表响应失败,msg里是失败的原因    # loads可以反序列化内置数据类型,而load可以从文件读取    if (json.loads(result.text))["r"] == 1:        # 要用验证码,post后登录        data['captcha'] = get_captcha()        result = session.post(url, data=data, headers=headers)        print((json.loads(result.text))['msg'])        # 保存cookie到本地    session.cookies.save(ignore_discard=True, ignore_expires=True)def isLogin():    # 通过查看用户个人信息来判断是否已经登录    url = "https://www.zhihu.com/settings/profile"    # 禁止重定向,否则登录失败重定向到首页也是响应200    login_code = session.get(url, headers=headers, allow_redirects=False).status_code    if login_code == 200:        return True    else:        return Falseif __name__ == '__main__':    if isLogin():        print('您已经登录')    else:        account = input('输入账号:')        secret = input('输入密码:')        login(account, secret)


以上程序的原理如下

创建一个带有cookie的opener,在访问登录的URL时,将登录后的cookie保存下来,然后利用这个cookie来访问其他网址。

如登录之后才能查看的成绩查询呀,本学期课表呀等等网址,模拟登录就这么实现啦,是不是很酷炫?

好,小伙伴们要加油哦!我们现在可以顺利获取网站信息了,接下来就是把网站里面有效内容提取出来,下一节我们去会会正则表达式!