scrapy模拟登陆知乎--抓取热点话题

工具准备

在开始之前,请确保 scrpay 正确安装,手头有一款简洁而强大的浏览器, 若是你有使用 postman 那就更好了。

scrapy genspider zhihu

使用以上命令生成知乎爬虫,代码如下:

# -*- coding: utf-8 -*-
import scrapy

class ZhihuSpider(scrapy.Spider):
    name = ‘zhihu‘
    allowed_domains = [‘www.zhihu.com‘]
    start_urls = [‘http://www.zhihu.com/‘]

    def parse(self, response):
        pass

有一点切记,不要忘了启用 Cookies切记切记 :

# Disable cookies (enabled by default)
COOKIES_ENABLED = True

模拟登陆

过程如下:

  • 进入登录页,获取 Header 和 Cookie 信息,
    完善的 Header 信息能尽量伪装爬虫, 有效 Cookie 信息能迷惑知乎服务端,使其认为当前登录非首次登录,若无有效 Cookie 会遭遇验证码。 在抓取数据之前,请在浏览器中登录过知乎,这样才使得 Cookie 是有效的。
  • 欢迎加入我的QQ群`923414804`与我一起学习,群里有我学习过程中整理的大量学习资料。加群即可免费获取

Header 和 Cookie 整理如下:

headers = {
    ‘Host‘:
    ‘www.zhihu.com‘,
    ‘Connection‘:
    ‘keep-alive‘,
    ‘Origin‘:
    ‘https://www.zhihu.com‘,
    ‘User-Agent‘:
    ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36‘,
    ‘Content-Type‘:
    ‘application/x-www-form-urlencoded; charset=UTF-8‘,
    ‘Accept‘:
    ‘*/*‘,
    ‘X-Requested-With‘:
    ‘XMLHttpRequest‘,
    ‘DNT‘:
    1,
    ‘Referer‘:
    ‘https://www.zhihu.com/‘,
    ‘Accept-Encoding‘:
    ‘gzip, deflate, br‘,
    ‘Accept-Language‘:
    ‘zh-CN,zh;q=0.8,en;q=0.6‘,
}

cookies = {
    ‘d_c0‘:
    ‘"AHCAtu1iqAmPTped76X1ZdN0X_qAwhjdLUU=|1458699045"‘,
    ‘__utma‘:
    ‘51854390.1407411155.1458699046.1458699046.1458699046.1‘,
    ‘__utmv‘:
    ‘51854390.000--|3=entry_date=20160322=1‘,
    ‘_zap‘:
    ‘850897bb-cba4-4d0b-8653-fd65e7578ac2‘,
    ‘q_c1‘:
    ‘b7918ff9a5514d2981c30050c8c732e1|1502937247000|1491446589000‘,
    ‘aliyungf_tc‘:
    ‘AQAAAHVgviiNyQsAOhSntJ5J/coWYtad‘,
    ‘_xsrf‘:
    ‘b12fdca8-cb35-407a-bc4c-6b05feff37cb‘,
    ‘l_cap_id‘:
    ‘"MDk0MzRjYjM4NjAwNDU0MzhlYWNlODQ3MGQzZWM0YWU=|1503382513|9af99534aa22d5db92c7f58b45f3f3c772675fed"‘,
    ‘r_cap_id‘:
    ‘"M2RlNDZjN2RkNTBmNGFmNDk2ZjY4NjIzY2FmNTE4NDg=|1503382513|13370a99ee367273b71d877de17f05b2986ce0ef"‘,
    ‘cap_id‘:
    ‘"NmZjODUxZjQ0NzgxNGEzNmJiOTJhOTlkMTVjNWIxMDQ=|1503382513|dba2e9c6af7f950547474f827ef440d7a2950163"‘,
}
  • 在浏览器中,模拟登陆,抓取登陆请求信息。 

从图中可以看到 _xsrf 参数, 这个参数与登陆验证信息无关,但很明显是由登陆页面携带的信息。 Google了下 xsrf 的含义, 用于防范 跨站请求伪造 。

  • 整理以上,代码如下:

    loginUrl = ‘https://www.zhihu.com/#signin‘
    siginUrl = ‘https://www.zhihu.com/login/email‘
    
    def start_requests(self):
        return [
            scrapy.http.FormRequest(
                self.loginUrl,
                headers=self.headers,
                cookies=self.cookies,
                meta={‘cookiejar‘: 1},
                callback=self.post_login)
        ]
    
    def post_login(self, response):
        xsrf = response.css(
            ‘div.view-signin > form > input[name=_xsrf]::attr(value)‘
        ).extract_first()
        self.headers[‘X-Xsrftoken‘] = xsrf
    
        return [
            scrapy.http.FormRequest(
                self.siginUrl,
                method=‘POST‘,
                headers=self.headers,
                meta={‘cookiejar‘: response.meta[‘cookiejar‘]},
                formdata={
                    ‘_xsrf‘: xsrf,
                    ‘captcha_type‘: ‘cn‘,
                    ‘email‘: ‘[email protected]‘,
                    ‘password‘: ‘xxxxxx‘,
                },
                callback=self.after_login)
        ]

设置Bearer Token

经过上述步骤登陆成功了,有点小激动,有没有! 但苦难到此还远没有结束,这个时候尝试抓取最近热门话题,直接返回 code:401 ,未授权的访问。 授权信息未设置,导致了此类错误,莫非遗漏了什么,看来只能在浏览器中追踪请求参数来侦测问题。 在浏览器的请求中,包含了Bearer Token, 而我在scrapy中模拟的请求中未包含此信息, 所以我被服务器认定为未授权的。 通过观察发现 Bearer Token 的关键部分,就是 Cookies 中的 z_c0 包含的信息。

z_c0 包含的信息,是在登陆完成时种下的,所以从登陆完成返回的登陆信息里,获取要设置的 Cookie 信息, 然后拼接出 Bearer Token,最后设置到 Header 中。

代码整理如下:

def after_login(self, response):
    jdict = json.loads(response.body)
    print(‘after_login‘, jdict)
    if jdict[‘r‘] == 0:
        z_c0 = response.headers.getlist(‘Set-Cookie‘)[2].split(‘;‘)[0].split(
            ‘=‘)[1]
        self.headers[‘authorization‘] = ‘Bearer ‘ + z_c0
        return scrapy.http.FormRequest(
            url=self.feedUrl,
            method=‘GET‘,
            meta={‘cookiejar‘: response.meta[‘cookiejar‘]},
            headers=self.headers,
            formdata={
                ‘action_feed‘: ‘True‘,
                ‘limit‘: ‘10‘,
                ‘action‘: ‘down‘,
                ‘after_id‘: str(self.curFeedId),
                ‘desktop‘: ‘true‘
            },
            callback=self.parse)
    else:
        print(jdict[‘error‘])

获取数据

上述步骤后,数据获取就水到渠成了,为了检测成功与否, 把返回信息写到文件中,而且只获取前五十个,代码如下:

feedUrl = ‘https://www.zhihu.com/api/v3/feed/topstory‘
nextFeedUrl = ‘‘
curFeedId = 0

def parse(self, response):
    with open(‘zhihu.json‘, ‘a‘) as fd:
        fd.write(response.body)
    jdict = json.loads(response.body)
    jdatas = jdict[‘data‘]
    for entry in jdatas:
        entry[‘pid‘] = entry[‘id‘]
        yield entry

    jpaging = jdict[‘paging‘]
    self.curFeedId += len(jdatas)
    if jpaging[‘is_end‘] == False and self.curFeedId < 50:
        self.nextFeedUrl = jpaging[‘next‘]
        yield self.next_request(response)

def next_request(self, response):
    return scrapy.http.FormRequest(
        url=self.nextFeedUrl,
        method=‘GET‘,
        meta={‘cookiejar‘: response.meta[‘cookiejar‘]},
        headers=self.headers,
        callback=self.parse)

最终获取的数据如下图所示:

写在最后

知乎的数据,只有登录完成之后,才可有效的获取,所以模拟登陆是无法忽略不管的。 所谓的模拟登陆,只是在scrapy中尽量的模拟在浏览器中的交互过程,使服务端无感抓包过程。 请求中附加有效的 Cookies 和 Headers 头信息,可有效的迷惑服务端, 同时在交互的过程中,获取后续请求必要信息和认证信息,使得整个流程能不断先前。

原文地址:https://www.cnblogs.com/paisenpython/p/10314012.html

时间: 2024-08-27 21:04:45

scrapy模拟登陆知乎--抓取热点话题的相关文章

爬虫模拟登陆校园网并抓取作业

首先打开校园网的网络教学平台http://eol.zhbit.com/homepage/common/ 找到相应的表单代码 用户名的name是IPT_LOGINUSERNAME 密码的name是IPT_LOGINPASSWORD 提交的地址是http://www.zhbit.com/homepage/common/login.jsp 通过浏览器的抓包发现确实只有这两个数据提交 提交成功后页面变成这样 点击进入 发现地址已经变成http://eol.zhbit.com/main.jsp 所以我们的

网站爬取-案例四:知乎抓取(COOKIE登录抓取个人中心)(第一卷)

有很多网站是需要先登录,才可以浏览的,所以我们这个案例主要讲解如何以登陆的方式抓取这类的页面 第一:http本身是一种无状态的协议 这样两个请求没有任何关系,像淘宝这样的网站需要记录用户的每次请求,来看看有状态的请求 看一下COOKIE本地存储 用户名密码可以存到本地,所以安全性不高,这样就出现了SESSION机制,根据用户名和密码生成SESSIONID,根据SESSIONID请求取出用户要的内容 登陆时产生,退出时清空 看下登陆时 三个字段为ID,加密字段,失效日期,看下登录后的控制台 说到这

HttpClient 模拟登陆知乎

最近做爬虫相关工作,我们平时用HttpWebRequest 比较多,每一个Url都要创建一个HttpWebRequest实例, 而且有些网站验证比较复杂,在登陆及后续抓取数据的时候,每次请求需要把上次的Cookie传递给这次请求. 记得这篇博客(http://www.cnblogs.com/dudu/archive/2013/03/05/httpclient.html)结尾,dudu总结了: HttpClient最与众不同的地方是同一个HttpClient实例可以发出多次请求,每次请求是可以是完

模拟登陆知乎,返回400

模拟登陆知乎后,跳转到首页,返回400,请求无效,应该是知乎对request请求有做要求. 看了下请求头,主要关注cookie.referer和user_agent(不要问为什么,我看视频的),cookie在scrapy.Request里有单独参数.不管怎样,先测试下: # -*- coding: utf-8 -*- import scrapy,os,re from scrapy.http import Request from mouse import move class ZhihuSpid

Scrapy模拟登陆

1. 为什么需要模拟登陆? #获取cookie,能够爬取登陆后的页面 2. 回顾: requests是如何模拟登陆的? #1.直接携带cookies请求页面 #2.找接口发送post请求存储cookie 3. selenium是如何模拟登陆的? #找到对应的input标签,输入文字点击登录 4. 那么对于scrapy来说,也是有两个方法模拟登陆 # 1.直接携带cookie # 2.找到发送post请求的url地址,带上信息,发送请求 1. scrapy模拟登陆之携带cookie 应用场景: 1

运维学python之爬虫高级篇(六)scrapy模拟登陆

上一篇介绍了如何爬取豆瓣TOP250的相关内容,今天我们来模拟登陆GitHub. 1 环境配置 语言:Python 3.6.1 IDE: Pycharm 浏览器:firefox 抓包工具:fiddler 爬虫框架:Scrapy 1.5.0 操作系统:Windows 10 家庭中文版 2 爬取前分析 分析登陆提交信息分析登陆信息我使用的是fiddler,fiddler的使用方法就不作介绍了,大家可以自行搜索,首先我们打开github的登陆页面,输入用户名密码,提交查看fiddler获取的信息,我这

利用scrapy模拟登录知乎

闲来无事,写一个模拟登录知乎的小demo. 分析网页发现:登录需要的手机号,密码,_xsrf参数,验证码 实现思路: 1.获取验证码 2.获取_xsrf 参数 3.携带参数,请求登录 验证码url : "https://www.zhihu.com/captcha.gif?r={t}&type=login&lang=en".format(t=t)  # t 为时间戳 登录界面url : "https://www.zhihu.com/#signin" 手

scrapy爬虫-1-初试页面抓取

本文目标从初建scrapy工程到抓取一个论坛页面,涉及问题: 1.F12页面调试 2.xpath 3.输出抓取数据 创建工程 scrapy [object Object]startproject [object Object]tutorial 代码简单仅需修改items.py,spiders/xianzhenyuan_spider.py  2个文件,先列出代码,后再写调试步骤. items.py # -*- coding: utf-8 -*- import scrapy from scrapy.

python3下scrapy爬虫(第二卷:初步抓取网页内容之直接抓取网页)

上一卷中介绍了安装过程,现在我们开始使用这个神奇的框架 跟很多博主一样我也先选择一个非常好爬取的网站作为最初案例,那么我先用屌丝必备网站http://www.shaimn.com/xinggan/作为这一卷的案例,不用想有图,有字 第一步: 创建爬虫文件: 现在切换到scrapy_test的根目录下: 我们现在创建了爬虫文件,这个网页正常情况下就可以直接抓取,不像糗事啊,天猫啊需要到SETTING里去设置对抗ROBOT cookie user-AGENT这样的反爬手段 现在开始创建代码 现在在终