delphi/python 实现小红书xhs用户作品列表和图片/视频无水印解析

技术学习,请勿用与非法用途!!!

成品图

用户作品列表接口
/api/sns/web/v1/user_posted?num=30&cursor=&user_id=642bf0850000000011022c4e&image_scenes=
http Get方式,请求头需要带上x-s x-t签名验证

笔记明细接口
/api/sns/web/v1/feed
data = {"source_note_id":"64356527000000001303282b", "image_scenes":["CRD_PRV_WEBP","CRD_WM_WEBP"]}
http Post方式,请求头需要带上x-s x-t签名验证
x-s算法部分是js+python完成

unit ApiXHS;interface
usesWindows, Messages, SysUtils, Classes, Forms, OverbyteIcsWSocket,OverbyteIcsHttpProt, OverbyteIcsSuperObject, OverbyteIcsUtils, OverbyteIcsWndControl;type// 笔记信息PNoteItem = ^TNoteItem;TNoteItem = recorduser_id: string; //用户idnickname: string; //昵称avatar: string; //头像note_id: string;collected_count: Integer; //收藏数liked_count: Integer; //点赞数comment_count: Integer; //评论数share_count: Integer; //分享数create_time: TDateTime; //创建时间note_type: string; //类型   video -- 或 普通 normaltitle: string; //标题desc: string;image_list: TStrings; //图片列表或视频封面video_addr: string; //视频地址tag_list: TStrings;end;type// 小红书接口--仅学习交流 请勿用于非法用途TXHS = classprivatefunction GetCookie: string;procedure SetCookie(const Value: string);protectedhttp: TSslHttpCli;ssl: TSslContext;_a1: string;publicconstructor Create;destructor Destroy; override;function get_xs( 算法\/: jeomoo168 ): Boolean;function request(url, api, data: string; var json: ISuperObject; var s: string): Boolean; //请求function note_info(p: PNoteItem; var s: string): Boolean; //笔记信息function parse_noteId(url: string): string; //笔记链接->解析对于的笔记idfunction parse_userId(url: string): string; //作者主页链接->解析对于的用户idfunction user_posted(user_id: string;var cursor, s: string; var has_more: Boolean; items: TList): Boolean; //获取作者作品列表property cookie: string read GetCookie write SetCookie;property a1: string read _a1 write _a1;end;procedure InitProfileItem(pi: PProfileItem);
procedure InitNoteItem(p: PNoteItem);implementation
usesShellAPI;procedure InitProfileItem(pi: PProfileItem);
beginpi.user_id := '';pi.nickname := '';pi.avatar := '';pi.desc := '';pi.ipLocation := '';pi.follows := 0;pi.fans := 0;pi.interaction := 0;pi.gender := -1;
end;procedure InitNoteItem(p: PNoteItem);
beginif p = nil then exit;p.user_id := '';p.nickname := '';p.avatar := '';//  p.note_id := '';p.collected_count := 0;p.liked_count := 0;p.comment_count := 0;p.share_count := 0;p.create_time := Now;p.note_type := '';p.title := '';p.desc := '';p.video_addr := '';p.image_list := TStringList.Create;p.tag_list := TStringList.Create;
end;//******************************************************************************
{ TXHS }constructor TXHS.Create;
begininherited;_a1 := '';ssl := TSslContext.Create(nil);http := TSslHttpCli.Create(nil);http.SslContext := ssl;http.Agent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188';http.Accept := 'application/json, text/plain, */*';http.AcceptLanguage := 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6';http.Reference := 'https://www.xiaohongshu.com';http.ContentTypePost := 'application/json;charset=UTF-8'; http.Timeout := 30; //默认30秒
end;destructor TXHS.Destroy;
beginssl.Free;http.Free;inherited;
end;function TXHS.GetCookie: string;
beginResult := http.Cookie;
end;procedure TXHS.SetCookie(const Value: string);
vark: Integer;
beginhttp.Cookie := Value;k := 1;_a1 := ParseTag(Value, 'a1=', ';', k);
end;function TXHS.get_xs(api, data: string; var xs, xt, s: string): Boolean;
varjson: ISuperObject;
beginResult := False;s := '';if a1 = '' then exit; //未设置cookieResult := js-get-xs('x-s生成算法\/: jeomoo168', s);tryjson := SO(s);exceptjson := SO('{}');end;xs := json.S['X-s'];xt := json.S['X-t'];
end;function TXHS.request(url, api, data: string; var json: ISuperObject; var s: string): Boolean;
varxs, xt: string; // , vbuf: UTF8String;
beginResult := False;json := SO('{}');s := '';xs := '';xt := '';data := StringReplace(data, ' ', '', [rfReplaceAll]); //data字符串中不要有空格!!! 不然会请求失败if api <> '' then //api不为空时 需要x-s x-tbeginResult := get_xs(api, EscapeChars(data), xs, xt, s);if not Result then exit;end;//  xs:=''; xt:='';http.URL := url + api;http.ExtraHeaders.Clear;//http.ExtraHeaders.Add('Accept-Encoding: gzip, deflate'); //!!! 不能加这个 加了 返回数据被压缩了http.ExtraHeaders.Add('authority: edith.xiaohongshu.com');http.ExtraHeaders.Add('origin: https://www.xiaohongshu.com');http.ExtraHeaders.Add('Content-Type: application/json;charset=UTF-8');http.ExtraHeaders.Add('x-s: ' + xs);http.ExtraHeaders.Add('x-t: ' + xt);//http.ExtraHeaders.Add('x-s-common: ');http.RcvdStream := TMemoryStream.Create; // For answertryif data = '' thenhttp.Getelsebegin//j2 := SO(data);//v := j2.S['keyword']; //搜索关键词//if v <> '' then//begin//  v := utf8encode(v); //关键词utf8编码// data := Format('{"keyword":"%s","note_type":0,"page":1,"page_size":20,"search_id":"2ci5066wl1gu6kr4q9apa","sort":"general","image_scenes":"FD_PRV_WEBP,FD_WM_WEBP"}',          [v]);//end;data := utf8encode(data);http.SendStream := TMemoryStream.Create;http.SendStream.Write(PChar(data)^, Length(data));http.SendStream.Position := 0; // Send from start!http.Post;end;excepton e: Exception dobegins := Format('%s', [Trim(e.Message)]);exit;end;end;if http.StatusCode <> 200 thenif not SameText(http.RequestDoneErrorStr, 'No Error') thenbegins := http.RequestDoneErrorStr;exit;end;SetLength(buf, http.RcvdStream.Size);Move((http.RcvdStream as TMemoryStream).Memory^, buf[1], http.RcvdStream.Size);http.RcvdStream.Free;http.RcvdStream := nil;if http.SendStream <> nil thenbeginhttp.SendStream.Free;http.SendStream := nil;end;s := Trim(Utf8ToStringA(buf)); //utf8解码   Utf8Decodetryjson := SO(s);Result := json.B['success'];exceptjson := SO('{}');end;//  if Pos('Not Acceptable',s)>0 then     s:=s+Format('  xs=%s',[xs]);
end;function TXHS.note_info(p: PNoteItem; var s: string): Boolean;
varurl, api, data: string;json, info, vi: ISuperObject;va: TSuperArray;i: Integer;
beginResult := False;s := '';if p = nil then exit;InitNoteItem(p);url := 'https://edith.xiaohongshu.com';api := '/api/sns/web/v1/feed';data := '{"source_note_id":"' + p.note_id + '","image_scenes":["CRD_PRV_WEBP","CRD_WM_WEBP"]}';Result := request(url, api, data, json, s); //'Not Acceptable'if not Result then exit;info := json.O['data'].A['items'][0].O['note_card'];if info=nil then exit; //解析失败 有可能接口更新了p.user_id := info.O['user'].S['user_id'];p.nickname := info.O['user'].S['nickname'];p.avatar := info.O['user'].S['avatar'];p.collected_count := info.O['interact_info'].I['collected_count'];p.comment_count := info.O['interact_info'].I['comment_count'];p.share_count := info.O['interact_info'].I['share_count'];p.liked_count := info.O['interact_info'].I['liked_count'];p.desc := info.S['desc'];p.create_time := GetTime_DateTime(info.I['time']);p.title := info.S['title'];p.note_type := info.S['type'];// image_listva := info.A['image_list'];for i := 0 to va.Length - 1 dobeginvi := va[i];p.image_list.Add(vi.A['info_list'][1].S['url']);end;// tag_listva := info.A['tag_list'];for i := 0 to va.Length - 1 dobeginvi := va[i];p.tag_list.Add(vi.S['name']);end;if p.note_type = 'video' thenp.video_addr := 'https://sns-video-bd.xhscdn.com/' + info.O['video'].O['consumer'].S['origin_video_key'];
end;// 笔记链接->解析对于的笔记id
function TXHS.parse_noteId(url: string): string;
vars: string;json: ISuperObject;k: Integer;
beginResult := '';if url = '' then exit;if Pos('xiaohongshu.com/explore/', url) > 0 thenbegink := Pos('?', url);if k > 0 thenurl := Copy(url, 1, k - 1);url := url + '/';k := 1;Result := ParseTag(url, '/explore/', '/', k);exit;end;// http://xhslink.com/xxxxx 格式tryhttp.FollowRelocation := False;request(url, '', '', json, s);finallyhttp.FollowRelocation := True;end;//<a href="https://www.xiaohongshu.com/discovery/item/6558d9300000000032xxxxx?app_platform=ios&amp;app_version=8.14.3&amp;share_from_user_hidden=true&amp;type=normal&amp;xhsshare=CopyLink&amp;appuid=5beaa1f00ac0a40001f2d248&amp;apptime=1700968043">Temporary Redirect</a>.//或//Redirecting to <a href="/discovery/item/6558d930000000003200698c">/discovery/item/6558d9300000000032xxxxx</a>.k := Pos('?', s);if k > 0 thens := Copy(s, 1, k - 1) + '"';k := 1;Result := ParseTag(s, 'discovery/item/', '"', k);
end;// 作者主页链接->解析对于的用户id
function TXHS.parse_userId(url: string): string;
vark: Integer;
begin
// https://www.xiaohongshu.com/user/profile/5565692bb7ba2219xxxxx
// https://www.xiaohongshu.com/user/profile/5565692bb7ba221xxxxxx?xhsshare=CopyLink&appuid=5beaa1f00ac0a40001f2d248&apptime=1700990774Result := '';if url = '' then exit;if Pos('xiaohongshu.com/user/profile/', url) = 0 then exit;k := Pos('?', url);if k > 0 thenurl := Copy(url, 1, k - 1);url := url + '/';k := 1;Result := ParseTag(url, '/profile/', '/', k);exit;
end;//获取作者作品列表
function TXHS.user_posted(user_id: string; var cursor, s: string; var has_more: Boolean; items: TList): Boolean;
varapi, data, url: string;json, vi: ISuperObject;va: TSuperArray;p: PNoteItem;i: Integer;
beginitems.Clear;has_more := False;url := 'https://edith.xiaohongshu.com';api := Format('/api/sns/web/v1/user_posted?num=30&cursor=%s&user_id=%s&image_scenes=',[cursor, user_id]);data := '';Result := request(url, api, data, json, s);if not Result then exit;if json.O['data'] = nil then exit;cursor := json.O['data'].S['cursor'];has_more := json.O['data'].B['has_more'];va := json.O['data'].A['notes'];for i := 0 to va.Length - 1 dobeginApplication.ProcessMessages;vi := va[i];New(p);InitNoteItem(p);Items.Add(p);p.user_id := vi.O['user'].S['user_id'];p.nickname := vi.O['user'].S['nickname'];p.avatar := vi.O['user'].S['avatar'];p.liked_count := vi.O['interact_info'].I['liked_count'];p.note_id := vi.S['note_id'];p.title := vi.S['display_title'];p.note_type := vi.S['type'];end;
end;end.

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

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

相关文章

前端:HTML+CSS+JavaScript实现轮播图2

前端&#xff1a;HTMLCSSJavaScript实现轮播图2 1. 和之前版本的区别2. 实现原理3. 针对上述的改进3. 参考代码 1. 和之前版本的区别 之前发布的那篇关于轮播图的文章在这&#xff1a;前端&#xff1a;HTMLCSSJavaScript实现轮播图&#xff0c;只能说存在问题吧&#xff01;比…

三防平板|手持终端PDA|8寸/10寸工业三防平板电脑主板方案定制

近年来&#xff0c;随着科技的快速发展&#xff0c;三防平板成为了各行各业中不可或缺的工具。三防平板采用IP67级别的防护设计&#xff0c;通过了多项测试标准&#xff0c;如国标和美标&#xff0c;具备防水、防摔、防尘、防撞、防震、防跌落以及防盐雾等多重防护功能。因此&a…

C++特性之多态

C作为面向对象的语言&#xff0c;三大特性之一多态在平时的编程中使用频率特别高。 本篇文章就来详细讲解一下多态。 什么是多态 不同的对象做相同的一件事会出现不同的状态&#xff0c;这就是多态。 举个列子&#xff1a;比如普通人买车票要全价购买&#xff0c;而军人只用半…

每天学习一点shell系列(2)—函数的参数传递

参考博客&#xff1a;shell 脚本-10函数_eno_zeng的博客-CSDN博客 $n 或 ${n} &#xff1a;函数内使用 $n 或 ${n} 访问对应的参数, 数字代表参数的前后顺序, $1 代表第一个参数, $2 代表第三个参数, $n 代表第n个参数&#xff1b;当n>10时&#xff0c;需要使用${n}来获取参…

苹果Vision Pro即将量产

据界面新闻消息&#xff0c;苹果公司将在今年12月正式量产第一代MR&#xff08;混合现实&#xff09;产品Vision Pro。苹果公司对Vision Pro寄予了厚望&#xff0c;预计首批备货40万台左右&#xff0c;2024年的销量目标是100万台&#xff0c;第三年达到1000万台。 苹果的供应…

Linux中的文件系统

本章主要介绍文件系统的管理 了解什么是文件系统对分区进行格式化的操作挂载分区查找文件 在Windows系统中&#xff0c;买了一块新的硬盘加到电脑后&#xff0c;需要对分区进行格式化才能使用&#xff0c;Linux系统中也是一样&#xff0c;首先我们需要了解什么是文件系统 1.…

python数据分析总结(pandas)

目录 前言 df导入数据 df基本增删改查 数据清洗 ​编辑 索引操作 数据统计 行列操作 ​编辑 df->types 数据格式化 ​编辑 日期数据处理 前言 此篇文章为个人python数据分析学习总结&#xff0c;总结内容大都为表格和结构图方式&#xff0c;仅供参考。 df导入数…

初识人工智能,一文读懂人工智能概论(1)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

【分享】我想上手机器学习

目录 前言 一、理解机器学习 1.1 机器学习的目的 1.2 机器学习的模型 1.3 机器学习的数据 二、学习机器学习要学什么 2.1 学习机器学习的核心内容 2.2 怎么选择模型 2.3 怎么获取训练数据 2.4 怎么训练模型 三、机器学习的门槛 3.1 机器学习的第一道门槛 3.2 机器…

学习pytorch19 pytorch使用GPU训练

pytorch使用GPU进行训练 1. 数据 模型 损失函数调用cuda()2. 使用谷歌免费GPU gogle colab 需要创建谷歌账号登录使用, 网络能访问谷歌3. 执行4. 代码 B站土堆学习视频&#xff1a; https://www.bilibili.com/video/BV1hE411t7RN/?p30&spm_id_frompageDriver&vd_sourc…

防水,也不怕水。Mate X5是如何做到让你湿手湿屏也不影响操作的?

相信不少人都碰到过当手机屏幕存在小水珠时&#xff0c;触控变得不灵敏&#xff0c;或者出现“幽灵触屏”&#xff0c;指东打西的情况。 尤其是在洗澡、做饭&#xff0c;或者在户外遇到下雨天气时&#xff0c;如果打湿的手机收到重要聊天消息或者电话&#xff0c;却因为湿屏导…

循环结构中 break、continue、return 和exit() 的区别

循环结构中 break、continue、return 和exit() 的区别 文章目录 循环结构中 break、continue、return 和exit() 的区别一、break语句二、continue语句三、return 语句四、exit() 函数 说明&#xff1a;本文内容参考牟海军 著《C语言进阶&#xff1a; 重点、难点与疑点解析》&a…