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定时采集摄像头图像上传ftp服务器功能实现
Dec 23 Python
python获取android设备的GPS信息脚本分享
Mar 06 Python
python中split方法用法分析
Apr 17 Python
Python实现SMTP发送邮件详细教程
Mar 02 Python
用tensorflow实现弹性网络回归算法
Jan 09 Python
PyQt5实现暗黑风格的计时器
Jul 29 Python
python集合常见运算案例解析
Oct 17 Python
django 装饰器 检测登录状态操作
Jul 02 Python
Python requests及aiohttp速度对比代码实例
Jul 16 Python
python实现简单的tcp 文件下载
Sep 16 Python
python 如何引入协程和原理分析
Nov 30 Python
Pytorch数据读取之Dataset和DataLoader知识总结
May 23 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/06/24 PHP
PHP服务器页面间跳转实现方法
2012/08/02 PHP
浅析使用Turck-mmcache编译来加速、优化PHP代码
2013/06/20 PHP
解决CodeIgniter伪静态失效
2014/06/09 PHP
PHP加密解密字符串汇总
2015/04/26 PHP
PHP中__autoload和Smarty冲突的简单解决方法
2016/04/08 PHP
javascript下阻止表单重复提交、防刷新、防后退
2007/08/17 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
js自定义鼠标右键的实现原理及源码
2014/06/23 Javascript
JQuery标签页效果的两个实例讲解(4)
2015/09/17 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
2016/12/26 Javascript
jquery实现input框获取焦点的方法
2017/02/06 Javascript
Vue 中mixin 的用法详解
2018/04/23 Javascript
Vue.Draggable拖拽功能的配置使用方法
2020/07/29 Javascript
JavaScript Array对象基本方法详解
2019/09/03 Javascript
vue中v-model对select的绑定操作
2020/08/31 Javascript
JavaScript this关键字指向常用情况解析
2020/09/02 Javascript
如何管理Vue中的缓存页面
2021/02/06 Vue.js
Python笔记(叁)继续学习
2012/10/24 Python
Python循环语句之break与continue的用法
2015/10/14 Python
浅谈Python 字符串格式化输出(format/printf)
2016/07/21 Python
django rest framework 自定义返回方式
2020/07/12 Python
Python 常用日期处理 -- calendar 与 dateutil 模块的使用
2020/09/02 Python
使用OpenCV校准鱼眼镜头的方法
2020/11/26 Python
李宁官方网店:中国运动品牌
2017/11/02 全球购物
UNIONBAY官网:美国青少年服装品牌
2019/03/26 全球购物
Jacadi Paris英国官网:法国童装品牌
2019/08/09 全球购物
杭州联环马网络笔试题面试题
2013/08/04 面试题
数控技术应届生求职信
2013/11/13 职场文书
班主任师德师风自我剖析材料
2014/10/02 职场文书
教师学习群众路线心得体会
2014/11/04 职场文书
学校捐款活动总结
2015/05/09 职场文书
民间借贷纠纷案件代理词
2015/05/26 职场文书
python3.7.2 tkinter entry框限定输入数字的操作
2021/05/22 Python
详解在OpenCV中如何使用图像像素
2022/03/03 Python
Android开发手册Chip监听及ChipGroup监听
2022/06/10 Java/Android