Python爬虫:Requests模拟登录知乎 Matplotlib识别中文倒立验证码

先说明一下重点中文验证码的问题(这里用的还是人工识别的办法)。

刚开始用requests登录知乎的时候,只是简单地根据不同登录方式请求的url来用requests传递参数请求,然后debug次数多了以后就会一直出错。如下注释掉我要post的验证码数据,由一个函数调用返回:


先用写完后的代码作说明,captcha为验证码


pycharm调试模式下response的内容

将msg内容在python shell里print一下就是验证码识别失败,说明这个时候必须将验证码数据在登录表单里post过去。

因为一般浏览器登录以后,都会获取服务器返回的cookie保存在本地,以后浏览器再访问都会带上cookie中的信息供服务端识别。这里登录以后可以保存cookie,用reqeusts库的会话实例来完成原本requests的函数调用

session = requests.Session()

session.cookies = cookielib.LWPCookieJar(filename="cookies.txt")   # 指定cookies的保存文件名

以上代码和调用session.cookies.save()保存cookies还需要cookiejar

(好像有这个库兼容性问题,用这样的写法比较好

try:

    import cookielib

except:

    import http.cookiejar as cookielib

另外知乎总会识别请求头是否有不合法的字段值,比如用户的请求代理是客户端浏览器还是python代码,从而拒绝请求,必须在每个请求带上header, 如:

header = {

"Host": "www.zhihu.com",

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",

"Referer": "https://www.zhihu.com/"

}

1. 模拟登录开始:

用requests登录重要的一个方法就是requests.post(), 参数为目标url和表单数据。在知乎登录界面,输入邮箱或者手机号,故意填错密码,打开浏览器网页调试器,点击网络(network),观察请求的网页文件,可以看到http协议的请求头和响应头。


邮箱登录的请求(firefox下)

点击参数可以看到请求所带的参数

请求的参数:

_xsrf: 防止跨站脚本攻击的随机数

password: 登录密码

capatcha_type: 验证码类型,这里是cn

email: 登录邮箱

手机号码登录同理,url和表单餐宿略有不同。


主登录逻辑

正则表达式判断是哪种登录方式。现在需要确定_xsrf 和 验证码,完成两个方法来返回。

2. _xsrf比较简单,用lxml或者beautifulsoup从响应中的html文件解析即可,我这里直接用lxml解析,了解xpath就可以了,和css selector有类似结构。

需要 from lxml import etree

返回_xsrf

3. 获取中文验证码:

先来看下中文验证码和什么url或者参数有关:


刷新验证码图片可以看到出现一个GET请求,其请求url为:https://www.zhihu.com/captcha.gif?r=1508680722707&type=login&lang=cn

有过了解易知这个参数r是一个格林威治时间, 由str(int(time.time() * 1000))转换为字符串,

将其与其他固定参数拼接而成请求url。

需要用到两个库pillow和matplotlib(这也是我第一次用matplotlib~)

pillow是python常用的操作图像的库,matplotlib功能强大,更像一个绘图库。

用requests请求以后保存图片为以后识别做准备。因为图片有可能有两个或一个倒立文字,先用pillow显示图片,手动输入个数,再用matploylib读入图像文件,由ginput()函数获取鼠标点击的坐标。

这里尤其要注意要用到matplotlib的ion()方法打开interactive模式!因为这个花了好久查资料,因为注意到了代码在调试模式下才工作,有输出关于Tkagg的信息,反复看了官方文档找到: 什么是interactive模式

将坐标与其他信息拼接成字符串传回。

(原来知乎的请求头里可以看得见表单数据,现在采用了了gzip编码,看到的都是乱码)

Accept-Encodingg:zip, deflate, br

返回captcha数据

4.判断是否登录成功

请求私信的url根据返回的status_code即可判断,也可以下载首页的HTML看是否登录。

保存了cookies以后可以不用每次都重新登录,在.py文件开头加载进cookies,在cookie过期时效内可以直接登录

try:

    session.cookies.load(ignore_discard=True)

except:

    print("cookie未能加载")


参考:

http://blog.wish7.xyz/2016/11/05/%E7%9F%A5%E4%B9%8E%E7%88%AC%E8%99%AB/

推荐阅读更多精彩内容

  • 模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识、经验和见解为例。实现过程遇到不少疑问,借鉴了...
    sunhaiyu阅读 24,546评论 58 116
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 76,153评论 13 117
  • Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的...
    AlexMercer313阅读 1,500评论 1 5
  • HTTP cookie(也称为web cookie,网络cookie,浏览器cookie或者简称cookie)是网...
    留七七阅读 9,212评论 4 64
  • cookie机制 在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用...
    依依玖玥阅读 3,915评论 0 15