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

作者:pengjunlee 时间:2023-07-13 21:53:11 

为什么要模拟登录

有些网站是需要登录之后才能访问的,即便是同一个网站,在用户登录前后页面所展示的内容也可能会大不相同,例如,未登录时访问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

来源:https://blog.csdn.net/pengjunlee/article/details/89847344

标签:Scrapy,模拟登录
0
投稿

猜你喜欢

  • pyqt远程批量执行Linux命令程序的方法

    2023-05-08 15:59:06
  • mysql 动态执行存储过程语句

    2024-01-27 01:54:38
  • Django URL传递参数的方法总结

    2023-02-18 13:08:33
  • 经验总结:修改MySQL默认密码的具体步骤

    2009-01-04 13:29:00
  • Go语言并发编程之互斥锁Mutex和读写锁RWMutex

    2024-04-25 15:00:32
  • Flask URL传参与视图映射的实现方法

    2021-05-10 12:31:06
  • 解决SecureCRT通过SSH连接Ubuntu时vi命令有多余的m的问题

    2023-11-19 19:32:24
  • Kettle下载安装pdi-ce-7.1.0.0-12教程

    2023-11-27 05:38:36
  • Python 实现绘制子图及子图刻度的变换等问题

    2021-09-30 22:34:38
  • python利用Excel读取和存储测试数据完成接口自动化教程

    2022-04-02 05:25:13
  • python的concat等多种用法详解

    2022-08-14 23:37:18
  • Keras目标检测mtcnn facenet搭建人脸识别平台

    2023-09-28 07:02:01
  • Python库functools示例详解

    2021-03-10 07:01:27
  • Python PIL库图片灰化处理

    2022-08-18 20:57:30
  • HTML5 移动页面自适应手机屏幕宽度详解

    2022-08-14 23:14:43
  • 不通过数据源名DSN也能访问Access数据库吗?

    2009-10-29 12:22:00
  • 利用Python实现面部识别的方法详解

    2021-02-08 05:00:57
  • CSS3中的box-sizing属性

    2010-04-05 21:52:00
  • 一文带你了解Go语言中的指针和结构体

    2024-04-25 15:26:20
  • Centos7 下Mysql5.7.19安装教程详解

    2024-01-25 08:28:18
  • asp之家 网络编程 m.aspxhome.com