Development

Twitter ユーザーの誕生日を取得

Twitter では誕生日を設定できます。誕生日を設定すると、広告のターゲティングに活用されるとのこと。誕生日は「年」と「月日」ごとに公開範囲を設定でき、誕生日当日のユーザーのプロフィールページには、風船が飛ぶ機能があります。

誕生日の取得

さて、誕生日は Twitter API で取得できないため、スクレイピングするしかありません。誕生日を全体に公開しているユーザーであれば、サインインすることなく(Twitter の利用規約に従うことなく)誕生日を取得できます。

HTML

スクレイピングのため、Twitter の出力する HTML に大きく依存しますが、2015/10/19 時点では、次のような HTML です。

twitter.html
    <div class="ProfileHeaderCard-birthdate ">
      <span class="Icon Icon--balloon Icon--medium"></span>
      <span class="ProfileHeaderCard-birthdateText u-dir" dir="ltr"><span class="js-tooltip" title="公開">    誕生日 January 11
</span>
</span>

C# & HtmlAgilityPack でスクレイピング

C# とスクレイピングに便利かもしれない HtmlAgilityPack で取得してみます。HtmlAgilityPack は NuGet でインストールします。

スクリーンネームから誕生日部分のテキストを取得するメソッドはこんな感じ。@class=""ProfileHeaderCard-birthdateText u-dir"" のように class 属性の部分は完全一致しないと取得できないんですね。

TwitterSample.cs
static public async Task<string> GetBathDate(string screenName)
{
    // ユーザープロフィールページの HTML 取得
    string html;
    using (var client = new WebClient() { Encoding = Encoding.UTF8 })
    {
        html = await client.DownloadStringTaskAsync("https://twitter.com/" + screenName);
    }

    // <span class="ProfileHeaderCard-birthdateText u-dir" dir="ltr"> 直下の <span> のテキスト値取得
    var doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(html);
    var spans = doc.DocumentNode.SelectNodes(@"//span[@class=""ProfileHeaderCard-birthdateText u-dir""]/span");
    return spans?.First().InnerText;
}

メソッドの呼び出しはこんな感じです。

Program.cs
static void Main(string[] args)
{
    var birthDate = GetBathDate("5zj").Result?.Trim();
    Console.WriteLine(birthDate);

    // birthDate の例:
    //   "誕生日 1990年7月7日"
    //   "誕生日 July 07"
    //   "誕生日 1990"
    // 英語の場合:
    //   "Born on July 7, 1990"
    //   "Born on July 07"

    // DateTime 型に変換
    DateTime d;
    if (DateTime.TryParse(birthDate.Replace("誕生日", "").Trim(), out d))
    {
        Console.WriteLine(d);
    }
}

以上です。