비공식 아카라이브 아카콘(Arcacon) .NET 라이브러리
Arcacon.NET은 아카라이브의 아카콘(Arcacon) 스티커를 프로그래밍적으로 검색, 조회, 다운로드할 수 있는 .NET 라이브러리입니다.
⚠️ 주의: 이 라이브러리는 비공식이며, 아카라이브의 사이트 구조 변경 시 동작하지 않을 수 있습니다. 과도한 자동 요청은 IP 차단의 원인이 될 수 있으니 주의하세요.
🪟 Windows 전용: WebView2 기반 로그인을 사용하므로 Windows에서만 동작합니다.
- 🔍 아카콘 검색 — 제목, 닉네임, 태그로 검색 (인기순/최신순 정렬)
- 📋 목록 조회 — 인기 아카콘 / 최신 아카콘 목록
- 🏆 상단 인기 5개 — 일간 / 주간 / 월간 인기 아카콘 5개 조회
- 📦 패키지 상세 — 패키지 정보, 스티커 목록, 태그 조회
- 🔖 구독 목록 — 내가 구독(보유) 중인 아카콘 목록 조회
- ⬇️ 이미지 다운로드 — 개별 스티커 또는 패키지 전체 일괄 다운로드
- ⚡ 병렬 다운로드 — 패키지 전체 다운로드 시 병렬 처리 + 진행 상태 콜백
- 🔐 WebView2 로그인 — WebView2 기반 arca.live 로그인 (로그인 필요 API에 사용)
사용 환경에 맞는 패키지를 설치하세요.
| 환경 | 패키지 |
|---|---|
| WinUI 3 앱 | Arcacon.NET.WinRT |
| WPF / WinForms / Console 앱 | Arcacon.NET |
# WinUI 3 앱
dotnet add package Arcacon.NET.WinRT
# WPF / WinForms / Console 앱
dotnet add package Arcacon.NET또는 NuGet Package Manager에서 Arcacon.NET 또는 Arcacon.NET.WinRT를 검색하세요.
🔒 스티커 다운로드를 제외한 모든 API는 로그인이 필요합니다.
로그인은 WebView2 기반으로 동작합니다. 앱에서 CoreWebView2 인스턴스를 전달하면, 사용자가 직접 arca.live에 로그인할 때까지 대기한 뒤 세션 쿠키를 자동으로 추출합니다.
// WebView2 초기화 (WinUI 3 예시)
await webView.EnsureCoreWebView2Async();
await client.LoginAsync(webView.CoreWebView2);using Arcacon.NET;
using Arcacon.NET.Models;
await using var client = new ArcaconClient();
// 로그인 (CoreWebView2 인스턴스 필요)
await client.LoginAsync(webView.CoreWebView2);
// 아카콘 검색
var result = await client.SearchAsync("스텔라소라");
foreach (var package in result.Packages)
Console.WriteLine($"[{package.PackageIndex}] {package.Title} - {package.SellerName}");// 인기 아카콘
var hotList = await client.GetHotListAsync(page: 1);
// 최신 아카콘
var newList = await client.GetNewListAsync(page: 1);
// 상단 인기 아카콘 5개
var dailyPopularPackages = await client.GetDailyPopularAsync();
var weeklyPopularPackages = await client.GetWeeklyPopularAsync();
var monthlyPopularPackages = await client.GetMonthlyPopularAsync();// 태그로 검색, 최신순 정렬, 2페이지
var result = await client.SearchAsync(
query: "고양이",
searchType: ArcaconSearchType.Tags,
sort: ArcaconSearchSort.New,
page: 2);var detail = await client.GetPackageDetailAsync(packageIndex: 38576);
Console.WriteLine($"제목: {detail.Title}");
Console.WriteLine($"제작자: {detail.SellerName}");
Console.WriteLine($"스티커 수: {detail.Stickers.Count}개");
Console.WriteLine($"태그: {string.Join(", ", detail.Tags)}");
foreach (var sticker in detail.Stickers)
Console.WriteLine($"[{sticker.Id}] media={sticker.ImageUrl}, video={sticker.VideoUrl ?? "null"}, poster={sticker.PosterThumbnailUrl ?? "null"}");GetPackageDetailAsync()가 반환하는 sticker.ImageUrl은 패키지 공개 API(/api/emoticon/{packageIndex}) 기준 URL로 보정되며, 비디오 스티커의 원본 주소는 sticker.VideoUrl에 유지됩니다.
// 사용 중인 아카콘만
var activePackages = await client.GetSubscribedPackagesAsync();
// 미사용 아카콘 포함
var allPackages = await client.GetSubscribedPackagesAsync(includeInactive: true);
foreach (var package in allPackages)
Console.WriteLine($"[{package.PackageIndex}] 사용 중: {package.IsActive}");// 개별 스티커 다운로드 (byte[]) — 로그인 불필요
var sticker = detail.Stickers[0];
byte[] imageData = await client.DownloadStickerAsync(sticker);
// 스트림으로 다운로드
using var stream = await client.DownloadStickerStreamAsync(sticker);var progress = new Progress<(int Completed, int Total)>(report =>
Console.WriteLine($"다운로드 중... {report.Completed}/{report.Total}"));
await client.DownloadPackageAsync(
packageIndex: 38576,
outputDirectory: @"C:\Downloads",
progress: progress);ArcaconFileNameHelper를 사용하면 다운로드 파일명을 결정할 수 있습니다.
아카라이브 CDN은 URL 경로의 확장자와 실제 응답 바이트 포맷이 다를 수 있습니다. 예를 들어 URL은 .png여도 실제 파일은 WebP로 내려올 수 있으므로, 다운로드한 파일을 저장하거나 저장된 파일명을 메타데이터에 기록할 때는 GetStickerFileName(sticker, imageData) 오버로드 사용을 권장합니다.
var detail = await client.GetPackageDetailAsync(packageIndex: 38576);
foreach (var sticker in detail.Stickers)
{
var imageData = await client.DownloadStickerAsync(sticker);
// 실제 응답 바이트 기준 확장자를 사용
var fileName = ArcaconFileNameHelper.GetStickerFileName(sticker, imageData);
Console.WriteLine(fileName);
}
// 다운로드 전 URL 기준 추정만 필요한 경우
var predictedFileName = ArcaconFileNameHelper.GetStickerFileName(detail.Stickers[0]);
// 파일명 안전 변환만 필요한 경우
var safeName = ArcaconFileNameHelper.SanitizeFileName("잘못된/파일:명");// IHttpClientFactory 패턴과 호환
var httpClient = httpClientFactory.CreateClient();
await using var client = new ArcaconClient(httpClient);모든 비동기 메서드에서 CancellationToken을 지원합니다:
using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = await client.SearchAsync("스텔라소라", cancellationToken: cancellationTokenSource.Token);| 메서드 | 로그인 필요 | 설명 |
|---|---|---|
LoginAsync |
— | WebView2를 통해 arca.live 로그인 |
SearchAsync |
✅ | 아카콘 검색 (제목/닉네임/태그, 인기순/최신순) |
GetHotListAsync |
✅ | 인기 아카콘 목록 조회 |
GetNewListAsync |
✅ | 최신 아카콘 목록 조회 |
GetDailyPopularAsync |
✅ | 상단 일간 인기 아카콘 5개 조회 |
GetWeeklyPopularAsync |
✅ | 상단 주간 인기 아카콘 5개 조회 |
GetMonthlyPopularAsync |
✅ | 상단 월간 인기 아카콘 5개 조회 |
GetPackageDetailAsync |
✅ | 패키지 상세 정보 조회 |
GetSubscribedPackagesAsync |
✅ | 구독(보유) 아카콘 목록 조회 |
DownloadStickerAsync |
❌ | 스티커 이미지 byte[] 다운로드 |
DownloadStickerStreamAsync |
❌ | 스티커 이미지 Stream 다운로드 |
DownloadPackageAsync |
✅ | 패키지 전체 일괄 다운로드 |
| 클래스 | 메서드 | 설명 |
|---|---|---|
ArcaconFileNameHelper |
SanitizeFileName |
파일명에 사용할 수 없는 문자를 제거 |
ArcaconFileNameHelper |
GetStickerFileName(sticker) |
URL 기준으로 스티커 파일명 추정 |
ArcaconFileNameHelper |
GetStickerFileName(sticker, imageData) |
다운로드한 파일 시그니처 기준으로 스티커 파일명 결정 |
| 클래스 | 설명 |
|---|---|
ArcaconSearchResult |
검색 결과 (패키지 목록 + 페이지네이션) |
ArcaconPackageSummary |
패키지 요약 (검색 결과 항목) |
ArcaconPackageDetail |
패키지 상세 (스티커 목록 + 태그 포함) |
ArcaconSticker |
개별 스티커 정보 (ImageUrl, 비디오용 VideoUrl, PosterThumbnailUrl) |
ArcaconSubscribedPackage |
구독(보유) 아카콘 패키지 정보 |
ArcaconSearchSort |
정렬 방식 (Hot, New) |
ArcaconSearchType |
검색 유형 (Title, NickName, Tags) |
- .NET 10.0 이상 (Windows 10.0.26100.0 이상)
- Windows 전용 (WebView2 의존성)
- AngleSharp — HTML 파싱
- Microsoft.Web.WebView2 — 로그인 처리
- System.Net.Http.WinHttpHandler — HTTP 통신
MIT License
이호원
이 프로젝트는 GitHub Copilot의 도움을 받아 작성되었습니다.
