用scrapy 模拟知乎的登录过程
2017-06-11 23:30
295 查看
本人刚开始学习,可能有些不对的地方,希望大家指正~~
首先,我们分析下知乎登陆的接口,打开浏览器,到知乎的登陆界面,随便输入一个账号密码,查看点击登陆它干了些什么(别输入正确的,不然他就跳到首页去啦~)
可以看到它调用了一个phone_num的接口(邮箱登陆同理就不演示了),再看下这个接口的参数
出了那个_xsrf外,其他参数根据名字大概都可以猜到了
我们先来看看这个_xsrf从哪里来的,打开网页源码,查找_xsrf,发现有一个叫_xsrf的隐藏input标签,值和我们传入的这个参数是一样的
这样,我们就可以直接去取了
除了这个_xsrf外,我们还看到有一个叫captcha的参数,我们猜测它应该就是验证码,我们为了看看这个验证码是如何获得的,刷新一下看看
发现它调了这样一个接口,我们把这个url复制下来,然后直接打开看看~发现正是我们的验证码,我们看这个验证码,他是让我们点击倒立的字,再看我们上传的参数,除了那张图片的大小外,还有一个input_points的参数,应该就是我们点击的点的坐标,服务器通过这个判断我们是否点击了倒立的字,如果我们这样传参数的话,验证码图片的大小我们看上去是固定的,但是这个坐标就比较麻烦了,我们再来分析一下这个请求验证码的url的参数,有3个参数,r,type,lang,最后一个参数好像是表示语言是中文,我们把它变为en验证一下,
发现请求变成了这样一张图片,这不就是直接输入验证码的图片了么~如果可以用这个输入验证码的话我们就可以解决验证码这个参数了
好了,请求的分析差不多就这样了~下面我们可以开始写代码了
先一下我使用的python版本为3.6
新建一个scrapy的项目,新建一个爬虫(以scrapy的base模板新建~另外,这篇文章就做登录的过程,item,pipelines,middleware,settings这些文件就用默认的就行了~)
我们想一下,这个登录的过程中,我们有两个接口需要调用,1是获取验证码,2就是登录,毫无疑问,获取验证码应该优先调用,我们把我们的初始url定为获取验证码,再看一下我们上面验证码接口的参数,有个r的参数,是一串数字,我们优先应该想到是一个和时间有关的参数,我们先用当前时间来试试,我们的入口函数start_requests就变成下面这样
debug 看下我们的回调函数的response
发现服务器返回了500的错误,并未进入我们的回调函数,再去看下我们的网络请求的header,我们知道scrapy对于cookie等一系列值都已经封装好了,但是下面有一个Use-Agent的参数,是需要我们传的,它表示了我们的系统信息以及我们的浏览器信息等一系列信息,我们直接在我们的浏览器复制这个,在我们的header里传进去,再次debug,进入到回调函数里了
看出body是一个二进制文件,我们把文件写入本地看看是不是我们要的验证码图片(注意:这里要用pillow的Image来把图片展示出来),发现我们的猜测都是正确的,打开就是我们的验证码图片了,然后就是读取验证码里的信息问题了,这里就用简单的打开图片我们手动输入的方式,当然,还可以用云打码这种三方平台来读取验证码信息,就可以让爬虫全程不需要人来操作了
接下来,我们就需要去调用登录的接口了,记得前面我们说的参数有个_xsrf的,我们先去取这个参数
参数都齐了,我们去调接口去~
后面还写了个检查登录是否成功的回调
运行一下我们的爬虫
嗯 ,成功了,接下来就可以去主页上爬取自己感兴趣的内容了
第一次写博客,有很多东西可能描述的也不是很清楚,最后把这个爬虫的完整代码放上来吧
首先,我们分析下知乎登陆的接口,打开浏览器,到知乎的登陆界面,随便输入一个账号密码,查看点击登陆它干了些什么(别输入正确的,不然他就跳到首页去啦~)
可以看到它调用了一个phone_num的接口(邮箱登陆同理就不演示了),再看下这个接口的参数
出了那个_xsrf外,其他参数根据名字大概都可以猜到了
我们先来看看这个_xsrf从哪里来的,打开网页源码,查找_xsrf,发现有一个叫_xsrf的隐藏input标签,值和我们传入的这个参数是一样的
这样,我们就可以直接去取了
除了这个_xsrf外,我们还看到有一个叫captcha的参数,我们猜测它应该就是验证码,我们为了看看这个验证码是如何获得的,刷新一下看看
发现它调了这样一个接口,我们把这个url复制下来,然后直接打开看看~发现正是我们的验证码,我们看这个验证码,他是让我们点击倒立的字,再看我们上传的参数,除了那张图片的大小外,还有一个input_points的参数,应该就是我们点击的点的坐标,服务器通过这个判断我们是否点击了倒立的字,如果我们这样传参数的话,验证码图片的大小我们看上去是固定的,但是这个坐标就比较麻烦了,我们再来分析一下这个请求验证码的url的参数,有3个参数,r,type,lang,最后一个参数好像是表示语言是中文,我们把它变为en验证一下,
发现请求变成了这样一张图片,这不就是直接输入验证码的图片了么~如果可以用这个输入验证码的话我们就可以解决验证码这个参数了
好了,请求的分析差不多就这样了~下面我们可以开始写代码了
先一下我使用的python版本为3.6
新建一个scrapy的项目,新建一个爬虫(以scrapy的base模板新建~另外,这篇文章就做登录的过程,item,pipelines,middleware,settings这些文件就用默认的就行了~)
我们想一下,这个登录的过程中,我们有两个接口需要调用,1是获取验证码,2就是登录,毫无疑问,获取验证码应该优先调用,我们把我们的初始url定为获取验证码,再看一下我们上面验证码接口的参数,有个r的参数,是一串数字,我们优先应该想到是一个和时间有关的参数,我们先用当前时间来试试,我们的入口函数start_requests就变成下面这样
def start_requests(self): t = str(int(time.time() * 1000)) captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + '&type=login&lang=en' return [scrapy.Request(url=captcha_url, headers={}, callback=self.parser_captcha)]
debug 看下我们的回调函数的response
发现服务器返回了500的错误,并未进入我们的回调函数,再去看下我们的网络请求的header,我们知道scrapy对于cookie等一系列值都已经封装好了,但是下面有一个Use-Agent的参数,是需要我们传的,它表示了我们的系统信息以及我们的浏览器信息等一系列信息,我们直接在我们的浏览器复制这个,在我们的header里传进去,再次debug,进入到回调函数里了
看出body是一个二进制文件,我们把文件写入本地看看是不是我们要的验证码图片(注意:这里要用pillow的Image来把图片展示出来),发现我们的猜测都是正确的,打开就是我们的验证码图片了,然后就是读取验证码里的信息问题了,这里就用简单的打开图片我们手动输入的方式,当然,还可以用云打码这种三方平台来读取验证码信息,就可以让爬虫全程不需要人来操作了
接下来,我们就需要去调用登录的接口了,记得前面我们说的参数有个_xsrf的,我们先去取这个参数
_xsrf = response.xpath("//input[@name='_xsrf']/@value").extract_first()
参数都齐了,我们去调接口去~
def login(self, response): xsrf = response.xpath("//input[@name='_xsrf']/@value").extract_first() if xsrf is None: return '' post_url = 'https://www.zhihu.com/login/phone_num' post_data = { "_xsrf": xsrf, "phone_num": 'your phone number', "password": 'your password', "captcha": response.meta['captcha'] } return [scrapy.FormRequest(url=post_url, formdata=post_data, headers=self.header, callback=self.check_login)]
后面还写了个检查登录是否成功的回调
def check_login(self, response): js = json.loads(response.text) if 'msg' in js and js['msg'] == '登录成功': for url in self.start_urls: yield scrapy.Request(url=url, headers=self.header, dont_filter=True)
运行一下我们的爬虫
嗯 ,成功了,接下来就可以去主页上爬取自己感兴趣的内容了
第一次写博客,有很多东西可能描述的也不是很清楚,最后把这个爬虫的完整代码放上来吧
# -*- coding: utf-8 -*- import json import os import scrapy import time from PIL import Image class ZhihuloginSpider(scrapy.Spider): name = 'zhihulogin' allowed_domains = ['www.zhihu.com'] start_urls = ['https://www.zhihu.com/'] Agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36' header = { 'User-Agent': Agent, } def parse(self, response): #主页爬取的具体内容 pass def start_requests(self): t = str(int(time.time() * 1000)) captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + '&type=login&lang=en' return [scrapy.Request(url=captcha_url, headers=self.header, callback=self.parser_captcha)] def parser_captcha(self, response): with open('captcha.jpg', 'wb') as f: f.write(response.body) f.close() try: im = Image.open('captcha.jpg') im.show() im.close() except: print(u'请到 %s 目录找到captcha.jpg 手动输入' % os.path.abspath('captcha.jpg')) captcha = input("please input the captcha\n>") return scrapy.FormRequest(url='https://www.zhihu.com/#signin', headers=self.header, callback=self.login, meta={ 'captcha': captcha }) def login(self, response): xsrf = response.xpath("//input[@name='_xsrf']/@value").extract_first() if xsrf is None: return '' post_url = 'https://www.zhihu.com/login/phone_num' post_data = { "_xsrf": xsrf, "phone_num": 'your phone number', "password": 'your password', "captcha": response.meta['captcha'] } return [scrapy.FormRequest(url=post_url, formdata=post_data, headers=self.header, callback=self.check_login)] # 验证返回是否成功 def check_login(self, response): js = json.loads(response.text) if 'msg' in js and js['msg'] == '登录成功': for url in self.start_urls: yield scrapy.Request(url=url, headers=self.header, dont_filter=True)
相关文章推荐
- session或scrapy实现模拟登录知乎
- 通过scrapy,从模拟登录开始爬取知乎的问答数据
- 使用requests和scrapy模拟知乎登录
- 【python爬虫03】使用Scrapy框架模拟登录知乎
- Scrapy模拟登录知乎
- [uwp]MVVM之MVVMLight,一个登录注销过程的简单模拟
- python--python3爬虫之模拟登录知乎
- HttpClient4.4.1模拟登录知乎
- scrapy模拟登录微博
- 用程序模拟新浪微博登录过程
- JSP+Servlet 无数据库模拟登录过程
- 验证过的模拟登录的方式,结合scrapy和selenium(phantom)
- android模拟登录知乎
- HttpClient4.4 登录知乎(详细过程)
- Python网络爬虫之模拟登录(以知乎为例)
- HttpClient4.4.1模拟登录知乎
- 模拟教务系统登录过程中的一些总结---至今还未成功模拟登录
- python 模拟ef登录过程
- Android(Java) 模拟登录知乎并抓取用户信息