由于2018知乎改版,增加了几个登录所需要的post_data,让我这个初出茅庐的小白头疼了几天,经过一番search(github和各种大佬的博客),最终成功的模拟登录的2018新版知乎。

方法如下:

1.谷歌浏览器,打开知乎登录页面,F12打开调试,F5刷新,选中Network,输入账号,错误的密码(正确的密码登录成功直接跳到主页了就无法分析登录的请求了),观察登录的过程中提交了哪些请求

  主要就是上图中4个请求

(1)第一个是一个GET请求,查看他的response是一个json格式的数据,show_captcha为true表示需要验证码,false为不需要

(2)第二个是一个PUT请求,这次请求得到了验证码的base64码,解码后可得到一张带有字母的图片验证码

(3)第三个是一个POST请求,表示服务器的验证结果是否正确,如果为true,表示验证成功,可以进行最后一个登陆请求了

(4)最后一个为登陆请求(POST),就是登陆请求了,新版知乎的登录post数据变成了Request Payload,比以前复杂了许多

发送请求的时候带上这些数据就可以啦。其中signature和timestamp较为复杂,signature是通过js加密过的(通过ctrl+alt+F搜索signature),可用python模拟js加密过程获得signature的值,timestamp为13位的时间戳。client_id和request header中的authorization后面部分是一样的。

2.下面附上整体代码:

  1 # -*- coding: utf-8 -*-
  2 __author__ = 'Mark'
  3 __date__ = '2018/4/15 10:18'
  4
  5 import hmac
  6 import json
  7 import scrapy
  8 import time
  9 import base64
 10 from hashlib import sha1
 11
 12
 13 class ZhihuLoginSpider(scrapy.Spider):
 14     name = 'zhihu03'
 15     allowed_domains = ['www.zhihu.com']
 16     start_urls = ['http://www.zhihu.com/']
 17     agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
 18     # agent = 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
 19     headers = {
 20         'Connection': 'keep-alive',
 21         'Host': 'www.zhihu.com',
 22         'Referer': 'https://www.zhihu.com/signup?next=%2F',
 23         'User-Agent': agent,
 24         'authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20'
 25     }
 26     grant_type = 'password'
 27     client_id = 'c3cef7c66a1843f8b3a9e6a1e3160e20'
 28     source = 'com.zhihu.web'
 29     timestamp = str(int(time.time() * 1000))
 30     timestamp2 = str(time.time() * 1000)
 31     print(timestamp2)
 32
 33     def get_signature(self, grant_type, client_id, source, timestamp):
 34         """处理签名"""
 35         hm = hmac.new(b'd1b964811afb40118a12068ff74a12f4', None, sha1)
 36         hm.update(str.encode(grant_type))
 37         hm.update(str.encode(client_id))
 38         hm.update(str.encode(source))
 39         hm.update(str.encode(timestamp))
 40         return str(hm.hexdigest())
 41
 42     def parse(self, response):
 43         print(response.body.decode("utf-8"))
 44
 45     def start_requests(self):
 46         yield scrapy.Request('https://www.zhihu.com/api/v3/oauth/captcha?lang=en',
 47                              headers=self.headers, callback=self.is_need_capture)
 48
 49     def is_need_capture(self, response):
 50         print(response.text)
 51         need_cap = json.loads(response.body)['show_captcha']
 52         print(need_cap)
 53
 54         if need_cap:
 55             print('需要验证码')
 56             yield scrapy.Request(
 57                 url='https://www.zhihu.com/api/v3/oauth/captcha?lang=en',
 58                 headers=self.headers,
 59                 callback=self.capture,
 60                 method='PUT'
 61             )
 62         else:
 63             print('不需要验证码')
 64             post_url = 'https://www.zhihu.com/api/v3/oauth/sign_in'
 65             post_data = {
 66                 "client_id": self.client_id,
 67                 "username": "***********",  # 输入知乎用户名
 68                 "password": "***********",  # 输入知乎密码
 69                 "grant_type": self.grant_type,
 70                 "source": self.source,
 71                 "timestamp": self.timestamp,
 72                 "signature": self.get_signature(self.grant_type, self.client_id, self.source, self.timestamp),  # 获取签名
 73                 "lang": "en",
 74                 "ref_source": "homepage",
 75                 "captcha": '',
 76                 "utm_source": "baidu"
 77             }
 78             yield scrapy.FormRequest(
 79                 url=post_url,
 80                 formdata=post_data,
 81                 headers=self.headers,
 82                 callback=self.check_login
 83             )
 84         # yield scrapy.Request('https://www.zhihu.com/captcha.gif?r=%d&type=login' % (time.time() * 1000),
 85         #                      headers=self.headers, callback=self.capture, meta={"resp": response})
 86         # yield scrapy.Request('https://www.zhihu.com/api/v3/oauth/captcha?lang=en',
 87         #                      headers=self.headers, callback=self.capture, meta={"resp": response},dont_filter=True)
 88
 89     def capture(self, response):
 90         # print(response.body)
 91         try:
 92             img = json.loads(response.body)['img_base64']
 93         except ValueError:
 94             print('获取img_base64的值失败!')
 95         else:
 96             img = img.encode('utf8')
 97             img_data = base64.b64decode(img)
 98
 99             with open('zhihu03.gif', 'wb') as f:
100                 f.write(img_data)
101                 f.close()
102         captcha = input('请输入验证码:')
103         post_data = {
104             'input_text': captcha
105         }
106         yield scrapy.FormRequest(
107             url='https://www.zhihu.com/api/v3/oauth/captcha?lang=en',
108             formdata=post_data,
109             callback=self.captcha_login,
110             headers=self.headers
111         )
112
113     def captcha_login(self, response):
114         try:
115             cap_result = json.loads(response.body)['success']
116             print(cap_result)
117         except ValueError:
118             print('关于验证码的POST请求响应失败!')
119         else:
120             if cap_result:
121                 print('验证成功!')
122         post_url = 'https://www.zhihu.com/api/v3/oauth/sign_in'
123         post_data = {
124             "client_id": self.client_id,
125             "username": "***********",  # 输入知乎用户名
126             "password": "***********",  # 输入知乎密码
127             "grant_type": self.grant_type,
128             "source": self.source,
129             "timestamp": self.timestamp,
130             "signature": self.get_signature(self.grant_type, self.client_id, self.source, self.timestamp),  # 获取签名
131             "lang": "en",
132             "ref_source": "homepage",
133             "captcha": '',
134             "utm_source": ""
135         }
136         headers = self.headers
137         headers.update({
138             'Origin': 'https://www.zhihu.com',
139             'Pragma': 'no - cache',
140             'Cache-Control': 'no - cache'
141         })
142         yield scrapy.FormRequest(
143             url=post_url,
144             formdata=post_data,
145             headers=headers,
146             callback=self.check_login
147         )
148
149     def check_login(self, response):
150         # 验证是否登录成功
151         text_json = json.loads(response.text)
152         print(text_json)
153         yield scrapy.Request('https://www.zhihu.com/inbox', headers=self.headers)

3.经过多番挣扎,此次模拟登录新版知乎终于成功,给自己上了一课,还有好多好多需要学习,一起加油吧!

注:

最后调试过程中出现的问题:

(1)验证码票据问题:setting.py文件,设置

COOKIES_ENABLED = True

(2)输入验证码最后检查登录是否成功浏览器时出现500错误,本以为是user-agent的问题,各种设置后发现还是没用,最后经调试发现是自己的timestamp值提交错了

应该先取整然后再转成字符串,写代码一定要仔细仔细仔细啊!!!我是真的皮。。。

参考链接:

https://zhuanlan.zhihu.com/p/34073256

http://www.bubuko.com/infodetail-2485207.html

https://github.com/zkqiang/Zhihu-Login/blob/master/zhihu_login.py

https://github.com/superdicdi/zhihu_login/blob/master/ZhiHu/spiders/zhihu_login.py

转载于:https://www.cnblogs.com/zzzzzhangrui/p/8847724.html

scrapy模拟登录2018新版知乎相关推荐

  1. scrapy mysql 模拟登录知乎_详细的Python Scrapy模拟登录知乎

    之前爬取携程和51job都是免登陆就能爬取数据的,但是今天爬取知乎的时候就需要登录后才能爬到数据,那我们只能进行模拟登录了. 知乎登录分为邮箱登录和手机登录两种方式,通过浏览器的开发者工具查看,我们通 ...

  2. scrapy模拟登录新浪微博

    hi: all, scrapy搞模拟登录真的很简单哦,以下均是在你安装scrapy成功的前提下哦. 首先,分析新浪微薄的登录流程,使用抓包工具得到下面的图片: 一般来说,登录主要就是对服务器进行pos ...

  3. Python 模拟登录知乎

    前言 必备知识点 headers Referer User-Agent 隐藏域 其他 模拟登录 模拟防爬 服务器端 loginphp loginhtml 浏览器测试 正常提交用户名密码的话如下 用户名 ...

  4. Python爬虫初学(三)—— 模拟登录知乎

    模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...

  5. python全系列之爬虫scrapy_python爬虫scrapy之登录知乎

    下面我们看看用scrapy模拟登录的基本写法: 注意:我们经常调试代码的时候基本都用chrome浏览器,但是我就因为用了谷歌浏览器(它总是登录的时候不提示我用验证码,误导我以为登录时不需要验证码,其实 ...

  6. scrapy 模拟登陆

    python 模拟登录豆瓣 并 发表动态:https://blog.csdn.net/freeking101/article/details/65445551 python网络爬虫之使用scrapy自 ...

  7. scrapy mysql 模拟登录知乎_Scrapy 模拟登录新版知乎

    写这篇文章是因为知乎登录已经改版了,新版登录和老版登录区别还是挺大了,新版登录的 post 请求减少了一些字段的同时新增了一些字段,而且新增的字段如 signature 的值是通过一些算法得到的,比较 ...

  8. 在scrapy上使用cookie模拟登录

    下面的例子模拟登录知乎的个人设置页面 设置代理池 scrapy + tor #安装tor sudo apt-get install tor sudo /etc/init.d/tor restart # ...

  9. 新版知乎登录之post请求

    前言 在上一篇文章中给大家讲解了requests发送post请求的几种方式,并分析了一些使用陷阱. 疑惑 在文章发表之后,有朋友给我留言说,知乎登录就没有使用提交Form表单(application/ ...

  10. 新版知乎登录request登录(1)(函数式编程)

    新版知乎登录request登录 运行脚本前提 pip3 install requests 更换用户名,密码,直接运行即可,运行时可能需要输入验证码,验证位于当前目录下. 具体代码,及关键步骤注释如下: ...

最新文章

  1. tfs连不上团队资源管理器问题
  2. sdut2772 KMP的简单应用
  3. gcc/g++静态链接和动态链接解决glibc版本不兼容的问题
  4. MySQL优化union查询
  5. 记一次 .NET 某消防物联网 后台服务 内存泄漏分析
  6. Java 8的新增功能(第二部分–可能会出现什么)
  7. 【渝粤题库】陕西师范大学202871 婚姻家庭法作业
  8. ISCSI 1-由零开始
  9. OpenStack 已死?
  10. python质量转换程序,Python库的文件转换成MP3和设置它们的质量
  11. Mybatis 传参问题
  12. 修改鼠标指针的样式,让鼠标变成动态个性化图标,让你的鼠标图标更炫酷起来。
  13. CI框架(4)-页面跳转
  14. photoshop cs6 下载并安装教程
  15. python做一个大鱼吃小鱼_Python精灵模块制作的大鱼吃小鱼游戏
  16. 程序员除了代码,连数字都神神秘秘的
  17. JAVA 面试(更新)
  18. M1 电脑可以体验Windows11系统吗?M1 MAC安装win11详细教程(附图解)
  19. 了解vm.swappiness
  20. bzoj3166: [Heoi2013]Alo

热门文章

  1. ButterKnife8.5.1最新版本使用详细步骤
  2. Android 代码混淆之部分类不混淆的技巧
  3. Integer的比较
  4. 推荐一本好书《应用框架的设计与实现 .NET平台》电子工业出版社
  5. android.mk ifeq使用介绍,Makefile中的ifeq 多条件使用
  6. Wireshark实战分析之UDP协议
  7. mysql5.6跳过密码登录_mysql-配置与使用(跳过原始密码登陆)
  8. DPDK之PMD原理
  9. freeswitch 使用mysql替换默认的sqlite
  10. visual studio code写c语言是在include下有绿色的下划线提示not found