因为现在很多网站为了限制爬虫,设置了为只有登录才能看更多的内容,不登录只能看到部分内容,这也是一种反爬虫的手段,所以这个文章通过模拟登录知乎来作为例子,演示如何通过scrapy登录知乎

在通过scrapy登录知乎之前,我们先通过requests模块登录知乎,来熟悉这个登录过程

不过在这之前需要了解的知识有:

cookie和session
关于cookie和session我之前整理了一篇博客供参考:
http://www.cnblogs.com/zhaof/p/7211253.html
requests模块的会话维持功能:
这个我在 http://www.cnblogs.com/zhaof/p/6915127.html 关于requests模块中也已经做了整理
主要内容如下,详细内容可参考上面那篇关于requests模块使用的文章
会话维持
cookie的一个作用就是可以用于模拟登陆,做会话维持

import requests
s = requests.Session()
s.get("http://httpbin.org/cookies/set/number/123456")
response = s.get("http://httpbin.org/cookies")
print(response.text)

这是正确的写法,而下面的写法则是错误的

import requests
requests.get("http://httpbin.org/cookies/set/number/123456")
response = requests.get("http://httpbin.org/cookies")
print(response.text)

因为这种方式是两次requests请求之间是独立的,而第一次则是通过创建一个session对象,两次请求都通过这个对象访问
关于爬虫常见登录的方法
这里我之前的文章 http://www.cnblogs.com/zhaof/p/7284312.html 也整理的常用的爬虫登录方法
这点是非常重要的

只有上面这些基础的内容都已经掌握,才能完成下面内容

非框架登录知乎

这里我测试的结果是通过爬虫登录知乎的时候必须携带验证码,否则会提示验证码错误,下面是关于如果没有带验证码时候提示的错误,这个错误可能刚开始写登录知乎的时候都会碰到,所以这里我把这段代码贴出来:

import json
import requests
from bs4 import BeautifulSoupheaders = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
}#这里是非常关键的
session = requests.session()def get_index():'''用于获取知乎首页的html内容:return:'''response = session.get("http://www.zhihu.com",headers=headers)return response.textdef get_xsrf():'''用于获取xsrf值:return:'''html = get_index()soup = BeautifulSoup(html,'lxml')res = soup.find("input",attrs={"name":"_xsrf"}).get("value")return resdef zhihu_login(account,password):'''知乎登录:param account::param password::return:'''_xsrf = get_xsrf()post_url = "https://www.zhihu.com/login/phone_num"post_data = {"_xsrf":_xsrf,"phone_num":account,"password":password,}response = session.post(post_url,data=post_data,headers=headers)res = json.loads(response.text)print(res)zhihu_login('13121210484','********')

上述代码当你的用户名和密码都正确的时候最后结果会打印如下内容:

我猜测是可能知乎识别了这是一个爬虫,所以让每次登陆都需要验证码,其实这个时候你正常通过浏览器登陆知乎并不会让你输入验证码,所以这里我们需要获去验证码并将验证码传递到请求参数中,我们分析登录页面就可当登录页需要输入验证码的时候,我们点击验证码会生成新的验证码,抓包分析如下:

这行我们就获得了生成验证码的地址:
https://www.zhihu.com/captcha.gif?r=1503303312357&type=login
这个时候我们登录的时候传递的参数中就会增加captcha参数

所以我们将上面的代码进行更改,添加验证码参数

import json
import requests
from bs4 import BeautifulSoupheaders = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
}#这里是非常关键的
session = requests.session()def get_index():'''用于获取知乎首页的html内容:return:'''response = session.get("http://www.zhihu.com",headers=headers)return response.textdef get_xsrf():'''用于获取xsrf值:return:'''html = get_index()soup = BeautifulSoup(html,'lxml')res = soup.find("input",attrs={"name":"_xsrf"}).get("value")return resdef get_captcha():'''获取验证码图片:return:'''import timet = str(int(time.time()*1000))captcha_url = "https://www.zhihu.com/captcha.gif?r={0}&type=login".format(t)t = session.get(captcha_url,headers=headers)with open("captcha.jpg","wb") as f:f.write(t.content)try:from PIL import Imageim = Image.open("captcha.jpg")im.show()im.close()except:passcaptcha = input("输入验证码>")return captchadef zhihu_login(account,password):'''知乎登录:param account::param password::return:'''_xsrf = get_xsrf()post_url = "https://www.zhihu.com/login/phone_num"captcha = get_captcha()post_data = {"_xsrf":_xsrf,"phone_num":account,"password":password,'captcha':captcha,}response = session.post(post_url,data=post_data,headers=headers)res = json.loads(response.text)print(res)zhihu_login('13121210484','******')

这样我们再次登录就会发现结果如下,表示登录成功:

这里要说明的一个问题是这里的验证码并没有接打码平台,所以是手工输入的。

scrapy登录知乎

我们上面已经通过非框架的模式即requests模块的方式成功登录了知乎,现在就是把上面的代码功能在scrapy中实现,这里有一个非常重要的地方,上面的代码中为了会话维持,我们通过:
session = requests.session()
那么我们如何在scrapy中实现呢?

这里就是通过yield,完整代码如下(这里的爬虫是在scrapy项目里直接生成的一个爬虫):

import json
import reimport scrapy
from urllib import parseclass ZhihuSpider(scrapy.Spider):name = "zhihu"allowed_domains = ["www.zhihu.com"]start_urls = ['https://www.zhihu.com/']headers = {'User-Agent':"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",}def start_requests(self):'''重写start_requests,请求登录页面:return:'''return [scrapy.Request('https://www.zhihu.com/#signin',headers=self.headers,callback=self.login)]def login(self,response):'''先通过正则获取xsrf值,然后通过scrapy.Request请求验证页面获取验证码:param response::return:'''response_text = response.textmatch_obj = re.match('.*name="_xsrf" value="(.*?)"',response_text,re.DOTALL)print(match_obj.group(1))xsrf=''if match_obj:xsrf = match_obj.group(1)if xsrf:post_data = {"_xsrf":xsrf,"phone_num":"13121210484","password":"********",'captcha':'',}import timet = str(int(time.time() * 1000))captcha_url = "https://www.zhihu.com/captcha.gif?r={0}&type=login".format(t)#这里利用meta讲post_data传递到后面的response中yield scrapy.Request(captcha_url,headers=self.headers,meta={"post_data":post_data} ,callback=self.login_after_captcha)def login_after_captcha(self,response):'''将验证码写入到文件中,然后登录:param response::return:'''with open("captcha.jpg",'wb') as f:f.write(response.body)try:from PIL import Imageim = Image.open("captcha.jpg")im.show()except:pass#提示用户输入验证码captcha = input("请输入验证码>:").strip()#从response中的meta中获取post_data并赋值验证码信息post_data = response.meta.get("post_data")post_data["captcha"] = captchapost_url = "https://www.zhihu.com/login/phone_num"# 这里是通过scrapy.FormRequest提交form表单return [scrapy.FormRequest(url=post_url,formdata=post_data,headers=self.headers,callback=self.check_login,)]def check_login(self,response):'''验证服务器的返回数据判断是否成功,我们使用scrapy会自动携带我们登录后的cookie:param response::return:'''text_json = json.loads(response.text)print(text_json)for url in self.start_urls:yield self.make_requests_from_url(url,dont_filter=True,header=self.headers)

上述代码中:

yield scrapy.Request(captcha_url,headers=self.headers,meta={"post_data":post_data} ,callback=self.login_after_captcha)

原本scrapy中的scrapy.Request会保存访问过程中的cookie信息其实这里面也是用也是cookiejar,这里通过yield 的方式实现了与会话的维持
我们通过调试登录,如下,同样也登录成功:

Python爬虫从入门到放弃(二十四)之 Scrapy登录知乎相关推荐

  1. Python爬虫新手入门教学(二十):爬取A站m3u8视频格式视频

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 前文内容 Python爬虫新手入门教学(一):爬取豆瓣电影排行信息 Python爬虫新手入门 ...

  2. python爬虫从入门到实战笔记——第四章Scrapy框架

    推荐阅读: python爬虫从入门到实战笔记--第一章爬虫原理和数据爬取 python爬虫从入门到实战笔记--第二章非结构化数据和结构化数据的提取 python爬虫从入门到实战笔记--第三章动态HTM ...

  3. Python爬虫从入门到放弃(十二)之 Scrapy框架的架构和原理

    原文地址https://www.cnblogs.com/zhaof/p/7173397.html 这一篇文章主要是为了对scrapy框架的工作流程以及各个组件功能的介绍 Scrapy目前已经可以很好的 ...

  4. Python爬虫从入门到放弃(十五)之 Scrapy框架中Spiders用法

    Spider类定义了如何爬去某个网站,包括爬取的动作以及如何从网页内容中提取结构化的数据,总的来说spider就是定义爬取的动作以及分析某个网页 工作流程分析 以初始的URL初始化Request,并设 ...

  5. Python爬虫从入门到放弃(十三)之 Scrapy框架的命令行详解

    这篇文章主要是对的scrapy命令行使用的一个介绍 创建爬虫项目 scrapy startproject 项目名 例子如下: localhost:spider zhaofan$ scrapy star ...

  6. Python爬虫从入门到放弃(十一)之 Scrapy框架整体的一个了解

    这里是通过爬取伯乐在线的全部文章为例子,让自己先对scrapy进行一个整理的理解 该例子中的详细代码会放到我的github地址:https://github.com/pythonsite/spider ...

  7. AutoLisp从入门到放弃(十四)

    AutoLisp从入门到放弃(十四) AutoLisp选择集操作 AutoLisp从入门到放弃(十四) 一.ssget 1.函数说明 2.参数说明 3.代码示例 二.ssadd.ssdel 1.函数说 ...

  8. java从入门到精通二十四(三层架构完成增删改查)

    java从入门到精通二十四(三层架构完成增删改查) 前言 环境准备 创建web项目结构 导入依赖和配置文件 创建层次模型 实现查询 实现添加 实现修改 完成删除 做一个用户登录验证 会话技术 cook ...

  9. GPS从入门到放弃(十四) --- 电离层延时

    GPS从入门到放弃(十四) - 电离层延时 电离层概念 电离层(Ionosphere)是地球大气的一个电离区域.它是受到太阳高能辐射以及宇宙线的激励而电离的大气高层.50千米以上的整个地球大气层都处于 ...

  10. Python爬虫新手入门教学(二):爬取小说

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

最新文章

  1. 人才招聘丨 清华大学精准医学研究院招聘启事
  2. 字符设备编号的注册分配
  3. xwiki[未完成]
  4. bootstrap的栅格布局与两列布局结合使用
  5. centos中bash占用cpu_Docker 多种维度限制容器可用的 CPU
  6. 本周ASP.NET英文技术文章推荐[10/21 – 10/27]
  7. vscode 书签_10个我必备的 VS code 拓展
  8. git回滚命令reset、revert的区别
  9. php ajax实现上移,jquery实现标签上移、下移、置顶_jquery
  10. 扎克伯格公开信:Facebook拥有五大核心价值
  11. 会计凭证BAPI_ACC_DOCUMENT_POST
  12. api质量等级_润滑油的API等级分类新
  13. 全球首个企业云计算平台初探
  14. 牛腩新闻发布系统—错误总结
  15. 【信道编码/Channel Coding】纠错编码与差错控制
  16. matlab函数power,Matlab中Powergui介绍.pdf
  17. sort()与拉姆达表达式
  18. 微信小程序自定义picker多列选择器
  19. Ubuntu下安装KDE
  20. Android Studio 项目依赖由于资源在国外而下载不了的问题

热门文章

  1. linux安装php-redis扩展(转)
  2. UIScrollerView ,UIPageControl混搭使用,添加定时器,无限循环滚动
  3. .NET Framework中的配置文件(config)
  4. SpringBoot学习笔记(15):动态数据源切换
  5. SqlDbx 个人版本使用指定的instant client
  6. 认识JQuery的三天--看视频得到的一些小知识点
  7. 【Go命令教程】11. go vet 与 go tool vet
  8. mysql 分组之后统计记录条数
  9. 财神:如何快速打造一个5万粉的微信公众号
  10. mysql查询时去除重复数据以及 FOUND_ROWS 统计记录函数