Scrapy实现模拟登录的示例代码


Posted in Python onFebruary 21, 2021

为什么要模拟登录

有些网站是需要登录之后才能访问的,即便是同一个网站,在用户登录前后页面所展示的内容也可能会大不相同,例如,未登录时访问Github首页将会是以下的注册页面:

Scrapy实现模拟登录的示例代码

然而,登录后访问Github首页将包含如下页面内容:

Scrapy实现模拟登录的示例代码

如果我们要爬取的是一些需要登录之后才能访问的页面数据就需要模拟登录了。通常我们都是利用的 Cookies 来实现模拟登录,在Scrapy中,模拟登陆网站一般有如下两种实现方式:

           (1) 请求时携带Cookies

           (2) 发送Post请求获取Cookies

请求时携带Cookies

对于一些Cookies过期时间很长的不规范网站,如果我们能够在Cookies过期之前爬取到所有我们想要的数据,可以考虑在请求时直接将Cookies信息带上来模拟用户登录。

以下是模拟登录Github的示例代码:

# -*- coding: utf-8 -*-
import scrapy
import re
 
class TmallLoginSpider(scrapy.Spider):
  name = 'github_login3'
  allowed_domains = ['github.com']
  start_urls = ['https://github.com/']
 
  def start_requests(self): # 请求时携带Cookies
    cookies = '_ga=GA1.2.363045452.1554860671; tz=Asia%2FShanghai; _octo=GH1.1.1405577398.1554860677; _device_id=ee3ff12512668a1f9dc6fb33e388ea20; ignored_unsupported_browser_notice=false; has_recent_activity=1; user_session=5oxrsfsZCor1iJFCgRXXyeAXd8hcmzEUGh70-xHWLjQkT62Q; __Host-user_session_same_site=5oxrsfsZCor1iJFCgRXXyeAXd8hcmzEUGh70-xHWLjQkT62Q; logged_in=yes; dotcom_user=pengjunlee; _gat=1'
    cookies = {i.split('=')[0]: i.split('=')[1] for i in cookies.split('; ')}
    yield scrapy.Request(self.start_urls[0], cookies=cookies)
    
  def parse(self, response): # 验证是否请求成功
    print(re.findall('Learn Git and GitHub without any code!',response.body.decode()))

执行爬虫后,后台部分日志截图如下:

Scrapy实现模拟登录的示例代码

发送Post请求模拟登录

Scrapy还提供了两种通过发送Post请求来获取Cookies的方法。

scrapy.FormRequest()

使用scrapy.FormRequest()发送Post请求实现模拟登陆,需要人为找出登录请求的地址以及构造出登录时所需的请求数据。

使用scrapy.FormRequest()模拟登录Github的示例代码: 

# -*- coding: utf-8 -*-
import scrapy
import re
 
class GithubLoginSpider(scrapy.Spider):
  name = 'github_login'
  allowed_domains = ['github.com']
  start_urls = ['https://github.com/login']
 
  def parse(self, response): # 发送Post请求获取Cookies
    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()
    form_data = {
      'login': 'pengjunlee@163.com',
      'password': '123456',
      'webauthn-support': 'supported',
      'authenticity_token': authenticity_token,
      'utf8': utf8,
      'commit': commit}
    yield scrapy.FormRequest("https://github.com/session", formdata=form_data, callback=self.after_login)
 
  def after_login(self, response): # 验证是否请求成功
    print(re.findall('Learn Git and GitHub without any code!', response.body.decode()))

从后台日志不难看出,Scrapy 在请求完 https://github.com/session 后,自动帮我们重定向到了Github首页。

Scrapy实现模拟登录的示例代码

scrapy.FormRequest.from_response()

scrapy.FormRequest.from_response()使用起来比 scrapy.FormRequest()更加简单方便,我们通常只需要提供用户相关信息(账户和密码)即可,scrapy.FormRequest.from_response()将通过模拟点击为我们填充好其他的表单字段并提交表单。

使用scrapy.FormRequest.from_response()模拟登录Github的示例代码: 

# -*- coding: utf-8 -*-
import scrapy
import re
 
class GithubLogin2Spider(scrapy.Spider):
  name = 'github_login2'
  allowed_domains = ['github.com']
  start_urls = ['https://github.com/login']
 
  def parse(self, response): # 发送Post请求获取Cookies
    form_data = {
      'login': 'pengjunlee@163.com',
      'password': '123456'
    }
    yield scrapy.FormRequest.from_response(response,formdata=form_data,callback=self.after_login)
 
  def after_login(self,response): # 验证是否请求成功
    print(re.findall('Learn Git and GitHub without any code!',response.body.decode()))

scrapy.FormRequest.from_response()方法还可以传入其他参数来帮我们更加精确的指定表单元素:

'''
response (Response object) ? 包含表单HTML的响应,将用来对表单的字段进行预填充
formname (string) ? 如果设置了该值,name 等于该值的表单将被使用
formid (string) ? 如果设置了该值,id 等于该值的表单将被使用
formxpath (string) ? 如果设置了该值,匹配该 xpath 的第一个表单将被使用
formcss (string) ? 如果设置了该值,匹配该 css选择器的第一个表单将被使用
formnumber (integer) ? 索引值等于该值的表单将被使用,默认第一个(索引值为 0 )
formdata (dict) ? 传入的表单数据,将覆盖form 元素中已经存在的值
clickdata (dict) ? 用于查找可点击控件的属性值
dont_click (boolean) ? 如果设置为 True,将不点击任何元素,直接提交表单数据
'''

参考文章

https://doc.scrapy.org/en/latest/topics/request-response.html

到此这篇关于Scrapy实现模拟登录的示例代码的文章就介绍到这了,更多相关Scrapy 模拟登录内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python 解析html之BeautifulSoup
Jul 07 Python
简单说明Python中的装饰器的用法
Apr 24 Python
Python随机生成手机号、数字的方法详解
Jul 21 Python
Python利用multiprocessing实现最简单的分布式作业调度系统实例
Nov 14 Python
Python 机器学习库 NumPy入门教程
Apr 19 Python
Python unittest 简单实现参数化的方法
Nov 30 Python
Python按钮的响应事件详解
Mar 04 Python
Python 识别12306图片验证码物品的实现示例
Jan 20 Python
python实现替换word中的关键文字(使用通配符)
Feb 13 Python
python判断变量是否为列表的方法
Sep 17 Python
python spilt()分隔字符串的实现示例
May 21 Python
Python基础学习之奇异的GUI对话框
May 27 Python
scrapy-splash简单使用详解
Feb 21 #Python
详解使用scrapy进行模拟登陆三种方式
Feb 21 #Python
利用Python如何画一颗心、小人发射爱心
Feb 21 #Python
python 第三方库paramiko的常用方式
Feb 20 #Python
Python中Qslider控件实操详解
Feb 20 #Python
python基于selenium爬取斗鱼弹幕
Feb 20 #Python
Python爬虫+Tkinter制作一个翻译软件的示例
Feb 20 #Python
You might like
php不用正则采集速度探究总结
2008/03/24 PHP
PHP自定义函数收代码
2010/08/01 PHP
Linux Apache PHP Oracle 安装配置(具体操作步骤)
2013/06/17 PHP
PhpDocumentor 2安装以及生成API文档的方法
2014/05/21 PHP
php实现高效获取图片尺寸的方法
2014/12/12 PHP
JavaScript Event学习第五章 高级事件注册模型
2010/02/07 Javascript
工作需要写的一个js拖拽组件
2011/07/28 Javascript
JavaScript字符串插入、删除、替换函数使用示例
2013/07/25 Javascript
使用js完成节点的增删改复制等的操作
2014/01/02 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
2014/04/16 Javascript
AngularJS中实现动画效果的方法
2016/07/28 Javascript
又一款js时钟!transform实现时钟效果
2016/08/15 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
AngularJs导出数据到Excel的示例代码
2017/08/11 Javascript
JS实现运动缓冲效果的封装函数示例
2018/02/18 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
React父子组件间的传值的方法
2018/11/13 Javascript
JavaScript函数的特性与应用实践深入详解
2018/12/30 Javascript
js实现类似iphone的网页滑屏解锁功能示例【附源码下载】
2019/06/10 Javascript
通过实例学习React中事件节流防抖
2019/06/17 Javascript
JavaScript实现鼠标移入随机变换颜色
2020/11/24 Javascript
python网络编程学习笔记(九):数据库客户端 DB-API
2014/06/09 Python
Python中的面向对象编程详解(下)
2015/04/13 Python
Python 模板引擎的注入问题分析
2017/01/01 Python
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
解决出现Incorrect integer value: '' for column 'id' at row 1的问题
2017/10/29 Python
Django1.11自带分页器paginator的使用方法
2019/10/31 Python
python:批量统计xml中各类目标的数量案例
2020/03/10 Python
美国手机支架公司:PopSockets
2019/11/27 全球购物
以思科路由器为例你写下单臂路由的配置命令
2013/08/03 面试题
介绍一下RMI的基本概念
2016/12/17 面试题
企业文化口号
2014/06/12 职场文书
科级干部群众路线教育实践活动对照检查材料思想汇报
2014/09/20 职场文书
公务员党的群众路线教育实践活动学习心得体会
2014/10/30 职场文书
简述Java中throw-throws异常抛出
2021/08/07 Java/Android
js作用域及作用域链工作引擎
2022/07/07 Javascript