delphi 12 学习如何登陆网站下载文件

启动时等待验证码.

输入验证码后,等待处理数据

处理完成后,显示数据

实现原理:利用已有的账号和密码登录后产生的cookie,向服务器请求数据.返回的数据是JSON格式,后期需要自己整理.

注意,请在程序中使用同一个TnetHttpClient控件来完成.因为里面保存了cookie信息

需要了解的知识点:

一. token:

在 Web 开发中,Token 经常用于用户身份验证。当用户成功登录后,服务器会生成一个 Token,并将其返回给客户端。客户端将该 Token 存储在本地,以后的请求都携带该 Token,用于证明请求的合法性。服务器会根据 Token 验证用户身份,并决定是否允许该请求访问相关资源。

在登录页面的源代码中,按 ctrl+F 查找 token

二.cookie

复制代码

Cookie 主要用于跟踪用户的状态和行为,以提供个性化的用户体验。通过存储在 Cookie 中的数据,网站可以识别和区分不同的用户,记录用户的偏好设置,保持用户登录状态,以及追踪用户在网站上的访问轨迹等。这些信息可以在用户下次访问网站时被读取并使用。Cookie 有两种类型:会话性 Cookie 和持久性 Cookie。会话性 Cookie 存储在用户的计算机上,但在用户关闭浏览器时会被自动删除。这种类型的 Cookie 通常用于临时存储会话信息,如用户的登录状态。持久性 Cookie 有一个指定的过期日期,可以在用户关闭浏览器后继续存在。这种类型的 Cookie 可以用于记住用户的偏好设置和提供个性化的内容。

复制代码

三.Referer 

Referer 是一个 HTTP 请求头字段,提供了当前请求的来源信息,用于统计、安全验证和针对性处理等用途。但由于用户隐私的考虑,Referer 值可能为空或被限制。

四.数据的请求地址.就是向服务器请求数据的地址.

下面的动画中,展示了登录网站后,如何获取Referer和数据请求地址的过程.

第一步就是登陆了,

第二步是转到要下载文件的页面,按F12调出开发者工具.红3是清除当前记录,避免干扰

 第三步.点击下载文件,然后会看到出现两条记录(以我当面的页面为例).我们观察第二个地址.里面有limit,明显是分页的,舍去,取第一个地址.

也就是数据请求的地址找到了. 等于号后面的那串13位数字,我后面会讲

第四步,单击第一条记录,可以看到它的标头信息,里面就有Referer 信息,记下来.其实为了保险起见,标头里的信息应该全部封装到代码里才算完美.

 点击预览选项卡,这里你就可以看到你的数据包了,我们要抓的,就是这个数据. 

 最后我们再回头看看这一串13位的数字.它其实是一个13位的时间戳,它是给服务器用来校验请求的时间是否在合法范围内.知道它是什么,要做一个就简单了

下面是完整的程序代码:

复制代码

typeTForm1 = class(TForm)Image1: TImage;Label1: TLabel;NetHTTPClient1: TNetHTTPClient;scGPEdit1: TscGPEdit;cxGrid1Level1: TcxGridLevel;cxGrid1: TcxGrid;cxGrid1TableView1: TcxGridTableView;cxGrid1TableView1Column1: TcxGridColumn;cxGrid1TableView1Column2: TcxGridColumn;cxGrid1TableView1Column3: TcxGridColumn;cxGrid1TableView1Column4: TcxGridColumn;cxGrid1TableView1Column5: TcxGridColumn;scGPPanel1: TscGPPanel;scGPPanel2: TscGPPanel;procedure FormCreate(Sender: TObject);procedure Image1Click(Sender: TObject);procedure scGPEdit1RightButtonClick(Sender: TObject);procedure scGPEdit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);private{ Private declarations }public{ Public declarations }end;TMyThread = class(TThread)protectedprocedure Execute; override;end;varForm1: TForm1;implementationusesDateUtils;{$R *.dfm}// 取13位数字时间
function GetDigitalTime: string;
varS_Char: string;
beginS_Char := FormatSettings.DateSeparator;Result := IntToStr(MilliSecondsBetween(IncHour(now, -8), StrToDateTime('1970'+ S_Char + '1' + S_Char + '1')));
end;procedure LoadTxtToCxGrid();   //把处理好的数据,加载进表格,展示给用户
beginvar Lines := TStringList.Create;tryLines.LoadFromFile('d:\resule.txt', TEncoding.UTF8);var view := form1.cxGrid1TableView1.DataController;for var i := 1 to Lines.Count - 1 dobeginvar k := view.AppendRecord;var arr: TArray<string> := Lines[i].Split([',']);for var j := 0 to 4 dobeginview.Values[k, j] := arr[j];  //这里一定要注意.先在cxgrid中创建好列,这里是五列,所以才写了0 to 4 .群里有个老六,就为这点喷我,搞得很不愉快.end;end;//隐藏验证码部分,显示出数据表Form1.scGPPanel1.Visible := False;Form1.Height := 300;Form1.scGPPanel2.Visible := True;Form1.scGPPanel2.Align := alClient;finallyLines.Free;DeleteFile('D:\123.txt');        //删除文件DeleteFile('d:\resule.txt');     //删除文件end;
end;function washData(): Boolean;  //清洗数据
varReader: TStreamReader;Writer: TStreamWriter;txts: string;JSONObj: TJSONObject;StockValue, GoodsNameValue: string;JsonArray: TJSONArray;
beginReader := TStreamReader.Create('D:\123.txt');Writer := TStreamWriter.Create('D:\resule.txt');trytxts := Reader.ReadToEnd; // 读取全部的文件内容JSONObj := TJSONObject.ParseJSONValue(txts) as TJSONObject;tryif Assigned(JSONObj) thenbeginJsonArray := JSONObj.GetValue('rows') as TJSONArray;    //选对节点,才能拿到正确数据Writer.WriteLine('物料代码,物料名称,规格型号,单位,库存');for var i := 0 to JsonArray.Count - 1 dobeginStockValue := JsonArray.Items[i].GetValue<string>('stock'); // 获取 stock 字段值GoodsNameValue := JsonArray.Items[i].GetValue<string>('goods_name'); // 获取 goods_name 字段值// 输出数据if GoodsNameValue <> '' thenbeginGoodsNameValue := GoodsNameValue.Replace('\', '', [rfReplaceAll]);  //去掉所有'\'GoodsNameValue := GoodsNameValue.Replace('刀', '刀/', [rfReplaceAll]);GoodsNameValue := GoodsNameValue.Replace('丝锥', '丝锥/', [rfReplaceAll]);GoodsNameValue := GoodsNameValue.Replace('钻D', '钻/D', [rfReplaceAll]);GoodsNameValue := GoodsNameValue.Replace('钻头', '钻头/', [rfReplaceAll]);var arr: tarray<string>;arr := GoodsNameValue.Split(['/']);Writer.WriteLine(arr[0] + ',' + arr[1] + ',' + arr[2] + ',' + arr[3]+ ',' + StockValue);end;end;end;finallyJSONObj.Free;end;finallyReader.Free;Writer.Free;//写入表格LoadTxtToCxGrid;end;
end;procedure TForm1.scGPEdit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
beginif Key = 13 thenscGPEdit1RightButtonClick(Sender);
end;procedure TForm1.scGPEdit1RightButtonClick(Sender: TObject);
varss_Request: TStringList;token: string;captcha: string;match: TMatch;S2, S3: TMemoryStream;Resp: IHTTPResponse;
const// 登陆页面TokenURL = '登陆地址';// 提交网址PostURL = '登陆地址';
begin//封装标头信息NetHTTPClient1.UserAgent :='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36';NetHTTPClient1.Accept := 'application/json, text/javascript, */*; q=0.01';NetHTTPClient1.ContentType := 'application/json';captcha := Trim(scGPEdit1.text); // 用户输入的验证码if Length(captcha) <> 4 then // 初步判断用户输入的验证码长度是否正确beginShowMessage('请输入正确的验证码');Exit;end;// --------获取token  ---------Resp := NetHTTPClient1.Get(TokenURL); // 取得登陆页面的源代码// -------用正则取出tokenmatch := TRegEx.match(Resp.ContentAsString(TEncoding.UTF8), '[\w]{32}');if match.Success thenbegintoken := match.Groups[0].Value;endelsebeginShowMessage('没有找到token');Exit;end;// --------封包---------ss_Request := TStringList.Create;ss_Request.Add('__token__=' + token);ss_Request.Add('username=登陆的用户名');ss_Request.Add('password=登陆密码');ss_Request.Add('captcha=' + scgpedit1.text);  //scgpedit1.text 是验证码,这个需要手动输入// resp 提交登陆请求Resp := NetHTTPClient1.Post(PostURL, ss_Request);if Resp.StatusCode = 200 then  //如果登陆成功,则开始抓包beginSleep(500);NetHTTPClient1.CustomHeaders['X-Requested-With'] := 'XMLHttpRequest';NetHTTPClient1.CustomHeaders['Referer'] :=  'xxxx';S2 := TMemoryStream.Create;NetHTTPClient1.Get('数据请求的地址'+ GetDigitalTime, S2);S2.Position := 0;S2.SaveToFile('d:\123.txt');    //把流数据保存成文件,以便后期处理scGPEdit1.text := '稍等,处理中...';scGPEdit1.Enabled := false;washData;    //自定义函数,整理123.txt中的内容为需要的格式endelseShowMessage('请求失败');
end;
//初始化窗口.开始时只显示验证码部分
procedure TForm1.FormCreate(Sender: TObject);
beginscGPPanel2.Visible := false;Self.Height := 120;scGPEdit1.Text := '请等待...';scGPEdit1.Enabled := False;Image1Click(Sender);
end;procedure TForm1.Image1Click(Sender: TObject); // 点击图片时更新验证码
varMyThread: TMyThread;
begin// 创建并启动自定义线程MyThread := TMyThread.Create(true);MyThread.FreeOnTerminate := true; // 线程执行结束后自动释放MyThread.Start;
end;{ TMyThread }
procedure TMyThread.Execute;
varStream: TMemoryStream;pngimage: TPngImage;
beginStream := TMemoryStream.Create;pngimage := TPngImage.Create;try   Form1.NetHTTPClient1.Get('验证码地址',  Stream);     // 下载验证码Stream.Position := 0;    //初始化读写位置pngimage.LoadFromStream(Stream); // 转换流Form1.Image1.Picture.Bitmap.Assign(pngimage); // 把验证码显示出来if Form1.Image1.Picture.Bitmap = nil thenShowMessage('验证码加载失败,请点击右边的图片重新加载')elsebeginForm1.scGPEdit1.Enabled := true;Form1.scGPEdit1.text := '';end;finallypngimage.Free;Stream.Free;end;
end;end.

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

btslab靶场-通过xss获取他人cookie并利用

目录 安装 通过xss获取cookie cookie利用 安装 下载btslab靶场链接&#xff1a;https://pan.baidu.com/s/1I9ZgzlZEWdobINGQUhy7Jw?pwd8888 提取码&#xff1a;8888 用phpEnv或者phpStudy部署好靶场环境&#xff08;这里就省略了&#xff09; 通过xss获取cookie 先访问…

Golang | Leetcode Golang题解之第316题去除重复字母

题目&#xff1a; 题解&#xff1a; func removeDuplicateLetters(s string) string {left : [26]int{}for _, ch : range s {left[ch-a]}stack : []byte{}inStack : [26]bool{}for i : range s {ch : s[i]if !inStack[ch-a] {for len(stack) > 0 && ch < stack…

通过Java实现插入排序(直接插入,希尔)与选择排序(直接选择,堆排)

目录 &#xff08;一&#xff09;插入排序 1.直接插入排序 &#xff08;1&#xff09;核心思想&#xff1a; &#xff08;2&#xff09;代码实现&#xff08;以从小到大排序为例&#xff09;&#xff1a; &#xff08;3&#xff09;代码分析&#xff1a; 2.希尔排序&#xff08…

MQ消息队列篇:三大MQ产品的必备面试种子题

MQ有什么用&#xff1f; MQ&#xff08;消息队列&#xff09;是一种FIFO&#xff08;先进先出&#xff09;的数据结构&#xff0c;主要用于实现异步通信、削峰平谷和解耦等功能。它通过将生产者生成的消息发送到队列中&#xff0c;然后由消费者进行消费。这样&#xff0c;生产…

(四)activit5.23.0修复跟踪高亮显示BUG

一、先看bug 在 &#xff08;三&#xff09;springboot2.7.6集成activit5.23.0之流程跟踪高亮显示 末尾就发现高亮显示与预期不一样&#xff0c;比如上面的任务2前面的箭头没有高亮显示。 二、分析原因 具体分析步骤省略了&#xff0c;主要是ProcessInstanceHighlightsResour…

【iOS】暑假第二周——网易云APP 仿写

目录 前言首页关于UINavigationBarAppearance “我的”账号夜间模式——多界面传值遇到的问题所用到的其他知识整理NSNotificationreloadData各种键盘模式 总结 前言 有了之前仿写ZARA的基础&#xff0c;本周我们仿写了网易云APP&#xff0c;在这里对多界面传值进行了首次应用—…

算力共享中神经网络切片和算力分配策略

目录 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进行映射 算力分配策略 get_current_shard 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进…

【MySQL】索引——索引的引入、认识磁盘、磁盘的组成、扇区、磁盘访问、磁盘和MySQL交互、索引的概念

文章目录 MySQL1. 索引的引入2. 认识磁盘2.1 磁盘的组成2.2 扇区2.3 磁盘访问 3. 磁盘和MySQL交互4. 索引的概念4.1 索引测试4.2 Page4.3 单页和多页情况 MySQL 1. 索引的引入 海量表在进行普通查询的时候&#xff0c;效率会非常的慢&#xff0c;但是索引可以解决这个问题。 -…

PHP中关于排名和显示的问题

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

RabbitMQ应用场景及特性

RabbitMQ是一款开源的消息队列中间件&#xff0c;拥有非常好用的管理控制面板&#xff0c;类似使用navicat一样&#xff0c;简便的操纵数据库。 应用场景 一、流量削峰 在一些并发量较高的场景下&#xff0c;比如秒杀活动&#xff0c;抢票等&#xff0c;同一时间访问量急剧增…

【Linux】shell命令与Linux权限的概念

目录 一、shell命令二、Linux权限的概念2.1 Linux权限的概念2.1.1 用户2.1.2 指令2.1.2.1 su指令2.1.2.2 sudo指令 2.2 Linux权限管理2.2.1 文件访问者的分类&#xff08;人&#xff09;2.2.2 文件类型和访问权限&#xff08;事物属性&#xff09;2.2.2.1 文件类型2.2.2.2 基本…

[240804] OpenTofu 1.8.0 发布,带来更友好的编码体验 | 生成式 AI 滥用现象分析

目录 OpenTofu 1.8.0 发布&#xff0c;带来更友好的编码体验生成式 AI 滥用现象分析 OpenTofu 1.8.0 发布&#xff0c;带来更友好的编码体验 OpenTofu 1.8.0 现已发布&#xff0c;主要功能包括&#xff1a; 变量和局部值的早期求值: 现在可以在模块源、后端配置和状态加密等更…

使用 1panel面板 部署 springboot 和 vue

代码仓库&#xff1a;还没弄 目录 网站介绍安装步骤1. 准备云服务器2. 准备域名&#xff08;可跳过&#xff09;3. 安装1panel面板4. 服务器开放端口5. 进入1panel面板6. 安装并启动软件&#xff08;服务器和面板开放端口&#xff09;7. 打包并上传项目7.1 打包 Java项目&#…

网页保护用户 小tips

在使用创建web开发的过程中&#xff0c;直接使用用户名url&#xff0c;容易造成用户信息的被攻击&#xff0c;例如对方直接访问 ../../.../username 的网页&#xff0c;可以窃取用户信息&#xff0c;然而把usename变成一堆乱码就安全的多 效果&#xff1a; 代码&#xff1a;…

想做抖音短视频,视频素材去哪里找啊?

各位抖音上的短视频创作者们&#xff0c;是否曾幻想过自己的作品能够在全网爆火&#xff0c;却常因为缺少那些能够让视频更加生动的素材而感到困扰&#xff1f;不用担心&#xff0c;今天我要为大家介绍几个优秀的视频素材网站&#xff0c;让你的抖音之路顺风顺水&#xff01; …

星环科技与宁夏银行“大数据联合实验室”揭牌,持续打造金融科技新范式

5月30-31日&#xff0c;2024向星力未来数据技术峰会期间&#xff0c;在峰会现场来宾共同见证下&#xff0c;星环科技与宁夏银行“大数据联合实验室”正式揭牌&#xff0c;宁夏银行股份有限公司首席信息官崔彦刚与星环科技副总裁邱磊共同为联合实验室揭牌。 星环科技与宁夏银行借…

【每日刷题】Day92

【每日刷题】Day92 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 面试题 16.05. 阶乘尾数 - 力扣&#xff08;LeetCode&#xff09; 2. 取近似值_牛客题霸_牛客网 (n…

4. 最长公共前缀

4. 最长公共前缀 题目题目分析 题目 题目分析 首先要对字符串数组进行分析&#xff0c;字符串数组元素的最长公共前缀肯定不会超过最小元素长度&#xff0c;并如存在公共前缀则需遍历整个字符串元素&#xff0c;有点像二维数组&#xff0c;最后加上截取字符串加上判空操作就完…

测试——Selenium

内容大纲: 什么是自动化测试 什么是Selenium Selenium工作原理 Selenium环境搭建 Selenium API 目录 1. 什么是自动化测试 2. 什么是Selenium 3. Selenium工作原理 4. Selenium环境搭建(java) 5. Selenium API 5.1 定位元素 5.1.1 CSS选择器定位元素 5.1.2 XPath定位元…

Kubernets(k8s) 网络原理三:同主机内Pod相互访问

前两篇文章中我们介绍了pod怎么和宿主机通信以及pod怎么访问外网&#xff0c;这两种通信是理解pod间通信的基础。 关于pod间的相互访问&#xff0c;这里还需要细化一下。回想一下pod在k8s节点中的分布&#xff0c;两个pod可能分布在同一台宿主机上&#xff0c;也可能分布在不同…