首页 / 文档 / 强类型映射

强类型映射

默认情况下 GetAsync() 返回 Dictionary<string, string>。如果你想要强类型结果,使用泛型版本 GetAsync<T>()

基本用法

定义一个 POCO 类,属性名与 Recipe 中的字段名一致:

public class Repo
{
    public string? Title { get; set; }
    public string? Url   { get; set; }
    public string? Lang  { get; set; }
    public int     Stars { get; set; }
}

var repos = await Pa.Source("Github.Trending").GetAsync<Repo>();
foreach (var r in repos.Data)
    Console.WriteLine($"[{r.Lang}] {r.Title} — {r.Stars} stars");

特性标注方式

使用 [Selector] 特性标注属性,直接指定 CSS 选择器:

[Recipe("MyTrending", Category = "Tech")]
[Get("https://github.com/trending")]
[Container("article.Box-row")]
public class Repo
{
    [Selector("h2 a")]                                         public string? Title { get; set; }
    [Selector("h2 a", Attr = "href", Base = "https://github.com")] public string? Url { get; set; }
    [Selector("span[itemprop=programmingLanguage]")]            public string? Lang { get; set; }
}

Pa.DiscoverFromLoadedAssemblies();
var data = await Pa.Source("MyTrending").GetAsync<Repo>();

特性说明

特性用途位置
[Recipe("Name")]声明数据源
[Get("url")]请求地址
[Container("selector")]容器选择器
[Selector("css")]字段选择器属性
[Selector("css", Attr = "href")]取属性值属性
[Selector("css", Base = "https://...")]URL 拼接基地址属性

类型转换

Aneiang.Pa 自动将字符串转换为目标属性类型:

public class NewsItem
{
    public string? Title    { get; set; }
    public string? Url      { get; set; }
    public int     Rank     { get; set; }    // 自动转 int
    public DateTime Date   { get; set; }    // 自动转 DateTime
    public bool     IsHot   { get; set; }    // 自动转 bool
}

与 YAML Recipe 配合

YAML Recipe 定义字段名,强类型映射定义 C# 类:

# recipes/news/myapi.yaml
name: MyAPI
category: News
display_name: 我的 API
fetch:
  url: https://api.example.com/items
parse:
  type: html
  container: ".item"
  fields:
    title: { selector: "h3" }
    url:   { selector: "a", attr: href }
    rank:  { selector: ".rank" }
public class MyItem
{
    public string? Title { get; set; }
    public string? Url   { get; set; }
    public int     Rank  { get; set; }
}

Pa.Configure(c => c.UseRecipesFolder("./recipes"));
var data = await Pa.Source("MyAPI").GetAsync<MyItem>();

流式强类型

await foreach (var item in Pa.Source("WeiBo").StreamAsync<NewsItem>())
{
    Console.WriteLine($"{item.Title}");
}