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

DevelopmentC#, Twitter

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

誕生日の取得

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

HTML

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

view raw
twitter.html
hosted with ❤ by GitHub

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

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

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

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;
}

view raw
TwitterSample.cs
hosted with ❤ by GitHub

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

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);
}
}

view raw
Program.cs
hosted with ❤ by GitHub

以上です。