atelier:mitsuba

i love UI/UX, Blend, XAML, Behavior, P5, oF, Web, Tangible Bits and Physical computing. なにかあればお気軽にご連絡ください。atelier@c-mitsuba.com

Nancyでganrefをスクレイピングして、おねーさまを眺めれるようにしてみた。

とりあえず、快適におねーさまがたのポートレートを見れるようにしてみた。
元のURLはこんなかんじ。
http://ganref.jp/photo_searches/result/page:1/sort:created/direction:desc?keyword=&parent_category=%E4%BA%BA%E7%89%A9&category=%E5%A5%B3%E6%80%A7

書いたコードはこんなかんじ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using Nancy.Helpers;
using Sgml;

namespace Antoinette
{
    public class GanrefModule : Nancy.NancyModule
    {
        public GanrefModule()
        {
            Get["/ganref/lady/"] = _ => "<script> window.location.href='./1'; </script>";

            Get["/ganref/lady/{page}"] = _ =>
            {
                var url =
                    string.Format("http://ganref.jp/photo_searches/result/page:{0}/sort:created/direction:desc?keyword=&parent_category=%E4%BA%BA%E7%89%A9&category=%E5%A5%B3%E6%80%A7",
                    HttpUtility.UrlDecode(_.page)
                );

                XDocument xml;
                using (var sgml = new SgmlReader() { Href = url, IgnoreDtd = true })
                {
                    xml = XDocument.Load(sgml);
                }

                var ns = xml.Root.Name.Namespace;
                var imgroot = xml.Descendants(ns + "div").Where(div => div.FirstAttribute.Value == "thumb140");
                var imgUrls = imgroot.Select(xElement => xElement.Descendants(ns + "a").Descendants(ns + "img").Skip(2).First().FirstAttribute.Value).ToList();

                return imgUrls.Aggregate("", (current, imgUrl) => current + ("<img src='" + imgUrl + "'/>"));
            };
        }
    }
}

ちょっと解説。

Get["/ganref/lady/"] = _ => "<script> window.location.href='./1'; </script>";

なしでもよいのだけど、なしの場合は自動で1ページ目が入る。0をいれても1ページ目のデータが降ってくる。
なので、とりあえず/1に遷移してる。
こういうのはNancy側では書けないのかなぁ?

            Get["/ganref/lady/{page}"] = _ =>
            {
                var url =
                    string.Format("http://ganref.jp/photo_searches/result/page:{0}/sort:created/direction:desc?keyword=&parent_category=%E4%BA%BA%E7%89%A9&category=%E5%A5%B3%E6%80%A7",
                    HttpUtility.UrlDecode(_.page)
                );

                XDocument xml;
                using (var sgml = new SgmlReader() { Href = url, IgnoreDtd = true })
                {
                    xml = XDocument.Load(sgml);
                }

                var ns = xml.Root.Name.Namespace;
                var imgroot = xml.Descendants(ns + "div").Where(div => div.FirstAttribute.Value == "thumb140");
                var imgUrls = imgroot.Select(xElement => xElement.Descendants(ns + "a").Descendants(ns + "img").Skip(2).First().FirstAttribute.Value).ToList();

                return imgUrls.Aggregate("", (current, imgUrl) => current + ("<img src='" + imgUrl + "'/>"));
            };

典型的なスクレイピング
のいえさんのブログを参考にしました。
http://neue.cc/2010/03/02_244.html

短い気がするけど、けっこー試行錯誤した><
linqxmlのところはもう少し綺麗に書ける気もするなぁ、、、

出来上がったものがこちら
http://antoinette.azurewebsites.net/ganref/lady/