using dodohold.core; using Sayaka.Common; using System.Diagnostics; using System.Text.RegularExpressions; using System.Web; namespace molilian.core { public partial class PddUnionPlus { public static string _url_pattern = @"https?://(?:[\w-]+\.)*(?:yangkeduo\.com|pinduoduo\.com)(?:/[^\s]*)?"; public static string GetLink(string content) { if (string.IsNullOrEmpty(content)) return content; string result = content; // Regex regex = new(_url_pattern); MatchCollection matches = regex.Matches(content); foreach (Match m in matches.Cast()) { string url = m.Value; return url; } return string.Empty; } public static string GetDeeplink(string url) { string result = $"pinduoduo://com.xunmeng.pinduoduo/{url}"; return result; } private string ExtractGoodsIdUrl(string url) { var uri = new Uri(url); var queryParams = HttpUtility.ParseQueryString(uri.Query); string goodsId = queryParams["goods_id"]; if (!string.IsNullOrEmpty(goodsId) && uri.AbsolutePath.StartsWith("/goods")) { // 保持域名和路径不变,仅保留 goods_id 参数 var baseUrl = $"{uri.Scheme}://{uri.Host}{uri.AbsolutePath}"; return $"{baseUrl}?goods_id={goodsId}"; } return url; // 如果没有找到 goods_id 参数,则返回原始 URL } private bool IsTrackUrl(string sourceUrl) { string pattern = @"^https?://mobile\.yangkeduo\.com/goods(\d*)\.html\?ps=.*$"; Regex regex = new Regex(pattern); return regex.IsMatch(sourceUrl); } /// /// bool:是否ps链接,string 处理后的链接 /// /// /// /// public async Task GetRedirectedUrlAsync(string sourceUrl, CancellationToken cancellationToken = default) { var isTrackUrl = IsTrackUrl(sourceUrl); if (!isTrackUrl) return ExtractGoodsIdUrl(sourceUrl); string redirectedUrl = sourceUrl; try { string useragent = ProviderFakeUserAgent.RandomMobile; WebClientUtility client = new() { AllowAutoRedirect = false, UserAgent = useragent, }; client.Proxy = _proxy; #if DEBUG client.Proxy = null; #endif var response = await client.RequestAsync(sourceUrl, "GET", cancellationToken); if (!response.Successed) return null; if (response.ResponseMessage.StatusCode == System.Net.HttpStatusCode.RedirectKeepVerb || response.ResponseMessage.StatusCode == System.Net.HttpStatusCode.TemporaryRedirect) { redirectedUrl = response.ResponseMessage.Headers.Location.ToString(); redirectedUrl = ExtractGoodsIdUrl(redirectedUrl); return redirectedUrl; } } catch (Exception ex) { } return sourceUrl; } public static PddDataDTO GetFormattedObject(string content, string ip = "", string oaid = "") { string shortLinkurl = GetLink(content); string deeplink_url = GetDeeplink(shortLinkurl); var link_type = LinkTypeEnum.unknown; if (!string.IsNullOrEmpty(shortLinkurl) && shortLinkurl.StartsWith("https://p.pinduoduo.com/")) { link_type = LinkTypeEnum.other_aff; } return new PddDataDTO() { message = string.Empty, link_type = link_type, channel = TkChannelEnum.pdd, accountName = string.Empty, success = false, content = content, ip = ip, oaid = oaid, elapsedTime = 0, itemName = "点击打开拼多多APP", shortLinkurl = string.Empty, deeplink_url = string.Empty, create_time = DateTime.Now, end_point = _end_point, }; } public async Task PddParseAsync(string content, int commerceType, PddDataDTO result, CancellationToken cancellationToken = default) { string message = "OK"; string url = GetLink(content); if (string.IsNullOrEmpty(url)) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.pdd; result.message = "放弃转链"; result.reason = "无效链接"; result.accountId = 0; result.accountName = string.Empty; result.content = content; return result; } string shortLinkurl = url; if (result.link_type == LinkTypeEnum.other_aff) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.pdd; result.message = "放弃转链"; result.reason = "其他推广链接"; result.accountId = 0; result.accountName = string.Empty; result.content = content; return result; } if (!TestParseCore.InWhitelist(result.ip, result.oaid) && FlowControlIgnoreRequest(_config, out string reason)) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.pdd; result.message = "放弃转链"; result.reason = reason; result.accountId = 0; result.accountName = string.Empty; result.content = content; return result; } var isTrackUrl = IsTrackUrl(url); //不是跟踪链接 ps=*** 就返回 //2024-09-26 放开数字id转链 //if (!isTrackUrl) //{ // result.success = false; // result.link_type = LinkTypeEnum.unknown; // result.channel_type = ChannelTypeEnum.pdd; // result.message = "放弃转链"; // result.reason = "数字id链接"; // result.accountId = 0; // result.accountName = string.Empty; // result.content = content; // return result; //} //去追踪 Stopwatch stopwatch = Stopwatch.StartNew(); stopwatch.Start(); var redirectedUrl = await GetRedirectedUrlAsync(url, cancellationToken); stopwatch.Stop(); if (redirectedUrl != url) { result.rawContent2 = redirectedUrl; url = redirectedUrl; result.elapsedTime2 = (int)stopwatch.ElapsedMilliseconds; } switch (commerceType) { case 1: case 2: result.success = false; result.message = "放弃转链"; result.reason = $"厂商放弃{commerceType}"; return result; } Stopwatch stopwatch2 = Stopwatch.StartNew(); stopwatch2.Start(); switch (_account.work_mode) { case PddUnionWorkMode.SiteApi: result = await UnionGeneratelink(result, url, cancellationToken); break; //case PddUnionWorkMode.AffApi: // result = await GetPromotionByAffAsync(result, url, cancellationToken); // break; case PddUnionWorkMode.Crawler: default: result = await transferUrl(result, url, cancellationToken); break; } stopwatch2.Stop(); result.elapsedTime3 = (int)stopwatch2.ElapsedMilliseconds; return result; } } }