专栏首页Python爬虫与数据分析Scrapy爬取知乎------模拟登录

Scrapy爬取知乎------模拟登录

从今天开始更新关于爬取知乎的一系列文章,最近一直在优化代码,奈何代理IP有用的都是要钱的,所以已经不知道怎么优化了,发出来大家也参考参考,顺便提点意见。

知乎对于爬虫还是很友好的。所以其实也挺好弄得。

这是知乎刚进来的页面必须要登录。但是有时候是需要验证码而有时候不需要。所以这也需要做一个判断。

我们的最终目标是构建 POST 请求所需的 Headers 和 Form-Data 这两个对象即可。

继续看Requests Headers信息,和登录页面的 GET 请求对比发现,这个 POST 的头部多了三个身份验证字段,经测试x-xsrftoken是必需的。

x-xsrftoken则是防 Xsrf 跨站的 Token 认证,访问首页时从Response HeadersSet-Cookie字段中可以找到。

具体的form-data: 可以参考知乎专栏:https://zhuanlan.zhihu.com/p/34073256

我的代码里没有实现点击倒立汉字的功能,有兴趣的可以去尝试。

def start_requests(self):
    # 进入登录页面,回调函数start_login()
    yield scrapy.Request('https://www.zhihu.com/api/v3/oauth/captcha?lang=en',headers=self.headers,callback=self.start_login, meta={'cookiejar': 1},)  # meta={'cookiejar':1}

这是直接去get它的验证码,URL后面加参数lang=en,他请求到的就会只有英文验证码,不会出现倒立的汉字。

def start_login(self,response):
    # 判断是否需要验证码
   need_cap=json.loads(response.body)['show_captcha']
    # re.search(r'true', resp.text)
    print(need_cap)
    if need_cap:
        print('需要验证码')
        yield scrapy.Request('https://www.zhihu.com/api/v3/oauth/captcha?lang=en',headers=self.headers,callback=self.capture,method='PUT', meta={'cookiejar': response.meta['cookiejar']})

    else:
        print('不需要验证码')
        post_url = 'https://www.zhihu.com/api/v3/oauth/sign_in'
        post_data ={
            'client_id': self.client_id,
            'grant_type': self.grant_type,
            'timestamp': self.timestamp,
            'source': self.source,
            'signature': self.get_signnature(self.grant_type, self.client_id, self.source, self.timestamp),
            'username': '+861777777',
            'password': '123456',
            'captcha': '',
            # 改为'cn'是倒立汉字验证码
            'lang': 'en',
            'ref_source': 'other_',
            'utm_source': ''}
        yield scrapy.FormRequest(url=post_url, formdata=post_data, headers=self.headers, meta={'cookiejar': response.meta['cookiejar']},)

这个函数有点小问题就是每次其实都会请求到验证码,所以有时候不需要验证码也还是要输入,要改进的话需要用正则去匹配响应的TRUE。但是感觉也没啥的,因为基本只需要登录一次,保存cookies就可以了。

def capture(self,response):
    try:
        img = json.loads(response.body)['img_base64']
    except ValueError:
        print('获取img_base64的值失败!')
    else:
        img = img.encode('utf8')
        img_data = base64.b64decode(img)

        with open('zhihu.gif', 'wb') as f:
            f.write(img_data)
            f.close()
    captcha = input('请输入验证码:')
    post_data = {
        'client_id': self.client_id,
        'grant_type': self.grant_type,
        'timestamp': self.timestamp,
        'source': self.source,
        'signature': self.get_signnature(self.grant_type, self.client_id, self.source, self.timestamp),
        'username': '+861777777777',
        'password': '123456',
        'captcha': captcha,
      'lang': 'en',
        'ref_source': 'other_',
        'utm_source': '',
        '_xsrf': '0sQhRIVITLlEX8kQWA09VOqsPlSqRJQT'
    }
    yield scrapy.FormRequest(
        url='https://www.zhihu.com/signin',
        formdata=post_data,
        callback=self.after_login,
        headers=self.headers,
        meta={'cookiejar': response.meta['cookiejar']},
    )
COOKIES_ENABLED = True

在setting.py中修改这个。意思就是使用自己定义的cookie。

def after_login(self, response):
    if response.status == 200:
        print("登录成功")
        """
                登陆完成后从第一个用户开始爬数据                """
        return [scrapy.Request(
            self.start_url,
            meta={'cookiejar': response.meta['cookiejar']},
            callback=self.parse_people,
            errback=self.parse_err,
        )]
    else:
        print("登录失败")

登录成功去请求下一个方法,登录失败可以打印响应的内容或者重新输入,这一部分我没具体写。有问题,有什么需要改进的大家可以留言。

基本到这里就结束了,关于知乎的登录。具体的headers可以去我发的参考链接。看到这了,点个赞再走吧,这个系列会持续更新......

本文分享自微信公众号 - Python爬虫scrapy(python_scrapy),作者:Andrew

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Scrapy爬取知乎------获取用户主页信息

    新建一个scrapy项目,scrapy startproject zhihuspider

    andrew_a
  • 入门机器学习(一)-----------------------感知器

    在人工智能领域,有一个方法叫机器学习。在机器学习方法中有一类算法叫神经网络:

    andrew_a
  • 使用 python 发送邮件

    使用 python 发送邮件,这个也没啥讲的,分享三种方式发送邮件,最后一种三行代码就可以发送邮件,是不是很爽啊,话不多说,直接上代码

    andrew_a
  • 【Code】关于 GCN,我有三种写法

    本篇文章主要基于 DGL 框架用三种不同的方式来实现图卷积神经网络。手机看可能不太方便,可以点击阅读原文,移步到知乎上看(但是我忘了加 = =)。

    阿泽 Crz
  • NLP经典算法复现!CRF原理及实现代码

    寄语:本文先对马尔可夫过程及隐马尔可夫算法进行了简单的介绍;然后,对条件随机场的定义及其三种形式进行了详细推导;最后,介绍了条件随机场的三大问题,同时针对预测问...

    Datawhale
  • 用最小二乘法对多项式进行拟合并可视化

    本篇文章所讲代码是对2018年全国大学生数学建模比赛A题附件的数据进行拟合,代码如下:

    用户3577892
  • PyQt5--QFileDiaglog

    py3study
  • vn.py源码解读(五、主引擎代码分析----CTP模块)

            上一篇文章讲了MainEngine中的初始化函数,重点是DataEngine的讲解。有了对行情数据的处理,还需要有行情数据的来源。在MainEn...

    钱塘小甲子
  • 你的童年有俄罗斯方块吗?教你用 Python 实现俄罗斯方块!

    还是为数不多的游戏类电子产品,对小孩子更是有着不可抗拒的魔力,在当时如果哪个小孩买了一个小游戏机,大伙一定迅速围上去...

    Python小二
  • 里程碑式成果Faster RCNN复现难?我们试了一下 | 附完整代码

    【导读】2019年以来,除各AI 大厂私有网络范围外,MaskRCNN,CascadeRCNN 成为了支撑很多业务得以开展的基础,而以 Faster RCNN ...

    AI科技大本营

扫码关注云+社区

领取腾讯云代金券