还没有写过博客,这个就算是给自己开个头吧。最近对Python爬虫比较感兴趣,刚刚入了门,就准备先模拟登陆知乎感受一下,过程也是挺艰辛的,就记录一下吧。
想想只要给用户名、密码、验证码然后Post一下就可以开开心心的登陆进去了,于是就抓紧行动起来。
Step 1:打开知乎登陆页面,准备登陆。
https://www.zhihu.com/#signin #知乎登陆页面
这里我登录输入的验证码采用手动方式,即通过保存上面登陆页面的验证码到本地,然后手动输入。于是动手准备获取<img>
标签下的src属性值,就是下面图里的src。快快编了一小段代码发现我果然图样了,获取到的src竟然是None。后来查找原因发现,虽然在开发者工具中可以看到<img>
的src属性值,但其实验证码是动态生成的,于是抓包找到登陆页面请求的验证码图片地址,下面是编写的代码和欺骗了我的图。
#该url用于打开知乎登陆页面
url = 'https://www.zhihu.com/#signin'
res = self.session.get(url)
print res.content
这个是我们真正要去请求图片验证码的地址。
#参数r返回的当前时间,第二个参数为登陆类型
https://www.zhihu.com/captcha.gif?r=1471097787070&type=login
Step 2:获取图片验证码
# 该captcha_url用于打开知乎验证码图片
captcha_url = 'https://www.zhihu.com/captcha.gif?r=%d&type=login' % (time.time() * 1000)
def save_captcha(self, captcha_url):
res = self.session.get(captcha_url)
filename = 'zhihu_captcha.jpg'
with open(filename, 'wb') as f:
f.write(res.content)
这样一来就搞定了验证码的问题,下面就可以考虑输入用户名、密码、验证码去登陆了,通过抓包发现,登陆知乎需要下面的参数,也就是除了用户名、密码、验证码外还有个_xsrf和remember_me,这里主要是获取_xsrf参数,发现html源代码里就有_xsrf参数,不用到别的页面去取喽!
# 获取xsrf参数
xsrf = _get_xsrf(res.content)
#获取知乎的xsrf字段
def _get_xsrf(html):
class XSRFParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.xsrf = None
def handle_starttag(self, tag, attrs):
if tag=='input' and _attr('name',attrs)=='_xsrf':
self.xsrf = _attr('value',attrs)
xsrfParser = XSRFParser()
xsrfParser.feed(html)
return xsrfParser.xsrf
#自己实现的_arrr获取html属性用
def _attr(attrname, attrs):
for attr in attrs:
if attr[0]==attrname:
return attr[1]
return None
Step 3:登陆知乎
验证码有了,_xsrf有了,这下终于可以登录了,真正接收用户名、密码等参数的是下面这个链接,邮箱登录的话应该是/email
post_url = 'https://www.zhihu.com/login/phone_num'
构造好我的HTTP头和要Post的数据准备登陆。
phone_num = '你注册时的手机号'
password = '你的密码'
post_url = 'https://www.zhihu.com/login/phone_num'
headers = {'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, sdch, br',
'Accept-Language':'zh-CN,zh;q=0.8',
'Connection':'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
'X-Xsrftoken':xsrf
}
data = {'_xsrf':xsrf,
'phone_num':phone_num,
'password':password,
'remember_me':'false',
'captcha':captcha
}
post_res = self.session.post(post_url, data=data, headers=headers)
print post_res.content
虽然代码写的丑,但是终于看到服务器返回正确的结果了,Nice。(按耐不住我激动的内心啊)
{"r":0,
"msg": "\u767b\u5f55\u6210\u529f"
}
当然最重要的还是登陆失败的过程:
登陆时总是会出现”errcode”: 1991829,ERR_VERIFY_CAPTCHA_SESSION_INVALID
可能原因有以下几个:
1.访问知乎时构造的HTTP头没有修改,比如没有修改User-Agent
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}
2.访问知乎图片验证码时没加type=login参数,这个很重要。