search
LoginSignup
3
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Wikipediaのアニメ情報をパース

目的

Wikipediaのアニメ記事中の「アニメタイトル」、「監督」、「脚本」、「音楽」、「アニメーション制作」の情報を取得する。

コード

Wikipedia.ts
getWikiInfo関数の引数に記事タイトルを入れる。
記事タイトルは「TypeScriptでWikipedia APIから情報取得」で取得する。
JSONの中身はWiki記法の文字列なので、正規表現で目的の情報を取得する。(タグの削除、<br>タグによるリスト化も行っている)
Underscore.jsのおかげで配列、オブジェクトを便利に扱うことができた。

Wikipedia.ts
namespace utils.Wikipedia {
    const ENDPOINT = 'https://ja.wikipedia.org/w/api.php?'
    const SEARCH_BASE_URL = ENDPOINT + 'action=query&list=search&format=json&srsearch='

    export function getWikiInfo(title: string, success: (info: WikiInfo) => void, fail?: (jqXhr: JQueryXHR) => void) {
        var url = INFO_BASE_URL + encodeURIComponent(title)
        var xhr = $.ajax({
            url: url,
            type: 'GET',
            dataType: 'jsonp',
            jsonpCallback: 'callback'
        })
        xhr.then((json: ContentResponseJson) => {
            var pages = json.query.pages
            var page: PageJson = _.first(_.values(pages))
            var revision = _.first(page.revisions)
            var content = revision['*']
            var tvAnimeInfobox = getTvAnimeInfoboxText(content)
            success({
                pageTitle: page.title,
                title: split(getValue(tvAnimeInfobox, 'タイトル')),
                director: split(getValue(tvAnimeInfobox, '監督')),
                writer: split(getValue(tvAnimeInfobox, '脚本')),
                music: split(getValue(tvAnimeInfobox, '音楽')),
                studio: split(getValue(tvAnimeInfobox, 'アニメーション制作'))
            })
        }, fail)
    }

    function getTvAnimeInfoboxText(input: string): string {
        var regex = /\{\{Infobox animanga\/TVAnime([\s\S]+?)\}\}/
        return regex.exec(input)[1]
    }

    function getValue(text: string, key: string): string {
        var regex = new RegExp('^\\| *' + key + ' *= *(.+?)$', 'm')
        var execArray = regex.exec(text)
        if (_.isEmpty(execArray)) {
            return ''
        } else {
            return removeSquareBracket(execArray[1])
        }
    }

    function removeSquareBracket(input: string) {
        return input.replace(/\[|\]/g, '')
    }

    function removeHtmlTag(input: string) {
        return input.replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g, '')
    }

    function split(input: string): Array<string> {
        var splitted = input.split(/<br ?\/?>/)
        var tagRemoved = _.map(splitted, (value) => {
            return removeHtmlTag(value)
        })
        return _.compact(tagRemoved)
    }

    interface ContentResponseJson {
        query: {
            pages: Object
        }
    }

    interface PageJson {
        pageId: number,
        title: string,
        revisions: Array<{
            '*': string
        }>
    }

    export interface WikiInfo {
        pageTitle: string,
        title: Array<string>,
        director: Array<string>,
        writer: Array<string>,
        music: Array<string>,
        studio: Array<string>
    }
}

サイトに反映

アニメ情報サーバーにアクセスするWebサイトで作成したAnime Info ClientにWikipedia情報を取得するページを追加した。
Wikipedia情報.PNG

Github

AnimeInfoClient

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3
Help us understand the problem. What are the problem?