読者です 読者をやめる 読者になる 読者になる

自己顕示欲の開放治療所

erg, programming and something.

別名:Laughing and Grief 雑記

Latin and Greekは習ったこともない

真面目な記事の他、特定の方には不快と思われる事柄に関して言及を行うことがあります。ちょっと頑張りますが、Blog内で解決できなかった場合要望があれば別ページに技術記事は書き直します

げっちゅな屋でスクレイピング

なに

まだとりあえずタイトルが引っぱれるだけですが。golangでscrapeライブラリを使っています。

先達がコチラhttp://akb428.hatenablog.com/?page=1437903964

追記(2016-11-10)

year、monthを引数にとってその年月の発売作品のタイトルを並べます。引数なしの場合、現在の月の発売作品を並べます。 respをCloseするようにしたのと、ブランド、発売日を表示するようにしました。

utf-8に変換してます Go言語で文字コード変換 - Qiita

code

package main

import (
    "flag"
    "fmt"
    "net/http"
    "strings"
    "time"

    "io/ioutil"
    "net/http/cookiejar"
    "net/url"

    "github.com/yhat/scrape"
    "golang.org/x/net/html"
    "golang.org/x/net/html/atom"
    "golang.org/x/text/encoding/japanese"
    "golang.org/x/text/transform"
)

const (
    stdLongYear = "2006"
    stdNumMonth = "1"
)

var (
    year  string
    month string
)

func eucjpToUtf8(str string) (string, error) {
    ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewDecoder()))
    if err != nil {
        return "", err
    }
    return string(ret), err
}

func main() {
    t := time.Now()

    flag.StringVar(&year, "year", t.Format(stdLongYear), "sell year")
    flag.StringVar(&month, "month", t.Format(stdNumMonth), "sell month")

    flag.Parse()

    getchuUrl := "http://www.getchu.com/all/price.html?genre=pc_soft&gage=adult"
    jar, _ := cookiejar.New(nil)
    var cookies []*http.Cookie
    cookie := &http.Cookie{
        Name:   "getchu_adalt_flag",
        Value:  "getchu.com",
        Path:   "/",
        Domain: "www.getchu.com",
    }
    cookies = append(cookies, cookie)
    u, _ := url.Parse(getchuUrl)
    jar.SetCookies(u, cookies)
    client := &http.Client{
        Jar: jar,
    }

    postData := strings.NewReader("&year=" + year + "&month=" + month)
    req, _ := http.NewRequest("POST", getchuUrl, postData)
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    resp, err := client.Do(req)

    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    root, err := html.Parse(resp.Body)
    if err != nil {
        panic(err)
    }

    matcherGame := func(n *html.Node) bool {
        if n.DataAtom == atom.A && n.Parent != nil && n.Parent.Parent != nil {
            return scrape.Attr(n.Parent, "align") == "left"
        }
        return false
    }

    matcherSellday := func(n *html.Node) bool {
        if n.DataAtom == atom.Td {
            return scrape.Attr(n, "class") == "black" && scrape.Attr(n, "align") == "center"
        }
        return false
    }

    matcherBrand := func(n *html.Node) bool {
        if n.DataAtom == atom.Td {
            return scrape.Attr(n, "class") == "black" && scrape.Attr(n, "align") == "left"
        }
        return false
    }

    games := scrape.FindAll(root, matcherGame)
    selldays := scrape.FindAll(root, matcherSellday)
    brands := scrape.FindAll(root, matcherBrand)

    selldayList := make(map[int]string)
    for i, sellday := range selldays {
        selldayList[i] = scrape.Text(sellday)
    }

    brandList := make(map[int]string)
    for i, brand := range brands {
        brandList[i], err = eucjpToUtf8(scrape.Text(brand))
        if err != nil {
            panic(err)
        }
    }

    for i, game := range games {
        //    sellday, err := eucjpToUtf8(scrape.Text(sellday))
        game, err := eucjpToUtf8(scrape.Text(game))
        if err != nil {
            panic(err)
        }

        fmt.Printf("%s: %s| %s\n", selldayList[i], game, brandList[i])
    }

}