常见http状态码
code | 说明 |
---|---|
200 | 请求成功 |
301/302 | 永久重定向/临时重定向 |
403 | 没有权限访问 |
404 | 没有对应的资源 |
500 | 服务器错误 |
503 | 服务器停机或正在维护 |
要爬取知乎内容首先需要进行登录,在本文中我们主要介绍2种登录方式,第一种是通过requests的session保存cookies进行登录,第二种是通过scrapy
修改start_requests
函数进行登录
在utils中新建zhihu_login.py
,实例化一个session对象,设置其cookies对象为cookiesjar
库中的LWPCookieJar
对象,设置requests库需要用到的headrs(从浏览器中进行拷贝),
session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='zhihu_cookies.txt')
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
'Origin':'https://www.zhihu.com',
'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',
'Host':'www.zhihu.com',
'Referer':'https://www.zhihu.com/'
}
接下来,我们要寻找登录发送数据的页面,首先打开zhihu.com
退出之前的登录,来到一个登录页面,在登陆页面中使用手机号码登录,此时需要发送一个错误的信息给页面,以找到post数据的网页(如果输入正确的账号密码就直接登录成功了,一大堆网页请求就找不到我们需要的网页了)
找到了需要post的网页,发现post的数据有_xsrf
,passoword
,phone_num
,另外一个captcha_type
没有用,加了之后反而无法访问(不知道为什么)
def zhihu_login(account, password):
if re.match('1\d{10}', account):
phone_post_url = 'https://www.zhihu.com/login/phone_num'
post_data={
'_xsrf':get_xsrf(),
'phone_num':account,
'password':password,
# 'captcha_type':'cn'
}
# session_response = session.post(phone_post_url, data=post_data, headers=header)
# print(session_response.text)
# result_list = re.findall('"msg": "(.*?)"',session_response.text)[0]
# print(result_list.encode('utf8').decode('unicode-escape'))
# try:
# login_page = session.post(phone_post_url, data=post_data, headers=headers)
# print('不要验证码,login_code:{}'.format(login_page.status_code))
# except:
post_data['captcha'] = get_captcha()
login_page = session.post(phone_post_url, data=post_data, headers=headers)
result_list = re.findall('"msg": "(.*?)"', login_page.text)[0]
print(result_list.encode('utf8').decode('unicode-escape'))
session.cookies.save()
print('保存成功')
在这里我们一开始没有使用验证码,发现只要是爬虫登录都会被识别到,所以我们编写了一个用于生成验证码的代码:
def get_captcha():
t = str(int(time.time()*1000))
captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
r = session.get(captcha_url, headers=headers)
with open('captcha.jpg','wb') as f:
f.write(r.content)
try:
im = Image.open('captcha.jpg')
im.show()
im.close()
except:
print('wrong')
captcha = input('请输入验证码:')
return captcha
保存完cookies,我们尝试使用这个cookies再次登录
def get_again():
try:
session.cookies.load(ignore_discard=True)
print('cookies加载成功\n')
except:
print('cookies加载失败')
response = session.get('https://www.zhihu.com',headers=headers)
# response.encoding = response.apparent_encoding
with open('my_zhihu_login.html','wb') as f:
f.write(response.text.encode('utf8'))
print('保存页面成功')
查看这个页面发现不停地刷新,暂时还没有找到办法
首先生成一个新的spider,名字为zhihu
在class zhihu中定义headers等信息,重写start_requests
函数
def start_requests(self):
return [scrapy.Request('https://www.zhihu.com/#signin',headers=self.headers, callback=self.login)]
在start_requests
里面返回一个新的Request,其回调函数设置为一个新的login函数如下:
def login(self,response):
# print(response.text)
# a = ''
match_obj = re.match('.*name="_xsrf" value="(.*?)"', response.text, re.DOTALL)
if match_obj:
_xsrf = match_obj.group(1)
post_data = {
'_xsrf': _xsrf,
'phone_num': 'xxxxxxxxxxx',
'password': 'xxxxxxx',
'captcha':''
}
t = str(int(time.time() * 1000))
captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
return [scrapy.Request(url=captcha_url,
meta={'post_data':post_data},
headers=self.headers,
callback=self.get_captcha_login)]
else:
raise EOFError