首页 新闻 会员 周边 捐助

.NET: 如何用 AngleSharp 给文本中的 url 加上 utm 跟踪参数

0
悬赏园豆:30 [已解决问题] 解决于 2025-11-09 22:55

想通过 AngleSharp 实现这样一个功能,解析出文本中的所有 url 进行分析

  • 如果 url 参数中没有包含 ha_source=bokeyuan&ha_sourceId=89000449,则加上
  • 如果 url 参数中包含 ha_sourceha_sourceId,但值不一样,则替换

请问如何实现?

dudu的主页 dudu | 高人七级 | 园豆:24422
提问于:2025-11-08 21:09

QueryHelpers.ParseQuery 的返回值类型是 Dictionary<string, StringValues>,没有 Set 方法

dudu 3周前

HttpUtility.ParseQueryString 的返回值类型是 NameValueCollection,有 Set 方法

dudu 3周前
< >
分享
最佳答案
0

通过下面的代码实现了

namespace Cnblogs.Text;

public partial class HtmlUtility
{
    public static async Task<string> ModifyHtmlUrls(string html, string hostname, string queryString)
    {
        var isHtmlChanged = false;
        var context = BrowsingContext.New(Configuration.Default);
        var document = await context.OpenAsync(res => res.Content(html));
        var elements = document.GetElementsByTagName("a");

        foreach (var element in elements)
        {
            if (element is IHtmlAnchorElement anchor)
            {
                var newUrl = AddUrlParameters(anchor.Href, queryString);
                if (newUrl.Contains(hostname, StringComparison.OrdinalIgnoreCase))
                {
                    if (newUrl != anchor.Href)
                    {
                        anchor.Href = newUrl;
                        isHtmlChanged = true;
                    }

                    if (anchor.Target != "_blank")
                    {
                        anchor.Target = "_blank";
                        isHtmlChanged = true;
                    }
                }
            }
        }

        return isHtmlChanged && document.Body != null ? document.Body.InnerHtml : html;
    }

    public static string AddUrlParameters(string url, string queryString)
    {
        var urlBuilder = new UriBuilder(url);
        var originQueryString = urlBuilder.Query;
        var originQueryParams = HttpUtility.ParseQueryString(originQueryString);

        var newQueryParams = QueryHelpers.ParseQuery(queryString);

        foreach (var key in newQueryParams.Keys)
        {
            if (newQueryParams.TryGetValue(key!, out var values))
            {
                originQueryParams.Set(key, values.LastOrDefault());
            }
        }

        urlBuilder.Query = originQueryParams.ToString();
        return urlBuilder.Uri.ToString();
    }
}

用到的 nuget 包

<Project>
  <ItemGroup>
    <PackageReference Include="AngleSharp" Version="1.3.1" />
    <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="9.0.10" />
  </ItemGroup>
</Project>
dudu | 高人七级 |园豆:24422 | 2025-11-09 22:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册