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 selenium鼠标键盘操作(ActionChains)
Apr 12 Python
利用python程序生成word和PDF文档的方法
Feb 14 Python
Sublime开发python程序的示例代码
Jan 24 Python
利用Python代码实现数据可视化的5种方法详解
Mar 25 Python
python 多维切片之冒号和三个点的用法介绍
Apr 19 Python
解决PyCharm同目录下导入模块会报错的问题
Oct 13 Python
pytz格式化北京时间多出6分钟问题的解决方法
Jun 21 Python
解决python xx.py文件点击完之后一闪而过的问题
Jun 24 Python
在Django中实现添加user到group并查看
Nov 18 Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
Jan 20 Python
Python如何批量生成和调用变量
Nov 21 Python
代码复现python目标检测yolo3详解预测
May 06 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
删除无限级目录与文件代码共享
2006/07/12 PHP
APMServ使用说明
2006/10/23 PHP
解析PHP无限级分类方法及代码
2013/06/21 PHP
php+mysql数据库实现无限分类的方法
2014/12/12 PHP
深入理解JavaScript高级之词法作用域和作用域链
2013/12/10 Javascript
js使用removeChild方法动态删除div元素
2014/08/01 Javascript
jQuery仿Flash上下翻动的中英文导航菜单实例
2015/03/10 Javascript
分享15个大家都熟知的jquery小技巧
2015/12/02 Javascript
AngularJS仿苹果滑屏删除控件
2016/01/18 Javascript
BootStrap glyphicons 字体图标实现方法
2016/05/01 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
Vue学习笔记进阶篇之单元素过度
2017/07/19 Javascript
浅谈vue.use()方法从源码到使用
2019/05/12 Javascript
深入了解JavaScript 的 WebAssembly
2019/06/15 Javascript
vue中使用带隐藏文本信息的图片、图片水印的方法
2020/04/24 Javascript
vue+canvas实现拼图小游戏
2020/09/18 Javascript
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
2015/04/25 Python
pandas数据清洗,排序,索引设置,数据选取方法
2018/05/18 Python
详解Python中pandas的安装操作说明(傻瓜版)
2019/04/08 Python
python画微信表情符的实例代码
2019/10/09 Python
Python 使用type来定义类的实现
2019/11/19 Python
详解Python高阶函数
2020/08/15 Python
PyTorch 导数应用的使用教程
2020/08/31 Python
美国诺德斯特龙百货官网:Nordstrom
2016/08/23 全球购物
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
htmlentities() 和 htmlspecialchars()有什么区别
2015/07/01 面试题
internal修饰符起什么作用
2013/12/16 面试题
求职简历推荐信范文
2013/12/02 职场文书
公司新员工的演讲稿注意事项
2014/01/01 职场文书
学生出入校管理制度
2014/01/16 职场文书
高考备战决心书
2014/03/11 职场文书
纠纷协议书
2014/04/16 职场文书
2014感恩节演讲稿大全
2014/10/11 职场文书
2014年电话销售工作总结
2014/12/01 职场文书
金正昆讲礼仪观后感
2015/06/11 职场文书
pycharm部署django项目到云服务器的详细流程
2021/06/29 Python