三、scrapy爬虫框架——scrapy模拟登陆

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来进行处理的,其实现代码如下

# 这是源代码
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方法并在其中手动添加上cookie

2.2 携带cookies登陆github

测试账号 noobpythoner zhoudawei123

  • myCode
import scrapy
# 失败!!!!!!!!!!!!class Git1Spider(scrapy.Spider):name = 'git1'allowed_domains = ['github.com']start_urls = ['https://github.com/zep03']# 重写start_request()方法def start_request(self):url = self.start_urls[0]temp = '_octo=GH1.1.838083519.1594559947; _ga=GA1.2.1339438892.1594559990; _gat=1; tz=Asia%2FShanghai; _device_id=4d76e456d7a0c1e69849de2655198d40; has_recent_activity=1; user_session=e6aK8ODfFzCDBmDG72FxcGE17CQ3FiL23o; __Host-user_session_same_site=e6aK8ODfFzCDBmDTZMReW2g3PhRJEG72FxcGE17CQ3FiL23o; logged_in=yes; dotc'# split()将字符串按照;号进行切割,装进一个列表中# 通过字典生成式把cookie字符串转换成一个字典cookies = {data.split('=')[0]:data.split('=')[-1]  for data in temp.split(';')}print(cookies)# headers = {#     'Referer': 'https://github.com/login?return_to=%2Fzep03',#     # 'Host': 'github.com'#     'If-None-Match':'W/"f3d499ffda61143f54d8e48cb050e43d"'# }yield scrapy.Request(url = url,callback=self.parse,cookies=cookies# headers=headers)def parse(self, response):print(response.xpath('/html/head/title/text()').extract_first())
import scrapy
import reclass 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_dictcookies_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请求

3.1 发送post请求

注意:scrapy.FormRequest()能够发送表单和ajax请求,参考阅读 https://www.jb51.net/article/146769.htm

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

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

  3. 否登录成功:通过请求个人主页,观察是否包含用户名

3.1.2 代码实现如下:
  • myCode
import scrapyclass Git2Spider(scrapy.Spider):name = 'git2'allowed_domains = ['github.com']start_urls = ['http://github.com/login']def parse(self, response):# 从登录页面响应中解析出post数据# 正则提取token = response.xpath('//input[@name="authenticity_token"]/@value').extract_first()# print(token)timestamp_secret = response.xpath('//input[@name="timestamp_secret"]/@value').extract_first()# print(timestamp_secret)timestamp = response.xpath('//input[@name="timestamp"]/@value').extract_first()# print(timestamp)required_field_name = response.xpath('//*[@id="login"]/form/div[4]/input[6]/@name').extract_first()# print(required_field_name)post_data = {"commit": "Sign in","authenticity_token": token,"ga_id": "1029919665.1594130837","login": "账号","password": "密码","webauthn-support": "supported","webauthn-iuvpaa-support": "unsupported","return_to": "",required_field_name: "","timestamp": timestamp,"timestamp_secret": timestamp_secret}print(post_data)# 针对登陆url发送post请求yield scrapy.FormRequest(url='https://github.com/session',callback=self.after_login,formdata=post_data)def after_login(self,response):yield scrapy.Request('https://github.com/zep03',callback=self.check_login)def check_login(self,response):print(response.xpath('/html/head/title/text()').extract_first())
import scrapy
import reclass 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请求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2295. 替换数组中的元素

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的数组 nums ,它包含 n 个 互不相同 的正整数。请你对这个数组执行 m 个操作,在第 i 个操作中,你需要将数字 operations[i][0] 替换成 operations[i][1] 。 题目保证在第 i 个操作中&a…

ssh对等性配置

目的: 让通过ssh在目标机器上执行命令和scp, 不必每次输入密码. 做法: 假设有机器A, 机器B 在A上执行, ssh-keygen, 一路使用默认值, 成功生成: 私钥id_rsa, 公钥id_rsa.pub 把A上生成的公钥id_rsa.pub的内容, 写入机器B的.ssh/authorized_keys文件中, 文件不存在则创建. cat i…

四、scrapy爬虫框架——scrapy管道的使用

scrapy管道的使用 学习目标: 掌握 scrapy管道(pipelines.py)的使用 之前我们在scrapy入门使用一节中学习了管道的基本使用,接下来我们深入的学习scrapy管道的使用 1. pipeline中常用的方法: process_item(self,item,spider): 管道类中必须…

SPOJ COT Count on a tree 主席树

题意: 给\(n(1 \leq n \leq 10^5)\)一棵树,每个点有个权值。 还有\(m(1 \leq m \leq 10^5)\)个询问:\(u \, v \, k\),查询路径\(u \to v\)上权值第\(k\)小的权值。 分析: 和普通的区间一样,对于树维护到根节…

LeetCode 2296. 设计一个文本编辑器(双栈)

文章目录1. 题目2. 解题1. 题目 请你设计一个带光标的文本编辑器,它可以实现以下功能: 添加:在光标所在处添加文本。删除:在光标所在处删除文本(模拟键盘的删除键)。移动:将光标往左或者往右移…

五、scrapy爬虫框架——logging 模块的使用

logging 模块的使用 1、scrapy settings中设置LOG_LEVEL“WARNING”settings中设置LOG_FILE"./a.log"#设置日志保存的位置,设置会后终端不会显示日志内容import logging,实例化logger的方式在任何文件中使用logger输出内容 2、普通项目中 import logg…

CUBRID学习笔记 22 插入数据

CREATE TABLE auto_tbl(id INT AUTO_INCREMENT, name VARCHAR);自增长的列可以插入null, 同时一次可以插入多条记录.别的和其他的sql数据库语法基本一样 INSERT INTO auto_tbl VALUES (NULL, AAA); INSERT INTO auto_tbl (id, name) VALUES (NULL, AAA); INSERT INTO auto_tbl …

PyQt5 布局管理(水平、垂直、网格、表单、嵌套、QSplitter)

文章目录1. 布局管理2. 使用绝对位置布局3. QBoxLayoutaddStretch() 添加可伸缩控件4. QGridLayout5. QFormLayout6. 嵌套布局7. QSplitter 布局learn from 《PyQt5 快速开发与实战》 https://doc.qt.io/qtforpython/index.html https://www.riverbankcomputing.com/static/Doc…

一、Java 面向对象高级——Object类、常用API

day01【Object类、常用API】 主要内容 Object类Date类DateFormat类Calendar类System类StringBuilder类包装类 教学目标 -[ ] 能够说出Object类的特点 -[ ] 能够重写Object类的toString方法 -[ ] 能够重写Object类的equals方法 -[ ] 能够使用日期类输出当前日期 -[ ] 能够使…

FineUI(专业版)v3.0.0 发布,手机、平板和桌面全支持!

FineUI(专业版)v3.0.0 已经正式发布,全面支持手机、平板和桌面!自 2008 年 4 月发布第一个版本,我们持续更新了 126 个版本,拥有 16000 多位注册用户,1300 多位捐赠会员,200 多位网友…

二、Java 面向对象高级——Collection、泛型

day02【Collection、泛型】 主要内容 Collection集合迭代器增强for泛型 教学目标 能够说出集合与数组的区别 说出Collection集合的常用功能 能够使用迭代器对集合进行取元素 能够说出集合的使用细节 能够使用集合存储自定义类型 能够使用foreach循环遍历集合 能够使用泛型定…

LeetCode 2299. 强密码检验器 II

文章目录1. 题目2. 解题1. 题目 如果一个密码满足以下所有条件,我们称它是一个 强 密码: 它有至少 8 个字符。至少包含 一个小写英文 字母。至少包含 一个大写英文 字母。至少包含 一个数字 。至少包含 一个特殊字符 。特殊字符为:"!#…

Spring中RedirectAttributes对象重定向传参

Spring3中的FlashAttribute 为 了防止用户刷新重复提交,save操作之后一般会redirect到另一个页面,同时带点操作成功的提示信息。因为是Redirect,Request里 的attribute不会传递过去,如果放在session中,则需要在显示后及…

LeetCode 2300. 咒语和药水的成功对数(二分查找)

文章目录1. 题目2. 解题1. 题目 给你两个正整数数组 spells 和 potions ,长度分别为 n 和 m ,其中 spells[i] 表示第 i 个咒语的能量强度,potions[j] 表示第 j 瓶药水的能量强度。 同时给你一个整数 success 。一个咒语和药水的能量强度 相…

三、Java 面向对象高级——数据结构、List、Set、Collection

day03 【List、Set、数据结构、Collections】 主要内容 数据结构List集合Set集合Collections 教学目标 能够说出List集合特点 能够说出常见的数据结构 能够说出数组结构特点 能够说出栈结构特点 能够说出队列结构特点 能够说出单向链表结构特点 能够说出Set集合的特点 能够说…

Centos Cacti 0.8.8g

Centos Cacti 0.8.8g 一、Cacti简介1. cacti是用php语言实现的一个软件,它的主要功能是用snmp服务获取数据,然后用rrdtool储存和更新数据,当用户需要查看数据的时候用rrdtool生成图表呈现给用户。因此snmp和rrdtool是cacti的关键。Snmp关系着…

LeetCode 2301. 替换字符后匹配(字典)

文章目录1. 题目2. 解题1. 题目 给你两个字符串 s 和 sub 。同时给你一个二维字符数组 mappings ,其中 mappings[i] [oldi, newi] 表示你可以替换 sub 中任意数目的 oldi 字符,替换成 newi 。sub 中每个字符 不能 被替换超过一次。 如果使用 mappings…

一、Web服务器——Tomcat Servlet学习笔记

今日内容 web相关概念回顾web服务器软件:TomcatServlet入门学习 一、web相关概念回顾 软件架构 C/S:客户端/服务器端B/S:浏览器/服务器端 资源分类 静态资源:所有用户访问后,得到的结果都是一样的,称为静态…

LeetCode 2302. 统计得分小于 K 的子数组数目(前缀和+二分查找)

文章目录1. 题目2. 解题1. 题目 一个数组的 分数 定义为数组之和 乘以 数组的长度。 比方说,[1, 2, 3, 4, 5] 的分数为 (1 2 3 4 5) * 5 75 。 给你一个正整数数组 nums 和一个整数 k ,请你返回 nums 中分数 严格小于 k 的 非空整数子数组数目。 …

《MySchool数据库设计优化》内部测试

1) 在SQL Server 中,为数据库表建立索引能够( C )。 A. 防止非法的删除操作 B. 防止非法的插入操作 C. 提高查询性能 D. 节约数据库的磁盘空间 解析:索引的作用是通过使用索引,大大提高数据库的检索速度,改…