Python爬虫之模拟知乎登录的方法教程


Posted in Python onMay 25, 2017

前言

对于经常写爬虫的大家都知道,有些页面在登录之前是被禁止抓取的,比如知乎的话题页面就要求用户登录才能访问,而 “登录” 离不开 HTTP 中的 Cookie 技术。

登录原理

Cookie 的原理非常简单,因为 HTTP 是一种无状态的协议,因此为了在无状态的 HTTP 协议之上维护会话(session)状态,让服务器知道当前是和哪个客户在打交道,Cookie 技术出现了 ,Cookie 相当于是服务端分配给客户端的一个标识。

Python爬虫之模拟知乎登录的方法教程

  • 浏览器第一次发起 HTTP 请求时,没有携带任何 Cookie 信息
  • 服务器把 HTTP 响应,同时还有一个 Cookie 信息,一起返回给浏览器
  • 浏览器第二次请求就把服务器返回的 Cookie 信息一起发送给服务器
  • 服务器收到HTTP请求,发现请求头中有Cookie字段, 便知道之前就和这个用户打过交道了。

实战应用

用过知乎的都知道,只要提供用户名和密码以及验证码之后即可登录。当然,这只是我们眼中看到的现象。而背后隐藏的技术细节就需要借助浏览器来挖掘了。现在我们就用 Chrome 来查看当我们填完表单后,究竟发生了什么?

Python爬虫之模拟知乎登录的方法教程

(如果已经登录的,先退出)首先进入知乎的登录页面 https://www.zhihu.com/#signin ,打开 Chrome 的开发者工具条(按 F12)先尝试输入一个错误的验证码观察浏览器是如何发送请求的。

Python爬虫之模拟知乎登录的方法教程

从浏览器的请求可以发现几个关键的信息

  • 登录的 URL 地址是 https://www.zhihu.com/login/email
  • 登录需要提供的表单数据有4个:用户名(email)、密码(password)、验证码(captcha)、_xsrf。
  • 获取验证码的URL地址是 https://www.zhihu.com/captcha.gif?r=1490690391695&type=login

_xsrf 是什么?如果你对CSRF(跨站请求伪造)攻击非常熟悉的话,那么你一定知道它的作用,xsrf是一串伪随机数,它是用于防止跨站请求伪造的。它一般存在网页的 form 表单标签中,为了证实这一点,可以在页面上搜索 “xsrf”,果然,_xsrf在一个隐藏的 input 标签中

Python爬虫之模拟知乎登录的方法教程

摸清了浏览器登录时所需要的数据是如何获取之后,那么现在就可以开始写代码用 Python 模拟浏览器来登录了。登录时所依赖的两个第三方库是 requests 和 BeautifulSoup,先安装

pip install beautifulsoup4==4.5.3
pip install requests==2.13.0

http.cookiejar 模块可用于自动处理HTTP Cookie,LWPCookieJar 对象就是对 cookies 的封装,它支持把 cookies 保存到文件以及从文件中加载。

而 session 对象 提供了 Cookie 的持久化,连接池功能,可以通过 session 对象发送请求

首先从cookies.txt 文件中加载 cookie信息,因为首次运行还没有cookie,所有会出现 LoadError 异常。

from http import cookiejar
session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='cookies.txt')
try:
 session.cookies.load(ignore_discard=True)
except LoadError:
 print("load cookies failed")

获取 xsrf

前面已经找到了 xsrf 所在的标签,,利用 BeatifulSoup 的 find 方法可以非常便捷的获取该值

def get_xsrf():
 response = session.get("https://www.zhihu.com", headers=headers)
 soup = BeautifulSoup(response.content, "html.parser")
 xsrf = soup.find('input', attrs={"name": "_xsrf"}).get("value")
 return xsrf

获取验证码

验证码是通过 /captcha.gif 接口返回的,这里我们把验证码图片下载保存到当前目录,由人工识别,当然你可以用第三方支持库来自动识别,比如 pytesser。

def get_captcha():
 """
 把验证码图片保存到当前目录,手动识别验证码
 :return:
 """
 t = str(int(time.time() * 1000))
 captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
 r = session.get(captcha_url, headers=headers)
 with open('captcha.jpg', 'wb') as f:
  f.write(r.content)
 captcha = input("验证码:")
 return captcha

登录

一切参数准备就绪之后,就可以请求登录接口了。

def login(email, password):
 login_url = 'https://www.zhihu.com/login/email'
 data = {
  'email': email,
  'password': password,
  '_xsrf': get_xsrf(),
  "captcha": get_captcha(),
  'remember_me': 'true'}
 response = session.post(login_url, data=data, headers=headers)
 login_code = response.json()
 print(login_code['msg'])
 for i in session.cookies:
  print(i)
 session.cookies.save()

请求成功后,session 会自动把 服务端的返回的cookie 信息填充到 session.cookies 对象中,下次请求时,客户端就可以自动携带这些cookie去访问那些需要登录的页面了。

auto_login.py 示例代码

# encoding: utf-8
# !/usr/bin/env python
"""
作者:liuzhijun
"""
import time
from http import cookiejar

import requests
from bs4 import BeautifulSoup

headers = {
  "Host": "www.zhihu.com",
  "Referer": "https://www.zhihu.com/",
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'
}

# 使用登录cookie信息
session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='cookies.txt')
try:
  print(session.cookies)
  session.cookies.load(ignore_discard=True)

except:
  print("还没有cookie信息")


def get_xsrf():
  response = session.get("https://www.zhihu.com", headers=headers)
  soup = BeautifulSoup(response.content, "html.parser")
  xsrf = soup.find('input', attrs={"name": "_xsrf"}).get("value")
  return xsrf


def get_captcha():
  """
  把验证码图片保存到当前目录,手动识别验证码
  :return:
  """
  t = str(int(time.time() * 1000))
  captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
  r = session.get(captcha_url, headers=headers)
  with open('captcha.jpg', 'wb') as f:
    f.write(r.content)
  captcha = input("验证码:")
  return captcha


def login(email, password):
  login_url = 'https://www.zhihu.com/login/email'
  data = {
    'email': email,
    'password': password,
    '_xsrf': get_xsrf(),
    "captcha": get_captcha(),
    'remember_me': 'true'}
  response = session.post(login_url, data=data, headers=headers)
  login_code = response.json()
  print(login_code['msg'])
  for i in session.cookies:
    print(i)
  session.cookies.save()


if __name__ == '__main__':
  email = "xxxx"
  password = "xxxxx"
  login(email, password)

github源码地址:https://github.com/lzjun567/crawler_html2pdf/blob/master/zhihu/auto_login.py

总结

以上就是关于Python爬虫之模拟知乎登录的全部内容,希望本文的内容对大家学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python操作MySQL数据库的方法分享
May 29 Python
使用go和python递归删除.ds store文件的方法
Jan 22 Python
用Python编写一个每天都在系统下新建一个文件夹的脚本
May 04 Python
利用python对Excel中的特定数据提取并写入新表的方法
Jun 14 Python
对Python3.x版本print函数左右对齐详解
Dec 22 Python
Python使用pyshp库读取shapefile信息的方法
Dec 29 Python
python使用suds调用webservice接口的方法
Jan 03 Python
Django Rest framework权限的详细用法
Jul 25 Python
利用python3 的pygame模块实现塔防游戏
Dec 30 Python
python修改linux中文件(文件夹)的权限属性操作
Mar 05 Python
如何打包Python Web项目实现免安装一键启动的方法
May 21 Python
Python爬虫逆向分析某云音乐加密参数的实例分析
Dec 04 Python
python爬虫入门教程--优雅的HTTP库requests(二)
May 25 #Python
Python操作使用MySQL数据库的实例代码
May 25 #Python
python爬虫入门教程--快速理解HTTP协议(一)
May 25 #Python
用生成器来改写直接返回列表的函数方法
May 25 #Python
Python随机读取文件实现实例
May 25 #Python
利用Anaconda完美解决Python 2与python 3的共存问题
May 25 #Python
Python实现的简单dns查询功能示例
May 24 #Python
You might like
使用PHP处理数据库数据如何将数据返回客户端并显示当前状态
2016/02/16 PHP
php显示页码分页类的封装
2017/06/08 PHP
javascript脚本调试方法小结
2008/11/24 Javascript
JS 对输入框进行限制(常用的都有)
2013/07/30 Javascript
处理及遍历XML文档DOM元素属性及方法整理
2013/08/23 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
2014/04/02 Javascript
JS中使用Array函数shift和pop创建可忽略参数的例子
2014/05/28 Javascript
jQuery实现简易的天天爱消除小游戏
2015/10/16 Javascript
jQuery基于cookie实现的购物车实例分析
2015/12/24 Javascript
jQuery代码实现对话框右上角菜单带关闭×
2016/05/03 Javascript
JavaScript简单实现弹出拖拽窗口(二)
2016/06/17 Javascript
JS实现页面进入和返回定位到具体位置
2016/12/08 Javascript
JS日程管理插件FullCalendar中文说明文档
2017/02/06 Javascript
vue构建单页面应用实战
2017/04/10 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
利用nginx + node在阿里云部署https的步骤详解
2017/12/19 Javascript
webpack多入口文件页面打包配置详解
2018/01/09 Javascript
使用D3.js构建实时图形的示例代码
2018/08/28 Javascript
详解vuex中action何时完成以及如何正确调用dispatch的思考
2019/01/21 Javascript
Android 自定义view仿微信相机单击拍照长按录视频按钮
2019/07/19 Javascript
使用IPython下的Net-SNMP来管理类UNIX系统的教程
2015/04/15 Python
Python反射用法实例简析
2017/12/22 Python
tensorflow1.0学习之模型的保存与恢复(Saver)
2018/04/23 Python
详解Python 解压缩文件
2019/04/09 Python
django admin 添加自定义链接方式
2020/03/11 Python
详解python方法之绑定方法与非绑定方法
2020/08/17 Python
python实现在列表中查找某个元素的下标示例
2020/11/16 Python
自动化专业个人求职信范文
2013/11/29 职场文书
迎接领导欢迎词
2014/01/11 职场文书
面试后感谢信怎么写
2014/02/01 职场文书
读书活动总结范文
2014/04/26 职场文书
大学班级文化建设方案
2014/05/06 职场文书
篮球赛口号
2014/06/18 职场文书
2014年大学生党员评议表自我评价
2014/09/20 职场文书
可怜妈妈观后感
2015/06/09 职场文书
心得体会格式及范文
2016/01/25 职场文书