当前位置: 首页 > 后端技术 > Python

使用Python模拟登录知乎

时间:2023-03-26 19:40:41 Python

环境和开发工具。在抓包的时候,我开始使用Chrome开发工具中的Network,但是抓不到数据。后来用Fiddler成功抓取数据。下面将逐步详细说明上述过程。在模拟知乎登录之前??,我们先了解一下本案例使用的环境和工具:Windows7+Python2.75Chrome+Fiddler:用于监听客户端和服务端的通信,寻找相关参数的位置。仿真过程概述使用谷歌浏览器结合Fiddler监控客户端与服务端的通信过程;根据监控结果,构造请求服务器过程中传递的参数;使用Python模拟参数传递过程。客户端与服务端通信过程中的几个关键点:登录时的url地址获取登录时提交的参数[params]主要有两种方式:首先分析页面源码,找到表单标签和属性。适应更简单的页面。二、使用抓包工具查看提交的url和参数,一般使用Chrome的开发者工具中的Network、Fiddler等。登录后重定向的URL。参数探究首先看这个登录页面,就是我们登录时的url地址。看到这个页面,我们也可以大致猜到请求服务器时传递了几个字段。显然,有:用户名、密码、验证码和“记住我”。那么什么是实际的呢?下面我们来分析一下。先查看HTML源码,可以用CTRL+U在Google里查看,然后用CTRL+F输入input,看看有哪些字段值。具体如下:通过源码我们可以看到,请求服务端的过程中还携带了一个隐藏字段“_xsrf”。那么现在的问题是:这些参数在传递的时候是以什么名称传递的呢?这就需要使用其他工具来抓包进行分析。笔者是Windows系统,我这里使用的是Fiddler(当然你也可以用其他的)。抓包过程比较繁琐,因为抓到的东西很多,很难快速找到需要的信息。关于fiddler,非常好用。不知道的可以百度一下。为了防止其他信息干扰,我们先清除fiddler中的记录,然后输入用户名(笔者使用邮箱登录),密码等信息进行登录,在fiddler中会出现如下对应结果:备注:如果是手机登录,fiddler中对应的url是"/login/phone_num"。为了查看详细的请求参数,我们左键点击单机“/login/email”,可以看到如下信息:请求方式为POST。从Data可以看出,对应的字段名如下:_xsrfcaptchaemailpasswordremember这五个字段,代码中的email、password、captcha都是手动输入的,remember初始化为true。剩下的_xsrf,可以根据登录页面的源文件,将input作为_xsrf的值。对于验证码,您需要通过额外的请求。固定点查看源码可以看到链接:链接省略了ts(经测试,可以省略)。现在,该代码可用于模拟登录。模拟源码笔者在写代码实现知乎登录的过程中,将部分功能封装成一个简单的类WSpider以供复用,文件名为WSpider.py。#-*-编码:utf-8-*-"""创建于ThuNov0214:01:172016@author:liudiwei"""importurllibimporturllib2importcookielibimportloggingclassWSpider(object):def__init__(self):#initparamsself.url_path=Noneself.post_data=Noneself.header=Noneself.domain=Noneself.operate=None#initcookieself.cookiejar=cookielib.LWPCookieJar()self.opener.opener.opener.HTTPCookieProcessor(self.cookiejar))urllib2.install_opener(self.opener)defsetRequestData(self,url_path=None,post_data=None,header=None):self.url_path=url_pathself.post_data=post_datamlself.header=headerdefgetHt(self,is_cookie=False):如果self.post_data==None和self.header==None:request=urllib2.Request(self.url_path)else:request=urllib2.Request(self.url_path,urllib.urlencode(self).post_data),self.header)response=urllib2.urlopen(request)ifis_cookie:self.operate=self.opener.open(request)resText=response.read()返回resText将验证码保存到本地def保存验证码到本地def保存验证码saveCaptcha(self,captcha_url,outpath,save_mode='wb'):picture=self.opener.open(captcha_url).read()#使用openr访问验证码地址,获取cookielocal=open(outpath,save_mode)local.write(picture)local.close()defgetHtml(self,url):page=urllib.urlopen(url)html=page.read()returnhtml"""功能:输出文本内容到本地@paramscontent:text内容out_path:输出路径"""defoutput(self,content,out_path,save_mode="w"):fw=open(out_path,save_mode)fw.write(content)fw.close()"""#EXAMPLELogger=创建('mylogger','temp/logger.log')logger.debug('loggerdebugmessage')logger.info('loggerinfomessage')logger.warning('loggerwarningmessage')logger.error('loggererrormessage')logger.critical('loggercriticalmessage')"""defcreateLogger(self,logger_name,log_file):#创建一个记录器logger=logging.getLogger(logger_name)logger.setLevel(logging.INFO)#创建一个用于写入日志文件的处理程序fh=logging.FileHandler(log_file)andler#创建另一个,用于输出到控制台ch=logging.StreamHandler()#定义handler的输出格式formatterformatter=logging.Formatter('%(asctime)s|%(name)s|%(levelname)s|%(message)s')fh.setFormatter(formatter)ch.setFormatter(formatter)#Addhandlertologgerlogger.addHandler(fh)logger.addHandler(ch)Hulogreturnlogger关于zhipy源码中的模拟登录,如下:#-*-coding:utf-8-*-"""创建于ThuNov0217:07:172016@author:liudiwei"""importurllibfromWSpiderimportWSpiderfrombs4importBeautifulSoupasBSimportgetpassimportjsonimportWLoggerasWLog"""2016.11.03验证码问题暂时无法正常登录2016.11.04登录成功,验证码错误返回时出现如下问题:{"r":1,"errcode":1991829,"data":{"captcha":"验证码错误"},"msg":"验证码错误"}验证码过期:{"r":1,"errcode":1991829,"data":{"captcha":"验证码响应无效:(","name":"ERR_VERIFY_CAPTCHA_SESSION_INVALID"},"msg":"验证码响应无效:("}Login:{"r":0,"msg":"登录成功"}"""defzhiHuLogin():spy=WSpider()logger=spy.createLogger('mylogger','temp/logger.log')homepage=r"https://www.zhihu.com/"html=spy.opener.open(homepage).read()soup=BS(html,"html.parser")_xsrf=soup.find("输入",{'type':'hidden'}).get("value")#根据邮箱和手机登录获取的参数名称,邮箱登录传递的参数为'email',手机登录传递的参数为'phone_num'username=raw_input("Pleaseinputusername:")password=getpass.getpass("Pleaseinputyourpassword:")account_name=Noneif"@"inusername:account_name='email'else:account_name='phone_num'#保存验证码logger.info("savecaptchatolocalmachine.")captchaURL=r"https://www.zhihu.com/captcha.gif?type=login"#验证码urlspy.saveCaptcha(captcha_url=captchaURL,outpath="temp/captcha.jpg")#temp目录需要手动创建#请求参数列表post_data={'_xsrf':_xsrf,account_name:用户名,'password':密码,'remember_me':'true','captcha':raw_input("Pleaseinputcaptcha:")}#请求头内容={'':'*/*','Content-Type':'application/x-www-form-urlencoded;charset=UTF-8','X-Requested-With':'XMLHttpRequest','Referer':'https://www.zhihu.com/','Accept-Language':'en-GB,en;q=0.8,zh-CN;q=0.6,zh;q=0.4','Accept-Encoding':'gzip,deflate,br','User-Agent':'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/53.0.2785.116Safari/537.36','Host':'www.zhihu.com'}url=r"https://www.zhihu.com/login/"+account_namespy.setRequestData(url,post_data,header)resText=spy.getHtmlText()jsonText=json.loads(resText)ifjsonText["r"]==0:logger.info("登录成功!")else:logger.error("登录失败!")logger.error("错误信息--->"+jsonText["msg"])text=spy.opener.open(homepage).read()#重新打开首页,查看源码,可以看到此时已经登录了spy.output(text,"out/home.html")#out目录需要手动创建if__name__=='__main__':zhiHuLogin()源码分析,可以参考代码中的注释运行结果在控制台运行pythonzhiHuLogin.py,然后按照提示输入相应的内容,最后可以得到如下不同的结果(举三个例子):结果一:密码错误结果二:验证码错误结果3:登录成功通过代码,就可以成功登录知乎了,之后如果要爬取知乎里面的内容,就更方便了。想了解更多专业的Python技术知识,请上gzh【Python编程学习圈】,每天都有技术干货分享,还有海量Python学习资料和教程可以免费获取。对Python感兴趣的朋友可以去了解更多看看~