Skip to content

96 写个小程序来追剧

Jinxin Chen edited this page Dec 11, 2019 · 1 revision

今天已经周三,楚乔传的资源居然还没有更新。

不过每次都要打开网站,然后搜索,着实有点繁琐,要是有什么办法能够让资源更新了自动得到通知就好了。

作为一个优秀的程序猿,必须得用代码来解决问题啊,写个.NET Core程序来帮我盯着~

解决方案分析

登录

chd站的登录只需要输入正确的用户名和密码即可,不需要输入验证码,这就简单了,不需要再研究验证码识别程序。

下面是chd站点的登录表单

搜索及结果页面研究

登录之后,接下来研究搜索结果页面结构。

打开chd页面,然后搜索“楚乔传”,发现搜索结果地址如下:

https://chdbits.co/torrents.php?search=[keyword]&notnewword=1

查看结果列表结构,发现每一条记录都用 class="torrentname" 的 table 展示,并且按照资源新旧顺序排列,名称被包含在b的标签中:

基本上解决思路就已经明朗了:

  1. 登录,拿到cookie
  2. 访问搜索结果页面,分析数据
  3. 每隔一段时间对比一次最新记录是否有变化,如果有则通知

建立项目

建立一个简单的console程序,然后用vs code打开即可:

mkdir Supperxin.EpisodeMonitor
cd Supperxin.EpisodeMonitor
dotnet new console
dotnet resotre
code .

建立程序主体框架

static void Main(string[] args)
{
    var baseUrl = "https://chdbits.co";
    var loginUrl = "/takelogin.php";
    var username = "";
    var password = "";
    var resultQueryUrl = "/torrents.php?search=楚乔传&notnewword=1";
    var duration = 30 * 60 * 1000;


    var cookieContainer = LoginAndGetCookie(baseUrl, loginUrl, username, password);
    var originEpisode = string.Empty;
    while(true)
    {
        var html = GetLastestEpisodesHtml(baseUrl, resultQueryUrl, cookieContainer);
        var latestEpisode = AnalyzeHtmlToGetLatestEpisode(html);

        if(originEpisode != latestEpisode)
        {
            NotifyMe(latestEpisode);
            originEpisode = latestEpisode;
        }
        else
        {
            Console.Write(".");
        }

        Thread.Sleep(duration);
    }
}

登录获取cookie

private static CookieContainer LoginAndGetCookie(string baseUrl, string loginUrl, string username, string password)
{
    var baseAddress = new Uri(baseUrl);
    var cookieContainer = new CookieContainer();
    using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
    using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
    {
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("username", username),
            new KeyValuePair<string, string>("password", password),
        });
        var result = client.PostAsync(loginUrl, content).Result;
        result.EnsureSuccessStatusCode();
    }

    return cookieContainer;
}

获取搜索结果页面内容

private static string GetSearchResultHtml(string baseUrl, string resultQueryUrl, CookieContainer cookieContainer)
{
    var html = string.Empty;

    using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
    using (var client = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) })
    {
        var result = client.GetAsync(resultQueryUrl).Result;
        html = result.Content.ReadAsStringAsync().Result;
        result.EnsureSuccessStatusCode();
    }

    return html;
}

解析html

分析html之后,得到抓取最新一集标题的方法:

private static string AnalyzeHtmlToGetLatestEpisode(string html)
{
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);

    var input = doc.DocumentNode.SelectNodes("//table")
        .Where(n => n.Attributes.Contains("class") && n.Attributes["class"].Value == "torrentname")
        .First();

    var latestEpisode = Regex.Match(input.InnerHtml, @"<b>(?<tag>.+)</b>").Result("$1");

    return latestEpisode;
}

先简单的输出一下吧:

private static void NotifyMe(string episode)
{
    Console.WriteLine("\n\n");
    Console.WriteLine("==============================");
    Console.WriteLine("New episode : " + episode);
    Console.WriteLine("==============================");
}

现在新的发布,就会输出:

==============================
New episode : Princess Agents 2017 E29-E30 WEB-DL 1080p H264 AAC-CHDWEB
==============================

本程序的代码已经放到 Github:

https://github.com/xiaoxin01/Supperxin.EpisodeMonitor

Clone this wiki locally