• scrapy--Cookies


      大家好,之前看到的关于cookies的应用,由于有段时间没看,再看的时候花了一些时间,来给大家总结下。本文是根据:"http://www.bubuko.com/infodetail-2233980.html"基础上加了一些自己遇到的问题,希望能帮助到大家,那我们开始!!

    一: 先上一些干货,稍微做些前期知识储备:

    HTTP 请求方法:GET 和 POST(提交的方式)
        GET - 从指定的资源请求数据。
        POST - 向指定的资源提交要被处理的数据
        
    Cookie和session(存储的方式)
        1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
        2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
           考虑到安全应当使用session。
        3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
           考虑到减轻服务器性能方面,应当使用COOKIE。
        4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
        
        cookie - (name,value,domain,path,secure,expire(过期时间))
                根据用户名,密码,标识用户
        session - session_id+cookie
                根据session_id,标识用户,发送用户名和密码
        
        本来 session 是一个抽象概念,开发者为了实现中断和继续等操作,将 user agent 和 server  之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。 
        而 cookie 是一个实际存在的东西,http 协议中定义在 header 中的字段。可以认为是 session 的一种后端无状态实现。
        session 因为 session id 的存在,通常要借助 cookie 实现
        

    Scrapy模拟浏览器登录 

    scrapy的基本请求流程:
        1.start_request                        遍历start_urls列表
        2.make_requests_from_url         执行Request方法,请求start_urls里面的地址(post--登录)
        
    快速登录的方法:
      1.改写start_request,直接GET登录页面的html信息(登录的账户,密码,怎么提交,提交到哪)
        <form action="#" enctype="application/x-www-form-urlencoded" method="post">
            <tr id="auth_user_email__row">
            <tr id="auth_user_password__row">
            <tr id="auth_user_remember_me__row">
            <tr id="submit_record__row">
                <td class="w2p_fw">
                    <input type="submit" value="Log In" class="btn">
                    <button class="btn w2p-form-button" onclick="window.location='/places/default/user/register';return false">Register</button>
                </td>
            </tr>
            </tr>
            </tr>
            </tr>
        </form>    

      2.start_request方法GET到数据后,用callback参数,执行拿到response后要接下来执行哪个方法,然后在login方法里面写入登录用户名和密码

      3、parse_login方法是提交完表单后callback回调函数指定要执行的方法,为了验证是否成功。这里我们直接在response中搜索Welcome Liu这个字眼就证明登录成功。
      这个好理解,重点是yield from super().start_resquests(),这个代表着如果一旦登录成功后,就直接带着登录成功后Cookie值,方法start_urls里面的地址。
      这样的话登录成功后的response可以直接在parse里面写。

    Cookie登录:

        start_requests()方法,可以返回一个请求给爬虫的起始网站,这个返回的请求相当于start_urls,start_requests()返回的请求会替代start_urls里的请求
    
        Request()get请求,可以设置,url、cookie、回调函数
    
        FormRequest.from_response()表单post提交,第一个必须参数,上一次响应cookie的response对象,其他参数,cookie、url、表单内容等
    
        yield Request()可以将一个新的请求返回给爬虫执行
    
        在发送请求时cookie的操作,
        meta={'cookiejar':1}表示开启cookie记录,首次请求时写在Request()里
        meta={'cookiejar':response.meta['cookiejar']}表示使用上一次response的cookie,写在FormRequest.from_response()里post授权
        meta={'cookiejar':True}表示使用授权后的cookie访问需要登录查看的页面
    
        获取Scrapy框架Cookies
    
        请求Cookie
        Cookie = response.request.headers.getlist('Cookie')
        print(Cookie)
    
        响应Cookie
        Cookie2 = response.headers.getlist('Set-Cookie')
        print(Cookie2)

    二: 现在给大家开始代码:

    spider/pach.py

    # -*- coding: utf-8 -*-
    import scrapy
    from scrapy.http import Request,FormRequest
    from Pach.settings import USER_AGENT
    import pdb
    
    class PachSpider(scrapy.Spider):                            #定义爬虫类,必须继承scrapy.Spider
        name = 'pach'                                           #设置爬虫名称
        allowed_domains = ['edu.iqianyue.com']                  #爬取域名
        # start_urls = ['http://edu.iqianyue.com/index_user_login.html']     #爬取网址,只适于不需要登录的请求,因为没法设置cookie等信息
    
        header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'}  #设置浏览器用户代理
        '''
        headers = {
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.8',
            'Connection': 'keep-alive',
            'Content-Length': '11',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Host': 'edu.iqianyue.com',
            'Origin': 'edu.iqianyue.com',
            #'Referer': 'http://www.dy2018.com/html/tv/oumeitv/index.html',
            'User-Agent': USER_AGENT,
            'X-Requested-With': 'XMLHttpRequest',
    
        }
        '''
    
        def start_requests(self):       #用start_requests()方法,代替start_urls
            """第一次请求一下登录页面,设置开启cookie使其得到cookie,设置回调函数"""
            yield Request('http://edu.iqianyue.com/index_user_login.html',meta={'cookiejar':1},callback=self.parse)
    
        def parse(self, response):      #parse回调函数
    
            data =  {                    #设置用户登录信息,对应抓包得到字段
                'number':'xxxxx',
                'passwd':'xxxx',
                'submit':''
                    }
            # 响应Cookie
            Cookie1 = response.headers.getlist('Set-Cookie')   #查看一下响应Cookie,也就是第一次访问注册页面时后台写入浏览器的Cookie
            print('cookie1',Cookie1)
            """第二次用表单post请求,携带Cookie、浏览器代理、用户登录信息,进行登录给Cookie授权"""
            yield FormRequest.from_response(response,
                                              url='http://edu.iqianyue.com/index_user_login.html',   #真实post地址
                                              meta={'cookiejar':response.meta['cookiejar']},
                                              headers=self.header,
                                              formdata=data,
                                              callback=self.next,
                                            )
        def next(self,response):
            """登录后请求需要登录才能查看的页面,如个人中心,携带授权后的Cookie请求"""
            yield Request('http://edu.iqianyue.com/index_user_index.html',meta={'cookiejar':True},callback=self.next2)
    
        def next2(self,response):
            # 请求Cookie
            #Cookie2 = response.request.headers.getlist('Cookie')
            #print(Cookie2)
            body = response.body  # 获取网页内容字节类型
            unicode_body = response.body_as_unicode()  # 获取网站内容字符串类型
            a = response.css('div.col-md-4.column ::text').extract()[2]
            #a = response.css('div#panel-54098 h2::text').extract()  #得到个人中心页面
            print(a)

    设置代理:

    middlewares.py

    class PachSpiderMiddleware(object):
        # Not all methods need to be defined. If a method is not defined,
        # scrapy acts as if the spider middleware does not modify the
        # passed objects.
        def __init__(self, ip=''):
            self.ip = ip
    def process_request(self, request, spider): print('http://10.240:911') request.meta['proxy'] = 'http://10.240:911'

    settings.py

    USER_AGENT ={       #设置浏览器的User_agent
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
    }
    
    ROBOTSTXT_OBEY = False
    CONCURRENT_REQUESTS = 16
    DOWNLOAD_DELAY = 0.5
    #COOKIES_ENABLED = False
    
    DOWNLOADER_MIDDLEWARES = {
        #'Pach.middlewares.PachDownloaderMiddleware': 543,
        'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 543,
        'Pach.middlewares.PachSpiderMiddleware': 125,
    }
    
    ITEM_PIPELINES = {
        'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware':1,
        #'Pach.pipelines.PachPipeline': 300,
    }

    三: 需要注意的点

    #COOKIES_ENABLED = False    
    | COOKIES_ENABLED = True
    #settings.py 将cookies开启,才能获取登录成功后的信息,能够获取请求response.request.headers的"Cookie",无法获取response.headers的"Set-Cookie"
    
    #settings.py 将cookies禁用,无法获取登录成功后的信息,无法获取请求response.request.headers的"Cookie",能够获取response.headers的"Set-Cookie"
    
    (Pdb) response.request.headers
    {'Accept-Language': ['en'], 'Accept-Encoding': ['gzip,deflate'], 'Accept': ['text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'], 
    'User-Agent': ['Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'], 'Referer': ['http://edu.iqianyue.com/index_user_login.html'],
    'Cookie': ['PHPSESSID=2jhiv5fdb3rips83928mf5gaq2'], 'Content-Type': ['application/x-www-form-urlencoded']} (Pdb) response.headers {'Via': ['1.1 shzdmzpr03'], 'X-Powered-By': ['PHP/5.6.36'], 'Expires': ['Thu, 19 Nov 1981 08:52:00 GMT'], 'Server': ['Apache/2.4.6 (CentOS) PHP/5.6.36'],
    'Pragma': ['no-cache'], 'Cache-Control': ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'], 'Date': ['Tue, 09 Oct 2018 05:17:14 GMT'],
    'Content-Type': ['text/html; charset=utf-8']} -> a = response.css('div#panel-54098 h2::text').extract() (Pdb) c [u' u6211u7684u57fau672cu4fe1u606f ',
    u' u6211u5b66u4e60u7684u8bfeu7a0bu6570u91cf ',
    u' u6211u8d2du4e70u7684u8bfeu7a0bu6570u91cf '] COOKIES_ENABLED = False (Pdb) response.request.headers {'Accept-Language': ['en'], 'Accept-Encoding': ['gzip,deflate'], 'Accept': ['text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'],
    'User-Agent': ['Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'], 'Referer': ['http://edu.iqianyue.com/index_user_login.html'],
    'Content-Type': ['application/x-www-form-urlencoded']} (Pdb) response.headers {'Via': ['1.1 shzdmzpr03'], 'X-Powered-By': ['PHP/5.6.36'], 'Set-Cookie': ['PHPSESSID=0bjvnkfom3q9c9u878f0aauvi4; path=/'],
    'Expires': ['Thu, 19 Nov 1981 08:52:00 GMT'], 'Server': ['Apache/2.4.6 (CentOS) PHP/5.6.36'], 'Pragma': ['no-cache'],
    'Cache-Control': ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'], 'Date': ['Tue, 09 Oct 2018 05:20:23 GMT'],

    'Content-Type': ['text/html; charset=utf-8']} -> a = response.css('div#panel-54098 h2::text').extract() (Pdb) c [ ]
  • 相关阅读:
    宋宝华: 文件读写(BIO)波澜壮阔的一生【转】
    内核工具 – Sparse 简介【转】
    【java】JSON.toJSONString 空对象也可以转化为JSON字符串
    Seata分布式事务简单使用
    Mixin 工作原理
    公链
    公链
    公链
    公链
    公链
  • 原文地址:https://www.cnblogs.com/eilinge/p/9760024.html
Copyright © 2020-2023  润新知