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 [ ]
原文地址:https://www.cnblogs.com/eilinge/p/9760024.html