爬虫中scrapy模拟登录

410次阅读
没有评论

每日分享: 

有人三分钟泡面,有人三小时煲汤;有人的外卖已送达,而有人才刚切好菜。当你选好了你要的方式,坚定下去,别胡思乱想;我们要走的路不一样,花期也不一样,不必焦虑。

目标:

  1. 应用 请求对象cookies参数的使用
  2. 了解 start_requests函数的作用
  3. 应用 构造并发送post请求

一、回顾之前的模拟登录方法

1.1 requests模块如何实现模拟登录

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

1.2 selenium如何模拟登录

  1. 找到对应的input标签,输入文本(账号密码)点击登录

1.3 scrapy模拟登录(和requests登录思想一致)

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

二、scrapy携带cookies直接获取需要登录后的页面

应用场景:

  1. cookie过期时间很长,常用于一些比较low的网站(对cookie的管理不严)
  2. 能在cookie过期之前把所有的数据拿到
  3. 配合其他程序使用,比如其使用selenium把登录之后的cookie获取保存到本地,scrapy发送请求之前先读取本地cookie

2.1 实现:重构scrapy中的start_requests方法

scrapy中的start_url是通过start_requests来进行处理的,其实现代码如下:

#源代码
def start_requests(self):
    cls = self.__class__
    if not self.start_urls and hasattr(self, 'start_url'):
        raise AttributeError(
            "Crawling could not start: 'start_urls' not found "
            "or empty (but found 'start_url' attribute instead, "
            "did you miss an 's'?)")
    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 "
            f"(see {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)

def make_requests_from_url(self, url):
    """ This method is deprecated. """
    warnings.warn(
        "Spider.make_requests_from_url method is deprecated: "
        "it will be removed and not be called by the default "
        "Spider.start_requests method in future Scrapy releases. "
        "Please override Spider.start_requests method instead."
    )
    return Request(url, dont_filter=True)

所以说,如果start_url地址中的url是需要登录后才能访问的url地址,则需要重写start_request方法并在其中手动添加上cookie

2.2 携带cookies登录github

提示:

cookie要用昵称密码登录,而且最好是没有用验证码,直接登录进去的,之后抓包获取cookie;需要验证码抓包获取的cookie会登录失败

import scrapy


class CgithubSpider(scrapy.Spider):
    name = 'cgithub'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/aoospdk']

    # 重构start_requests方法
    def start_requests(self):
        # 抓包获取的cookie_str
        cookie_str = '登录后抓包获取的cookie'
        # 将cookie_str转化为cookie_dict
        cookie_dict = {data.split('=')[0]: data.split('=')[1] for data in cookie_str.split('; ')}
        yield scrapy.Request(
            url=self.start_urls[0],
            callback=self.parse,
            cookies=cookie_dict
        )
    
    # 输出title,后面没有· GitHub就证明登录成功
    def parse(self, response):
        print('--------------', response.xpath('/html/head/title/text()').extract_first())

注意:

  1. scrapy中cookie不能够放在headers中,在构造请求的时候有专门的cookies参数,能够接收字典形式的cookie
  2. 要在setting中注释ROBOTS协议,并且打开注释USER_AGENT(要把内容替换为自己的user-agent)

爬虫中scrapy模拟登录

结果: 

爬虫中scrapy模拟登录

可以看到,输出后面没有· GitHub,证明登录成功

 三、scrapy.Request发送post请求

可以通过scrapy.Request()指定method、body参数来发送post请求;但通常使用scrapy.FormRequest()来发送post请求

  1. 找到post的url地址:抓包获取
  2. 找到请求体规律:分析post请求中的数据,构建post_data
  3. 判断是否登录成功:看title

代码框架如下:

import scrapy


class Cgithub2Spider(scrapy.Spider):
    name = 'cgithub2'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/session']

    def parse(self, response):
        # 登录页面解析出post数据
        post_data = {
            ""
        }
        # 使用FormRequest发送post请求
        yield scrapy.FormRequest(
            url='https://github.com/session',
            callback=self.after_login,
            formdata=post_data
        )
        
    # 发送get请求
    def after_login(self):
        yield scrapy.Request(url='https://github.com/aoospdk', callback=self.cheak_login)
        
    # 输出title
    def cheak_login(self, response):
        print('--------------', response.xpath('/html/head/title/text()').extract_first())

可以在settings.py中通过设置COOKIES_DEBUG=true  能够在终端看到cookie的传递过程

总结:

  1. start_urls中的url地址是交给start_requests处理的,如果有必要,可以重写start_request函数
  2. 直接携带cookie登录:cookie只能传递给cookies参数接收
  3. scrapy.FormRequest()发送post请求
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:Python教程2022-10-19发表,共计3446字。
新手QQ群:570568346,欢迎进群讨论 Python51学习