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网络编程之读取网站根目录实例
Sep 30 Python
简单总结Python中序列与字典的相同和不同之处
Jan 19 Python
python编程实现归并排序
Apr 14 Python
5款非常棒的Python工具
Jan 05 Python
Python实现识别手写数字 Python图片读入与处理
Mar 23 Python
Request的中断和ErrorHandler实例解析
Feb 12 Python
对python append 与浅拷贝的实例讲解
May 04 Python
Python使用wget实现下载网络文件功能示例
May 31 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
Jun 01 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
Aug 16 Python
解决django 新增加用户信息出现错误的问题
Jul 28 Python
Python爬虫教程知识点总结
Oct 19 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 不错的学习资料
2009/02/06 PHP
LotusPhp笔记之:Logger组件的使用方法
2013/05/06 PHP
PHP遍历目录函数opendir()、readdir()、closedir()、rewinddir()总结
2014/11/18 PHP
php桥接模式应用案例分析
2019/10/23 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
语义化 H1 标签
2008/01/14 Javascript
Javascript中的delete介绍
2012/09/02 Javascript
Json对象与Json字符串互转(4种转换方式)
2013/03/27 Javascript
使用jQuery内容过滤选择器选择元素实例讲解
2013/04/18 Javascript
JavaScript 函数惰性载入的实现及其优点介绍
2013/08/12 Javascript
纯JS实现根据CSS的class选择DOM
2014/03/22 Javascript
jQuery实现简单网页遮罩层/弹出层效果兼容IE6、IE7
2014/06/16 Javascript
JS实现无限级网页折叠菜单(类似树形菜单)效果代码
2015/09/17 Javascript
详解JavaScript编程中正则表达式的使用
2015/10/25 Javascript
Bootstrap每天必学之进度条
2015/11/30 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
2016/07/27 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
2017/01/19 Javascript
js中new一个对象的过程
2017/02/20 Javascript
基于JQuery的购物车添加删除以及结算功能示例
2017/03/08 Javascript
Angular 2.x学习教程之结构指令详解
2017/05/25 Javascript
Underscore之Array_动力节点Java学院整理
2017/07/10 Javascript
JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】
2018/05/07 Javascript
angularJs中orderBy筛选以及filter过滤数据的方法
2018/09/30 Javascript
Vue CLI3中使用compass normalize的方法
2019/05/30 Javascript
实例讲解Python的函数闭包使用中应注意的问题
2016/06/20 Python
win10下Python3.6安装、配置以及pip安装包教程
2017/10/01 Python
Python标准模块--ContextManager上下文管理器的具体用法
2017/11/27 Python
Python实现基于C/S架构的聊天室功能详解
2018/07/07 Python
详解PyTorch手写数字识别(MNIST数据集)
2019/08/16 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
Pycharm常用快捷键总结及配置方法
2020/11/14 Python
工厂门卫岗位职责范本
2014/04/04 职场文书
幼儿园标语大全
2014/06/19 职场文书
简历自我评价范文
2019/04/24 职场文书
Django程序的优化技巧
2021/04/29 Python