scrapy模拟登录

学习目标:
  1. 应用 请求对象cookies参数的使用
  2. 了解 start_requests函数的做用
  3. 应用 构造并发送post请求

1. 回顾以前的模拟登录的方法

1.1 requests模块是如何实现模拟登录的?

  1. 直接携带cookies请求页面
  2. 找url地址,发送post请求存储cookie

1.2 selenium是如何模拟登录的?

  1. 找到对应的input标签,输入文本点击登录

1.3 scrapy的模拟登录

  1. 直接携带cookies
  2. 找url地址,发送post请求存储cookie

2. scrapy携带cookies直接获取须要登录后的页面

应用场景
  1. cookie过时时间很长,常见于一些不规范的网站
  2. 能在cookie过时以前把全部的数据拿到
  3. 配合其余程序使用,好比其使用selenium把登录以后的cookie获取到保存到本地,scrapy发送请求以前先读取本地cookie

2.1 实现:重构scrapy的starte_rquests方法

scrapy中start_url是经过start_requests来进行处理的,其实现代码以下python

# 这是源代码
def start_requests(self):
    cls = self.__class__
    if method_is_overridden(cls, Spider, 'make_requests_from_url'):
        warnings.warn(
            "Spider.make_requests_from_url method is deprecated; it "
            "won't be called in future Scrapy releases. Please "
            "override Spider.start_requests method instead (see %s.%s)." % (
                cls.__module__, cls.__name__
            ),
        )
        for url in self.start_urls:
            yield self.make_requests_from_url(url)
    else:
        for url in self.start_urls:
            yield Request(url, dont_filter=True)
复制代码

因此对应的,若是start_url地址中的url是须要登陆后才能访问的url地址,则须要重写start_request方法并在其中手动添加上cookiegit

2.2 携带cookies登录github

测试帐号 noobpythoner zhoudawei123github

import scrapy
import re

class Login1Spider(scrapy.Spider):
    name = 'login1'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/NoobPythoner'] # 这是一个须要登录之后才能访问的页面

    def start_requests(self): # 重构start_requests方法
        # 这个cookies_str是抓包获取的
        cookies_str = '...' # 抓包获取
        # 将cookies_str转换为cookies_dict
        cookies_dict = {i.split('=')[0]:i.split('=')[1] for i in cookies_str.split('; ')}
        yield scrapy.Request(
            self.start_urls[0],
            callback=self.parse,
            cookies=cookies_dict
        )

    def parse(self, response): # 经过正则表达式匹配用户名来验证是否登录成功
        # 正则匹配的是github的用户名
        result_list = re.findall(r'noobpythoner|NoobPythoner', response.body.decode()) 
        print(result_list)
        pass
复制代码
注意:
  1. scrapy中cookie不可以放在headers中,在构造请求的时候有专门的cookies参数,可以接受字典形式的coookie
  2. 在setting中设置ROBOTS协议、USER_AGENT

3. scrapy.Request发送post请求

咱们知道能够经过scrapy.Request()指定method、body参数来发送post请求;可是一般使用scrapy.FormRequest()来发送post请求ajax

3.1 发送post请求

注意:scrapy.FormRequest()可以发送表单和ajax请求,参考阅读 www.jb51.net/article/146…正则表达式

3.1.1 思路分析
  1. 找到post的url地址:点击登陆按钮进行抓包,而后定位url地址为https://github.com/sessionbash

  2. 找到请求体的规律:分析post请求的请求体,其中包含的参数均在前一次的响应中cookie

  3. 否登陆成功:经过请求我的主页,观察是否包含用户名session

3.1.2 代码实现以下:
import scrapy
import re

class Login2Spider(scrapy.Spider):
   name = 'login2'
   allowed_domains = ['github.com']
   start_urls = ['https://github.com/login']

   def parse(self, response):
       authenticity_token = response.xpath("//input[@name='authenticity_token']/@value").extract_first()
       utf8 = response.xpath("//input[@name='utf8']/@value").extract_first()
       commit = response.xpath("//input[@name='commit']/@value").extract_first()
        
        #构造POST请求,传递给引擎
       yield scrapy.FormRequest(
           "https://github.com/session",
           formdata={
               "authenticity_token":authenticity_token,
               "utf8":utf8,
               "commit":commit,
               "login":"noobpythoner",
               "password":"***"
           },
           callback=self.parse_login
       )

   def parse_login(self,response):
       ret = re.findall(r"noobpythoner|NoobPythoner",response.text)
       print(ret)
复制代码
小技巧

在settings.py中经过设置COOKIES_DEBUG=TRUE 可以在终端看到cookie的传递传递过程并发


小结

  1. start_urls中的url地址是交给start_request处理的,若有必要,能够重写start_request函数
  2. 直接携带cookie登录:cookie只能传递给cookies参数接收
  3. scrapy.Request()发送post请求
相关文章
相关标签/搜索