Python Selenium 自动化爬虫 + Charles Proxy 抓包

一、场景介绍

我们平常会遇到一些需要根据省、市、区查询信息的网站。

1、省市查询

比如这种,因为全国的省市比较多,手动查询工作量还是不小。

2、接口签名

有时候我们用python直接查询后台接口的话,会发现接口是加签名的。

而签名算法我们是不知道的。

扩展:

nonce(“只使用一次的数字”):number once 也就是随机验证码。

timestamp:客户端访问时间戳。

sign:请求参数签名。通过特定算法,将请求参数集合映射为一个字符串,这个字符串就是签名。签名能有效防止请求信息被黑客篡改。

province、city:就是我们前端请求的业务参数。

有了 sign 签名,为什么还需要 timestamp 和 nonce 呢?


timestamp 和 nonce 参数是为了防止重放攻击。

基于 timestamp 方案

每次HTTP请求,都需要加上 timestamp 参数,然后把 timestamp 和其他参数一起进行数字签名。
因为一次正常的HTTP请求,从发出到达服务器一般都不会超过60s,
所以服务器收到HTTP请求之后,首先判断时间戳参数与当前时间相比较,
是否超过了60s,如果超过了则认为是非法的请求。

但这种方式的漏洞也是显而易见的,如果在60s之内进行高饱和重放攻击,那就没办法了,所以这种方式不能保证请求仅一次有效。

基于 nonce 方案

nonce 的意思是仅一次有效的随机字符串,要求每次请求时,该参数要保证不同,所以该参数一般与时间戳有关,方便起见,可以直接使用时间戳的16进制,实际使用时可以加上客户端的ip地址,mac地址等信息做个哈希之后,作为nonce参数。

我们将每次请求的 nonce 参数存储到一个“集合”中,可以 json 格式存储到数据库或缓存中。
每次处理HTTP请求时,首先判断该请求的nonce参数是否在该“集合”中,如果存在则认为是非法请求。

这种方式也有很大的问题,那就是存储 nonce 参数的“集合”会越来越大,验证 nonce 是否存在“集合”中的耗时会越来越长。我们不能让nonce“集合”无限大,所以需要定期清理该“集合”,但是一旦该“集合”被清理,我们就无法验证被清理了的nonce参数了。也就是说,假设该“集合”平均1天清理一次的话,我们抓取到的该url,虽然当时无法进行重放攻击,但是我们还是可以每隔一天进行一次重放攻击的。而且存储24小时内,所有请求的“nonce”参数,也是一笔不小的开销。

基于 timestamp 和 nonce 方案

那我们如果同时使用 timestamp 和 nonce 参数呢?
nonce的一次性可以解决 timestamp 参数60s的问题,timestamp 可以解决 nonce 参数“集合”越来越大的问题。

我们在timestamp方案的基础上,加上nonce参数,因为timstamp参数对于超过60s的请求,都认为非法请求,所以我们只需要存储60s的nonce参数的“集合”即可。

结论:

timestamp 和 nonce 和其他参数一起进行数字签名。这样就能防止请求信息被篡改,还能防止重放攻击。

3、Selenium 自动化爬虫

这个时候,就是 python Selenium 自动化爬虫的用武之地了。

它通过分析前端界面元素,模拟用户真实点击的方式,来 请求接口数据

然后通过分析 界面DOM元素 的方式,来 提取响应数据

二、环境介绍

  • python:3.12.5
  • Edge 浏览器驱动:Edge 浏览器驱动官网
  • Selenium python 插件
  • Charles抓包软件(下文会介绍为什么需要)Charles 安装 可以看这篇博文

三、步骤

1、下载 Edge 浏览器驱动

首先进入 Edge 浏览器驱动官网 

选择 beta(公测) 或者 stable(稳定) 版,根据自身操作系统型号,选择 64位或32位下载。

解压到电脑中某个位置备用。

2、安装 Selenium

pip install selenium

3、安装 Edge-Selenium 工具

pip install msedge-selenium-tools

4、F12 分析前端页面

可以找到 省 的数据。此时,市的数据界面上并没有显示出来。

 

不过,通过翻看网站的JS资源,我们找到一个 area.js 这个就是全国区域的基础数据。

进一步分析,我们还知道 parentid 还是 省的 id。

5、area.js 数据导入 Excel

把 area.js 数据导入 Excel 通过 JSON数据行转列方式 得到Excel 数据

通过 Excel 的数据过滤方式,进一步证实了我们的猜测。

parentid 还是 省的 下拉控件的 value。

福建的 province 14 过滤出福建的 9 个城市。

6、初步思路

这个时候,我们有了一个用 Selenium 自动化请求的初步思路。

用 Selenium 遍历点击 省份控件,接着 级联点击 城市控件,然后点击 查询控件,

最后再用 DOM 方式提取请求响应数据。

7、数据准备

在电脑上,新建一个 city 文件夹,里面存放以 省份ID 命名的文件。

文件里面则是 城市ID,每个 城市ID 占一行。

8、Selenium 方案初版代码

经过上面的数据准备,我们基本可以写出初版的爬虫代码:

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time

# 浏览器驱动的存放位置
service = Service(executable_path=r"G:\msedgedriver.exe")
driver = webdriver.Edge(service=service)
driver.get("你的网页")

# 暂停 3 秒  等待网页加载完成
time.sleep(3)

# 找到  省    下拉框元素
province_element = driver.find_element(By.ID, 'province')
# 创建 Select 对象
province_select = Select(province_element)
# 找到  市  下拉框元素
city_element = driver.find_element(By.ID, 'city')
# 创建 Select 对象
city_select = Select(city_element)

# 输入文件
input_path = r"C:\Users\Administrator\Desktop\py\city"
# 输出文件
output_path = r"C:\Users\Administrator\Desktop\py\output.txt"

for  province  in  range(1, 35):
    print('-----------省份【' + str(province) + '】开始')
    # 选中省份
    province_select.select_by_value(str(province))

    # 省份文件
    file_path = input_path + "\\"+str(province)+'.txt'
    with open(file_path, 'r', encoding='utf-8') as input_file:
            for line in input_file:
                city = line.strip()
                print('---------------城市【'+city+'】开始')
                # 选中城市
                city_select.select_by_value(city)
                # 找到 搜索 按钮
                submit_element = driver.find_element(By.ID, 'submit')
                # 点击搜索
                submit_element.click()
                # 暂停 2 秒  等待网页加载完成
                time.sleep(2)
                # 获取无序列表中的所有列表项
                li_elements = driver.find_elements(By.TAG_NAME, 'li')
                # 提取列表项中的文本内容并打印
                for li in li_elements:
                    # 根据 属性或者 class 过滤掉不是我们想要的数据 li
                    # 因为一个界面里面,可能不止一个 列表
                    if None != li.get_attribute("data-index"):
                      with open(output_path, 'a', encoding='utf-8') as output_file:
                          output_file.write('\n' + li.text)

                print('---------------城市【'+city+'】结束')
    print('-----------省份【' + str(province) + '】结束')

# 关闭驱动
driver.quit()

爬到的数据因为涉及信息安全问题,就不在这里展示了。

但是这个代码爬取数据,有一个问题,那就是,

有时候,接口响应的数据是完整的,但是,有些数据并没有在界面上展示,Selenium 又是基于 DOM 对界面进行分析的,这部分数据我们就拿不到了,用 python 直接访问这些接口,因为有签名的存在,又没有这个条件。这个时候,Charles 代理就闪亮登场了。

通过将浏览器的网络,指向这个 Charles 代理,Selenium 在前端进行自动化请求的同时,Charles 代理负责对会话进行记录,最后通过分析 Charles 会话数据,就可以获取到我们的接口请求数据了。

处理过程如下:

 9、Selenium + Charles 方案

这个时候的爬虫代码,就变简单了,只要无脑点击就好。

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time

# 浏览器驱动的存放位置
service = Service(executable_path=r"G:\msedgedriver.exe")
driver = webdriver.Edge(service=service)
driver.get("你的网页")

# 暂停 3 秒  等待网页加载完成
time.sleep(3)

# 找到  省    下拉框元素
province_element = driver.find_element(By.ID, 'province')
# 创建 Select 对象
province_select = Select(province_element)
# 找到  市  下拉框元素
city_element = driver.find_element(By.ID, 'city')
# 创建 Select 对象
city_select = Select(city_element)

# 输入文件
input_path = r"C:\Users\Administrator\Desktop\py\city"

for  province  in  range(1, 35):
    print('-----------省份【' + str(province) + '】开始')
    # 选中省份
    province_select.select_by_value(str(province))

    file_path = input_path + "\\"+str(province)+'.txt'
    with open(file_path, 'r', encoding='utf-8') as input_file:
            for line in input_file:
                city = line.strip()
                print('---------------城市【'+city+'】开始')
                # 选中城市
                city_select.select_by_value(city)
                # 找到 搜索 按钮
                submit_element = driver.find_element(By.ID, 'submit')
                # 点击搜索
                submit_element.click()
                # 暂停 2 秒  等待网页加载完成
                time.sleep(2)
                print('---------------城市【'+city+'】结束')
    print('-----------省份【' + str(province) + '】结束')

# 关闭驱动
driver.quit()

 10、分析 Charles 会话 JSON

分析 Charles 会话 JSONicon-default.png?t=O83Ahttps://blog.csdn.net/matrixlzp/article/details/142308538?spm=1001.2014.3001.5502

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

细胞分裂检测系统源码分享

细胞分裂检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

计算机人工智能前沿进展-大语言模型方向-2024-09-20

计算机人工智能前沿进展-大语言模型方向-2024-09-20 1. Multimodal Fusion with LLMs for Engagement Prediction in Natural Conversation Authors: Cheng Charles Ma, Kevin Hyekang Joo, Alexandria K. Vail, Sunreeta Bhattacharya, Alvaro Fern’andez Garc’ia, Kailan…

[数据集][目标检测]智慧交通铁轨裂缝检测数据集VOC+YOLO格式4类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2709 标注数量(xml文件个数):2709 标注数量(txt文件个数):2709 标注…

独立站技能树/工具箱1.0 总纲篇丨出海笔记

正所谓要把一件事做到90分很难,但做到60分基本上照着SOP做到位都没问题,如果我们能把每件事都做到60分,那绝对比至少60%的人都强,除非你的对手不讲武德——那就是他很可能看了我这篇文章,不但每方面都超过及格线&#…

fiddler抓包06_抓取https请求(chrome)

课程大纲 首次安装Fiddler,抓https请求,除打开抓包功能(F12)还需要: ① Fiddler开启https抓包 ② Fiddler导出证书; ③ 浏览器导入证书。 否则,无法访问https网站(如下图&#xff0…

将sqlite3移植到arm开发板上:

一、下载源代码 sqlite3网址:https://www.sqlite.org/download.html 下载:sqlite-autoconf-3460100.tar.gz 二、解压 在Linux家目录下创建一个sqlite3文件夹,将压缩包复制到该文件夹下,再在该目录下打开一个终端,执行…

【Linux】简易日志系统

目录 一、概念 二、可变参数 三、日志系统 一、概念 一个正在运行的程序或系统就像一个哑巴,一旦开始运行我们很难知晓其内部的运行状态。 但有时在程序运行过程中,我们想知道其内部不同时刻的运行结果如何,这时一个日志系统可以有效的帮…

【路径规划】 红嘴蓝鹊优化器:一种用于2D/3D无人机路径规划和工程设计问题的新型元启发式算法

摘要 本文提出了一种新型元启发式算法——红嘴蓝鹊优化器(RBMO),用于解决2D和3D无人机路径规划以及复杂工程设计问题。RBMO灵感来源于红嘴蓝鹊的群体合作行为,包括搜索、追逐、捕猎和食物储藏。该算法通过模拟这些行为&#xff0…

prober found high clock drift,Linux服务器时间不能自动同步,导致服务器时间漂移解决办法。

文章目录 一、场景二、问题三、解决办法(一)给服务器添加访问网络能力(二)手动同步1. 检查有没有安装ntp2. 没有安装ntp则离线安装ntp2.1 下载安装包2.2 安装2.3 启动 ntp 3. 设置内部时钟源3.1 编辑/etc/ntp.conf3.1 重启ntp服务…

低代码平台后端搭建-阶段完结

前言 最近又要开始为跳槽做准备了,发现还是写博客学的效率高点,在总结其他技术栈之前准备先把这个专题小完结一波。在这一篇中我又试着添加了一些实际项目中可能会用到的功能点,用来验证这个平台的扩展性,以及总结一些学过的知识。…

【C++】关键字auto详解

🦄个人主页:小米里的大麦-CSDN博客 🎏所属专栏:C_小米里的大麦的博客-CSDN博客 🎁代码托管:C: 探索C编程精髓,打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、前言 二、类型别名思考 三、auto简介 四…

python 运行其他命令行工具,实时打印输出内容

起因, 目的: python 运行一个命令,最简洁的写法是: import os # 转换视频格式。 cmd "ffmpeg -i a1.ts -c copy a1.mp4"os.system(cmd)问题: 如果上面的视频比较大,需要运行很长时间,那么感觉就像是卡住…

向日葵和这三款远程控制神器,让你轻松掌控一切!

向日葵远程控制,作为科技控们的最佳良伴,一定是我们居家、办公必备的神器啦!别看咱们工作、学习有时候烦得心都碎成了二八瓣,但有了向日葵远程控制,咱们的效率绝对能飞起来!今天,咱们就一起走进…

C++11 lambda表达式

前言 上几期我们介绍了类的新功能,右值引用、完美转发语法特性,本期继续介绍C11的新语法特性,即lambda表达式! 目录 前言 lambda表达式 lambda的引入 什么是lambda 表达式 lambda表达式的语法 捕捉列表说明 lambda的底层…

卡西欧相机SD卡格式化后数据恢复指南

在数字摄影时代,卡西欧相机以其卓越的性能和便携性成为了众多摄影爱好者的首选。然而,随着拍摄量的增加,SD卡中的数据管理变得尤为重要。不幸的是,有时我们可能会因为操作失误或系统故障而将SD卡格式化,导致珍贵的照片…

Linux笔记---简单指令

1. 使用的环境 博主使用的是华为云服务器xshell终端的方式学习的,因为据说这样的方式比较接近以后的工作环境。 其中云服务器安装的是Ubuntu操作系统(以Linux为内核,适合新手学习Linux的一个版本) 这里的云服务器不一定使用华为的,但是我在…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0920)

十三、文章分类页面 - [element-plus 表格] Git仓库:https://gitee.com/msyycn/vue3-hei-ma.git 基本架子 - PageContainer 功能需求说明: 基本架子-PageContainer封装文章分类渲染 & loading处理文章分类添加编辑[element-plus弹层]文章分类删除…

win7自带壁纸丢失主题丢失

有时候盗版破解或者其他美化工具会导致win7自带的壁纸丢失,从个性化管理里面无法恢复原始的壁纸(如下图),但是由于工作原因公司的电脑又不方便设置第三方的壁纸,所以找了一下解决方案。 经典问题,百度找到的…

用户态缓存:高效数据交互与性能优化

目录 1. 用户态缓存区工作背景 1.1 为什么每条连接都需要读写缓存区 1.1.1 读缓存区(Read Buffer) 1.1.2 写缓存区(Write Buffer) 1.2 用户态缓存区的工作流程 1.3 用户态缓存区的重要性 2. UDP 和 TCP 的设计差异 2.1 UD…

机器翻译与数据集_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录介绍机器翻译下载和预处理数据集词元化词表加载数据集训练模型对上述代码中出现的Vocab进行总体解释和逐行解释使用场景 小结练习答案1. num_examples 参数对词表大小的影响2. 对于没有单词边界的语言,单词级词元化的有效性 介绍…