---恢复内容开始---html
在完成前面的阶段的任务以后,咱们如今已经可以尝试着去模拟登陆一些网站了。在这里咱们模拟登陆一下知乎作一下实验。笔者在这里总共用了三天多的时间,下面给你们分享一下笔者是怎么一步一步的模拟登陆成功的。也但愿你们可以吸收个人教训。
初步的模拟登陆
下面这段代码是笔者最初写的,咱们慢慢来看
import
requests
from bs4 import BeautifulSoup as bs
ssesion = requests.session()
headers = {
'Connection': 'keep-alive',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
'Accept-Encoding': 'gzip, deflate, sdch',
'Host': 'www.zhihu.com',
}
login_data = {'username': '', # 替换为帐号
'password': '', # 替换为密码
'remember_me': 'true',
'Referer': 'https://www.baidu.com/',
}
response = bs(requests.get('http://www.zhihu.com/#signin').content, 'html.parser')
xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
login_data['_xsrf'] =xsrf
responed = ssesion.post('http://www.zhihu.com/login/email',headers=headers,data=login_data)
print(responed)
在最初的写模拟登陆知乎的时候,笔者也是经过抓包,发现了,cookie中有一个_xsrf的属性,相似于token的做用。而这个东西的存在,就让咱们在模拟登陆的时候,必须将这个属性做为参数一块儿加在请求中发送出去,那么怎么得到这个东西呢?彷佛又是一个问题。
我想到的方法,就是随便访问一个页面,而后再页面元素中去定位到_xsrf这个字段,而后抓取下来,添加到data里,在请求的时候一块儿发出去就能够了。
而后为何会去用ssesion去请求,由于在知乎上,它的xsrf是一直在变化的,咱们每一次请求,它都在变。因此若是咱们用requests去请求的话,就没法登陆成功。
那么上面这段代码基本已经符合咱们的要求了。咱们运行看一下结果
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/Practice/Login_zhihu.py", line 20, in <module>
xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
TypeError: 'NoneType' object is not subscriptable
报错了,获取到的xsrf是空的,怎么办呢?嗯,根据这里的报错信息显示应该是类型错误,那就是获取xsrf那一段有错,咱们单独把那一段代码拿出去运行看看结果。
定位并修复报错信息
既然知道了错误缘由咱们就去看看,究竟是哪儿错了,要怎么解决。
首先,我单独的把获取xsrf那一段代码拿出来运行
import requests
from bs4 import BeautifulSoup as bs
response = bs(requests.get('http://www.zhihu.com/#signin').content, 'html.parser')
print(response)
xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
print(xsrf)
在这里,分开进行打印,以便查看究竟是走到哪一步出的错。
运行这一段代码获得结果以下显示:
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/Practice/Login_zhihu.py", line 6, in <module>
xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
TypeError: 'NoneType' object is not subscriptable
<html><body><h1>500 Server Error</h1>
An internal server error occured.
</body></html>
在这里报了500,也就是说咱们在get请求的那里就已经出错了,而后下方的xsrf也没有获取到。在这里我首先想到的是先解决爬取的xsrf为空的问题,这里实际上走入了一个误区。之因此会爬取xsrf失败,其实是因为在请求的时候就失败了,致使根本获取不到xsrf。因此应该是解决500的问题先。
那么怎么解决500问题呢?
通过前辈的教导,我在请求后面加上了headers,再次运行
import requests
frombs4importBeautifulSoupasbs
headers = {
'Connection':'keep-alive',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language':'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent':'Mozilla/5.0 (
Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
'Accept-Encoding':'gzip, deflate, sdch',
'Host':'www.zhihu.com',
}
login_data = {'username':'',# 替换为帐号
'password':'',# 替换为密码
'remember_me':'true',
'Referer':'https://www.baidu.com/',
}
response = bs(requests.get('http://www.zhihu.com/#signin',headers=headers).content,'html.parser')
xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
print(xsrf)
好的,在运行看看:
899ce2556d7e705ca9bbf2b818a48d40
好的,这里咱们能够看到是成功的爬取到了xsrf的信息,那么咱们将这段代码在拿到以前的模拟登陆的代码中去看看。
成功模拟登陆知乎
import requests
from bs4 import BeautifulSoup as bs
ssesion = requests.session()
headers = {
'Connection': 'keep-alive',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
'Accept-Encoding': 'gzip, deflate, sdch',
'Host': 'www.zhihu.com',
}
login_data = {'username': '', # 替换为帐号
'password': '', # 替换为密码
'remember_me': 'true',
'Referer': 'https://www.baidu.com/',
}
response = bs(requests.get('http://www.zhihu.com/#signin',headers=headers).content, 'html.parser')
xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
login_data['_xsrf'] =xsrf
responed = ssesion.post('http://www.zhihu.com/login/email',headers=headers,data=login_data)
print(responed)
运行这段代码获得的结果是
<Response [200]>
返回状态为200,说明咱们已经模拟登陆成功了。经历过蛮多挫折哈,光是错误定位那一起,我就折腾了整整一个晚上,还请教了好几个程序员都没有搞定。这里提醒你们一下,可千万不要犯我这样的错误咯。在作爬虫的时候,必定要记得请求的时候加上头信息。
---恢复内容结束---程序员