diff --git a/Emby.Plugins.JavScraper/Scrapers/FC2Video.cs b/Emby.Plugins.JavScraper/Scrapers/FC2Video.cs new file mode 100644 index 0000000..8fa41cd --- /dev/null +++ b/Emby.Plugins.JavScraper/Scrapers/FC2Video.cs @@ -0,0 +1,182 @@ +using Emby.Plugins.JavScraper.Http; +using HtmlAgilityPack; +#if __JELLYFIN__ +using Microsoft.Extensions.Logging; +#else +using MediaBrowser.Model.Logging; +#endif +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Emby.Plugins.JavScraper.Scrapers +{ + /// + /// https://adult.contents.fc2.com/article/2535523/ + /// + public class FC2Video : AbstractScraper + { + /// + /// 适配器名称 + /// + public override string Name => nameof(FC2Video); + + private static readonly Regex RegexDate = new Regex(@"(?[\d]{4}[-/][\d]{2}[-/][\d]{2})", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private static readonly Regex RegexFC2 = new Regex(@"FC2-*(PPV|)-(?[\d]{2,10})($|[^\d])", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static readonly Regex RegexFC2Video = new Regex(@"article/(?[\d]{2,10})($|[^\d])", RegexOptions.IgnoreCase | RegexOptions.Compiled); + + /// + /// 构造 + /// + /// + public FC2Video( +#if __JELLYFIN__ + ILoggerFactory logManager +#else + ILogManager logManager +#endif + ) + : base("https://adult.contents.fc2.com/", logManager.CreateLogger()) + { + } + + /// + /// 检查关键字是否符合 + /// + /// + /// + public override bool CheckKey(string key) + => JavIdRecognizer.FC2(key) != null; + + public override Task> Query(string key) + { + var match = RegexFC2.Match(key); + if (match.Success) + { + return DoQyery(new List(), match.Groups["id"].Value); + } + + match = RegexFC2Video.Match(key); + if (match.Success) + { + return DoQyery(new List(), match.Groups["id"].Value); + } + + return Task.FromResult(new List()); + } + + /// + /// 获取列表 + /// + /// 关键字 + /// + protected override async Task> DoQyery(List ls, string key) + { + var item = await GetById(key); + if (item != null) + { + ls.Add(new JavVideoIndex() + { + Cover = item.Cover, + Date = item.Date, + Num = item.Num, + Provider = item.Provider, + Title = item.Title, + Url = item.Url + }); + } + + return ls; + } + + /// + /// 无效方法 + /// + /// + /// + /// + protected override List ParseIndex(List ls, HtmlDocument doc) + { + throw new NotImplementedException(); + } + + /// + /// 获取详情 + /// + /// 地址 + /// + public override async Task Get(string url) + { + var match = RegexFC2.Match(url); + if (match.Success) + { + return await GetById(match.Groups["id"].Value); + } + + match = RegexFC2Video.Match(url); + if (match.Success) + { + return await GetById(match.Groups["id"].Value); + } + + return null; + } + + /// + /// 获取详情 + /// + /// 地址 + /// + private async Task GetById(string id) + { + //https://adult.contents.fc2.com/article/1252526/ + var url = $"/article/{id}/"; + var doc = await GetHtmlDocumentAsync(url); + if (doc == null) + { + return null; + } + + string title = doc.DocumentNode.SelectSingleNode("//meta[@name='twitter:title']").GetAttributeValue("content", null); + string cover = doc.DocumentNode.SelectSingleNode("//meta[@property='og:image']")?.GetAttributeValue("content", null); + string releaseDate = doc.DocumentNode.SelectSingleNode("//div[@class='items_article_Releasedate']")?.InnerText ?? string.Empty; + var match = RegexDate.Match(releaseDate); + if (match.Success) + { + releaseDate = match.Groups["date"].Value.Replace('/', '-'); + } + else + { + releaseDate = null; + } + + string seller = doc.DocumentNode.SelectSingleNode("//section[@class='items_comment_sellerBox']//h4")?.InnerText; + List genres = doc.DocumentNode.SelectNodes("//a[@class='tag tagTag']").Select(genre => genre.InnerText).ToList(); + List samples = doc.DocumentNode.SelectNodes("//section[@class='items_article_SampleImages']//a") + .Select(sample => sample.GetAttributeValue("href", null)) + .Where(sample => string.IsNullOrWhiteSpace(sample)) + .ToList(); + + var javVideo = new JavVideo() + { + Provider = Name, + Url = url, + Title = title, + Cover = cover, + Num = $"FC2-{id}", + Date = releaseDate, + Maker = seller, + Studio = seller, + Set = "FC2", + Genres = genres, + Samples = samples, + }; + + return javVideo; + } + } +} \ No newline at end of file