Python3网络爬虫开发实战(10)模拟登录(需补充账号池的构建)

news2024/12/28 18:25:09

文章目录

  • 一、基于 Cookie 的模拟登录
  • 二、基于 JWT 模拟登入
  • 三、账号池
  • 四、基于 Cookie 模拟登录爬取实战
  • 五、基于JWT 的模拟登录爬取实战
  • 六、构建账号池

很多情况下,网站的一些数据需要登录才能查看,如果需要爬取这部分的数据,就需要实现模拟登入的一些机制;模拟登录现在主要分为两种方式,一种是基于 Session 和 Cookie 的模拟登入,一种是基于 JWT(Json Web Token)的模拟登录。

对于第一种模式,打开网页后模拟登录,服务器会返回带有 Set-Cookie 字段的响应头,客户端会生成对应的 Cookie,其中保存着与 SessionID 相关的信息,之后发送给服务器的请求都会携带这个生成的 Cookie。服务器接收到请求后,会根据 Cookie 中保存的 SessionID 找到对应的 Session,同时效验 Cookie 里的相关信息,如果当前 Session 是有效的并且效验成功,服务器就判断当前用户已经登录,返回请求的页面信息,所以这种模式的核心是获取客户端登录后生成的 Cookie;

对于第二种模式,是因为现在有很多的网站采取的开发模式是前后端分离模式,所以使用 JWT 进行登录效验越来越普遍,在请求数据时,服务器会效验请求中携带的 JWT 是否有效,如果有效,就返回正常的数据,所以这种模式其实就是获取 JWT;

一、基于 Cookie 的模拟登录

如果要使用爬虫实现基于 Session 和 Cookie 的模拟登录,最为主要的是要维护好 Cookie 的信息,因为爬虫相当于客户端的浏览器;

  1. 如果在浏览器中登录了自己的账号,可以直接把网页中的 Cookie 复制给爬虫,就相当于手动在浏览器中登录;
  2. 如果让爬虫完全自动化操作,可以直接使用爬虫模拟登录过程,这个过程基本上就是一个 POST 请求,用爬虫把用户名,密码等信息提交给服务器,服务器会返回一个 Set-Cookie 字段,我们只需要将该字段保存下来,然后提交给爬虫请求就好;
  3. 如果 POST 请求难以构造,我们可以使用自动化工具来模拟登录,例如使用 Selenium,Playwright 来发送请求,然后获取 Cookie 进行发送请求;

二、基于 JWT 模拟登入

JWT 的字符串就是用户访问的凭证,所以模拟登录只需要做到以下几步:

  1. 模拟登录操作,例如拿着用户名和密码信息请求登录接口,获取服务器返回的结果,这个结果中通常包含 JWT 信息,将其保存下来即可;
  2. 之后发送给服务器的请求均携带 JWT,在 JWT 不过期的情况下,通常能正常访问和执行操作,携带方式多种多样,因网站而异;
  3. 如果 JWT 过期了,可能需要再次做第一步,重新获取 JWT;

三、账号池

如果爬虫要求爬取的数据量比较大,或者爬取速度比较快,网站又有单账号并发限制或者访问状态检测等反爬虫手段,我们的账号可能就无法访问网站或者面临封号的风险;

这时我们建立一个账号池进行分流,用多个账号随机访问网站或爬取数据,这样能大幅提高爬虫的并发量,降低被封号的风险,例如准备 100 个账号,将这 100 个账号都模拟登录,并保存对应的 Cookie 和 JWT,每次都随机抽取一个来访问,账号多,所以每个账号被选取的概率就小,也就避免了单账号并发量过大的问题,从而降低封号风险;

四、基于 Cookie 模拟登录爬取实战

目标网址:Scrape | Movie

账号:admin
密码:admin

这里由于登入请求构造并没有涉及到加密过程,因此我们可以直接构造 requests 请求来执行请求;仔细分析后可以发现登入请求返回的状态码是 302,同时登入完毕后页面自动发生了跳转,因此在使用 requests 够着 post 请求的时候,需要将 allow_redirects 参数设置为 False;

import requests
import parsel

headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'https://login2.scrape.center',
    'Referer': 'https://login2.scrape.center/login',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
}

data = {
    'username': 'admin',
    'password': 'admin',
}

response = requests.post('https://login2.scrape.center/login', headers=headers, data=data, allow_redirects=False)

# 得到 cookies
cookies = response.cookies.get_dict()


# 将获取到的 cookie 放入 requests 的 get 请求中
response = requests.get('https://login2.scrape.center/', cookies=cookies, headers=headers)

# 解析网页数据
selector = parsel.Selector(response.text)
names = selector.xpath('//*[@id="index"]/div[1]/div[1]/div/div/div/div[2]/a/h2/text()').getall()

# 打印名字
print(names)

# ['霸王别姬 - Farewell My Concubine',
#  '这个杀手不太冷 - Léon',
#  '肖申克的救赎 - The Shawshank Redemption',
#  '泰坦尼克号 - Titanic',
#  '罗马假日 - Roman Holiday',
#  '唐伯虎点秋香 - Flirting Scholar',
#  '乱世佳人 - Gone with the Wind',
#  '喜剧之王 - The King of Comedy',
#  '楚门的世界 - The Truman Show',
#  '狮子王 - The Lion King']

在这里我们首先获得了 cookies,然后又手动要将 cookies 放入到后续的请求之中,这里我们可以构建 Session 请求来自动化添加 cookies;如下

import requests
import parsel

headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'https://login2.scrape.center',
    'Referer': 'https://login2.scrape.center/login',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
}

data = {
    'username': 'admin',
    'password': 'admin',
}

# 构建 session
session = requests.Session()

# 发送登入请求
response = session.post('https://login2.scrape.center/login', headers=headers, data=data, allow_redirects=False)

# 无需手动配置 cookies,发送页面请求
response = session.get('https://login2.scrape.center/', headers=headers)

# 解析网页数据
selector = parsel.Selector(response.text)
names = selector.xpath('//*[@id="index"]/div[1]/div[1]/div/div/div/div[2]/a/h2/text()').getall()

# 打印名字
print(names)

# ['霸王别姬 - Farewell My Concubine',
#  '这个杀手不太冷 - Léon',
#  '肖申克的救赎 - The Shawshank Redemption',
#  '泰坦尼克号 - Titanic',
#  '罗马假日 - Roman Holiday',
#  '唐伯虎点秋香 - Flirting Scholar',
#  '乱世佳人 - Gone with the Wind',
#  '喜剧之王 - The King of Comedy',
#  '楚门的世界 - The Truman Show',
#  '狮子王 - The Lion King']

这里是对于请求未涉及到加密或者带有验证码的网站,如果涉及到加密但是又不会解密,我们可以使用自动化工具来获取 Cookie;这里以 Playwright 为例子;

import requests
import parsel
from playwright.sync_api import sync_playwright

def get_cookies():
    with sync_playwright() as playwright:
        cookies = {}
        browser = playwright.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()
        page.goto("https://login2.scrape.center/login")
        page.locator('input[name="username"]').fill("admin")
        page.locator('input[name="password"]').fill("admin")
        page.locator('input[type="submit"]').click()

        cookieList = context.cookies()
        context.close()
        browser.close()

        for cookie in cookieList:
            cookies[cookie['name']] = cookie['value']

        return cookies


headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'https://login2.scrape.center',
    'Referer': 'https://login2.scrape.center/login',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
}

cookies = get_cookies()
response = requests.get('https://login2.scrape.center/', cookies=cookies, headers=headers)

# 解析网页数据
selector = parsel.Selector(response.text)
names = selector.xpath('//*[@id="index"]/div[1]/div[1]/div/div/div/div[2]/a/h2/text()').getall()

# 打印名字
print(names)

# ['霸王别姬 - Farewell My Concubine',
#  '这个杀手不太冷 - Léon',
#  '肖申克的救赎 - The Shawshank Redemption',
#  '泰坦尼克号 - Titanic',
#  '罗马假日 - Roman Holiday',
#  '唐伯虎点秋香 - Flirting Scholar',
#  '乱世佳人 - Gone with the Wind',
#  '喜剧之王 - The King of Comedy',
#  '楚门的世界 - The Truman Show',
#  '狮子王 - The Lion King']

五、基于JWT 的模拟登录爬取实战

目标网址:Scrape | Movie

账号:admin
密码:admin

import requests

headers = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "Connection": "keep-alive",
    "Content-Type": "application/json;charset=UTF-8",
    "Origin": "https://login3.scrape.center",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
    "sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"',
}

json_data = {
    "username": "admin",
    "password": "admin",
}

# 这里使用 json 而不是使用 data 传参是因为 headers 中的 Content-Type 接受的是 application/json 数据
response = requests.post(
    "https://login3.scrape.center/api/login", headers=headers, json=json_data
)

# 获取 token 构建 headers 中的 Authorization
token = response.json()["token"]
Authorization = "jwt " + token
headers = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "Authorization": Authorization,
    "Connection": "keep-alive",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
    "sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"',
}

params = {
    "limit": "18",
    "offset": "0",
}

# 直接使用 get 请求获取数据
response = requests.get(
    "https://login3.scrape.center/api/book", params=params, headers=headers
)

print(response.json())

# {
#     "count": 9200,
#     "results": [
#         {
#             "id": "34473697",
#             "name": "R数据科学实战:工具详解与案例分析",
#             "authors": ["刘健", "邬书豪"],
#             "cover": None,
#         }
#     ],
# }

在这里由于使用的是 JWT,响应头中并不会返回一个 Set-Cookies 参数,因此使用 Session 来完成 JWT 是没有效果的,只能单个请求进行构建;

六、构建账号池

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2046118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KNN图像识别实例--手写数字识别

目录 前言 一、导入库 二、导入图像并处理 1.导入图像 2.提取出图像中的数字 3.将列表转换成数组 4.获取特征数据集 5.获取标签数据 三、使用KNN模型 1.创建KNN模型并训练 2.KNN模型出厂前测试 3.使用测试集对KNN模型进行测试 四、传入单个图像,使用该模…

叉车高位盲区显示器 无线摄像头免打孔 视线遮挡的解决方案

叉车作业货叉叉货时,货叉升降无法看清位置,特别是仓储的堆高车,司机把头探出去才勉强可以靠经验找准方位!一个不小心就可能叉歪了,使货物倾斜、跌落等等,从而发生事故!如何将隐患扼杀&#xff0…

【JAVA入门】Day21 - 时间类

【JAVA入门】Day21 - 时间类 文章目录 【JAVA入门】Day21 - 时间类一、JDK7前的时间相关类1.1 Date1.2 SimpleDateFormat1.3 Calendar 二、JDK8新增的时间相关类2.1 Date 相关类2.1.1 ZoneId 时区2.1.2 Instant 时间戳2.1.3 ZoneDateTime 带时区的时间 2.2 DateTimeFormat 相关…

刷题DAY7

三个数的排序 题目:输入三个整数x,y,z,请把这三个数由小到大输出 输入:输入数据包含3个整数x,y,z,分别用逗号隔开 输出:输出由小到大排序后的结果,用空格隔…

O2OA开发知识-后端代理/接口脚本编写也能像前端一样用上debugger

在o2oa开发平台中,后端代理或者接口的脚本编写也能像前端一样用上debugger,这是来自藕粉社区用户的宝贵技术支持。 感谢藕粉社区论坛用户提供的技术分享!tzengsh_BTstthttps://www.o2oa.net/forum/space-uid-4410.html 论坛地址&#xff1a…

【Kubernetes】k8s集群图形化管理工具之rancher

目录 一.Rancher概述 1.Rancher简介 2.Rancher与k8s的关系及区别 3.Rancher具有的优势 二.Rancher的安装部署 1.实验准备 2.安装 rancher 3.rancher的浏览器使用 一.Rancher概述 1.Rancher简介 Rancher 是一个开源的企业级多集群 Kubernetes 管理平台,实…

2024年高教社杯数学建模国赛A题思路解析+代码+论文

2024年高教社杯全国大学生数学建模竞赛(以下简称国赛)将于9月5日晚6时正式开始。 下文包含:2024国赛思路解析​、国赛参赛时间及规则信息说明、好用的数模技巧及如何备战数学建模竞赛 C君将会第一时间发布选题建议、所有题目的思路解析、相…

Axure:引领智慧时代的数据可视化原型设计先锋

在数字化转型的浪潮中,智慧农业、智慧城市、智慧社区、智慧水务等概念如雨后春笋般涌现,它们不仅重塑了我们的生活空间,也对数据可视化提出了前所未有的要求。作为原型设计领域的佼佼者,Axure RP凭借其强大的交互设计能力和直观的…

关于Nachi机器人自动运行上电条件

Nachi 机器人有两种控制柜,分别为 FD 控制柜和 CFD 控制柜。 对于 FD 控制器,执行以下操作。 1.旋转控制柜钥匙,使其对准标注位置①。 2.旋转示教器旋钮至下图所示位置。然后依次单击绿色按钮与白色按钮,机器人上电运行。 对于…

2025大数据毕业设计/计算机毕业设计创新必过选题(建议收藏)

一、大数据题目 项目架构模式: 1、数据Python爬虫:selenium、requests、DrissionPage等爬虫框架 2、hadoop、Spark、Flink(PyFlink)数据分析【可vmvare虚拟机可windwos电脑】 3、springboot、vue.js前后分离构建系统主体 4、…

排序篇——递归实现快速排序(hoare版-挖坑法-前后指针版)

目录 前言 一、key? 二、思路及代码实现 1.hoare版 2.挖坑法 3.前后指针版本 总结 前言 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。它会选出一个基准值(key),把它放到正确的位置(排序之后的位置)。 提示:以下是本篇…

c语言学习,tolower ()函数分析

1:tolower() 函数说明: 检查参数c,为大写字母返回对应的小写字母 2:函数原型: int toascii(int c) 3:函数参数: 参数c,为检测整数 4:返回值: 返回转换的小…

【Python】生成二维迷宫的算法

前言 哈里最近因为一个小插曲打算写一个设计迷宫的算法。为了锻炼脑力,特地没有上网搜索而是自己摸索出一个迷宫设计算法。 概述 1、需求 哈里准备实现下图的迷宫。 2、分析 可以看到,图里凡是x和y坐标为单数时,总是白色。于是哈里得到下…

二分查找专题(总)

1、经典二分查找模板 int search(vector<int>& nums, int target) {int right nums.size() - 1;int left 0;while(left < right){int mid (left right)/2;if(nums[mid] > target){right mid-1;}else if(nums[mid] < target){left mid1;}else {return…

c语言-经典例题

C语言-经典例题 一、单项选择题 1、 -- A 2、 -- C y<5 --是关系运算符的优先级大于&& -- 是逻辑运算符 3、 -- B - D选项&#xff1a;c是float类型&#xff0c;所以c/2是1.5 4、 -- C 从后往前执行&#xff08;先算后面的&a…

【uniapp】vue3+vite配置tailwindcss

安装 npm install autoprefixer tailwindcss uni-helper/vite-plugin-uni-tailwind -Dautoprefixer &#xff1a;自动管理浏览器前缀的插件&#xff0c;可以解析css文件并且添加前缀到css内容里。uni-helper/vite-plugin-uni-tailwind: 将 Tailwind CSS 框架集成到使用 Vite 作…

linux系统编程:多任务编程(进程1)

1.进程 进程:(进行中的程序)--正在运行的程序 (动态的) ---内存 程序的一次执行过程&#xff01; 一个程序一个程序 可以 对应多个进程 程序 -- a.out (可执行程序) ---静态的 程序 加载 到内存 运行起来 成为了 进程。 进程是 程序运行的实体。 程序 数据代码 2.进…

背包九讲(求方案数,求具体方案数,有依赖背包)

文章目录 求方案数基本思路代码 背包问题求具体方案基本思路代码 有依赖背包基本思路代码 求方案数 问题描述&#xff1a; 给定n nn个物品&#xff0c;以及一个容量大小为m mm的背包&#xff0c;然后给出n nn个物品的体积及价值&#xff0c;求背包最大价值是多少&#xff0c;也…

递归排序 归并排序 快排

递归 求中点 midL(R-L)/2 midL((R-L)>>1)右移一位更快 子问题等量 mast er公式 T(N) a*T(N/b)O(N^d) T(N):母 T(N/b)&#xff1a;子 &#xff08;是否等量&#xff09; a&#xff1a;调用多少次 O(N^d)&#xff1a;除去子变量之外的时间复杂度 子问题等量 上面…

sqli-labs-master靶场通关

目录 一、sqli-labs第一关 1.判断是否存在sql注入 &#xff08;1&#xff09;提示输入数字值的ID作为参数&#xff0c;输入?id1 &#xff08;2&#xff09;通过数字值不同返回的内容也不同&#xff0c;所以我们输入的内容是带入到数据库里面查询了 &#xff08;3&#xff0…