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实现的去除win下文本文件头部BOM的代码
Feb 10 Python
Python中os和shutil模块实用方法集锦
May 13 Python
JSONLINT:python的json数据验证库实例解析
Nov 28 Python
python实现Flappy Bird源码
Dec 24 Python
详解PyCharm安装MicroPython插件的教程
Jun 24 Python
django如何自己创建一个中间件
Jul 24 Python
利用python list完成最简单的DB连接池方法
Aug 09 Python
Python 获取命令行参数内容及参数个数的实例
Dec 20 Python
python3 实现调用串口功能
Dec 26 Python
Python生成器next方法和send方法区别详解
May 30 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
Sep 28 Python
Python中用xlwt制作表格实例讲解
Nov 05 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的运行机制与原理(底层)
2015/11/16 PHP
简单谈谈php浮点数精确运算
2016/03/10 PHP
javascript各种复制代码收集
2008/09/20 Javascript
javascript 精粹笔记
2010/05/09 Javascript
基于jQuery的history历史记录插件
2010/12/11 Javascript
一个JQuery写的点击上下滚动的小例子
2011/08/27 Javascript
用jquery模仿的a的title属性(兼容ie6/7)
2013/01/21 Javascript
jquery实现div阴影效果示例代码
2013/09/16 Javascript
JavaScript更改字符串的大小写
2015/05/07 Javascript
IE6兼容透明背景图片及解决方案
2015/08/19 Javascript
jquery编写Tab选项卡滚动导航切换特效
2020/07/17 Javascript
jquery中实现时间戳与日期相互转换
2016/04/12 Javascript
ArtEditor富文本编辑器增加表单提交功能
2016/04/18 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
JS基于for语句编写的九九乘法表示例
2018/01/04 Javascript
JavaScript设计模式之职责链模式应用示例
2018/08/07 Javascript
jQuery 实现批量提交表格多行数据的方法
2018/08/09 jQuery
axios对请求各种异常情况处理的封装方法
2018/09/25 Javascript
element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项小结【实例代码】
2018/11/20 Javascript
微信小程序开发之左右分栏效果的实例代码
2019/05/20 Javascript
vuex actions异步修改状态的实例详解
2019/11/06 Javascript
微信浏览器左上角返回按钮监听的实现
2020/03/04 Javascript
Python对象中__del__方法起作用的条件详解
2018/11/01 Python
对python条件表达式的四种实现方法小结
2019/01/30 Python
Python 3.8新特征之asyncio REPL
2019/05/28 Python
python+selenium实现自动化百度搜索关键词
2019/06/03 Python
pytorch forward两个参数实例
2020/01/17 Python
python实现批处理文件
2020/07/28 Python
Python析构函数__del__定义原理解析
2020/11/20 Python
Python实现Excel自动分组合并单元格
2021/02/22 Python
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
四年大学生活的个人自我评价
2013/12/11 职场文书
社团活动策划书范文
2014/01/09 职场文书
SpringBoot 集成Redis 过程
2021/06/02 Redis
MySQL 数据表操作
2022/05/04 MySQL