2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

nodejsで最新ニュースをmongoDBに保存する他

Last updated at Posted at 2014-05-10

論理構成とかなしただただメモですが読んで分かると思います。
データをテンプレートに投げれば、ニュースアプリとか作れます。

テンプレ

parseXML = require("xml2js").parseString
util = require "util"
http = require "http"
URL = require "URIjs"
mongoose = require "mongoose"
settings = require "./settings"
appId = 'XXXXXXXXXXXXXXXX'
log = (a) ->
	if arguments.length isnt 1
		return console.log arguments
	console.log util.inspect a,
		showHidden: false
		depth: 2
		color: true
	return a
  • xml2js:XMLをjsonに変える。超重要。
  • util:ログとれる、階層レベルを変えて目当てのデータを見つけるためにlog関数。
  • mongoose:データ保存、スキーマで必要なデータだけ取る。
  • settings:ホストとかポートとかの設定情報
  • appId: ヤフーのAPI使うための認証鍵。
  • URL:urlをjsonっぽく投げて作れる。url作るだけです。

yahooAPI

これを使ってみる。ほかに日本語解析とか、緯度経度で場所探しとかあるけど使い方は一緒。
リクエストパラメータに必要な情報を上ページから探してそれをもとにurlとクエリとデータの中身の表示を書く。

news =
	uri: 'http://news.yahooapis.jp/NewsWebService/V2/topics'
	data: # 後でクエリに使う
		appid: appId
		category: 'domestic'
		sort: 'pvindex'
		results: 10
	res: (data) -> data.ResultSet.Result

URL生成。使い方はnpmで調べてみて。

urler = new URL news.uri
urler.search news.data

通信します。



http.get urler.toString(), (res) ->
	body = ''
	res.setEncoding 'utf-8'
	res.on 'data', (chunk) ->
		body += chunk

	res.on 'end', (res) ->
		parseXML body,
			trim: true
			explicitArray: false
		, (err, data) ->
			if err then throw err
			log news.res data
.on 'error', (e) ->
	log e.message


APIってっこうやって使うんですかね。
これくらいならクライアントサイドだけで直接投げて済みそうですね。
一応APIの使い方でした。いろんなAPIで遊べますよ!

さて月5000回しか使えないらしいからDB保存しよう。log関数の代わりにデータベースに投げる、dbSave関数を作ります。

mongoose = require "mongoose"

mySchema = new mongoose.Schema
	NewsUpdateTime: String
	Keyword: String
	TopicName: String
	English: String
	Overview: String
	Category: String
	SubCategory: String
	Url: String
	PickupCategory: String
	PickupOrder: String
	PvIndex: String
	NewsNum: String
	NewsUrl: String
	SmartphoneUrl: String
mongoose.model 'yahoonews', mySchema
dbName = "yahoonews"

dbSave = (datas)  ->
	mongoose.connect "mongodb://" + settings.host + "/" + dbName
	News = mongoose.model "yahoonews"
	datas.forEach (data) ->
		news = new News data
		news.save()

databaseNameとコレクションネームが一緒でややこしい、ごめん
無事に保存できました。

しかし、、、
ここまで読んでくれて難だけど、10件しかとれないし、ニュースのURLはいってないし、なんだこのAPI?! ってなるんです。
なのに制限とか^^;

ニュースでもいいですけど、こんどは為替情報を保存してみようかな。さて

やってることは控えめなのに、げすいタイトルのページがあったのでまねてみます。yahooファイナンスさんのページからスクレイピングしてみます。アクセスは重いので練習しにくかったです。


# マーケットの最新情報を得るスクレイピング
jsdom = require "jsdom"
jsdom.env 'http://finance.yahoo.co.jp', ["http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"], (err, window) ->	window.$('.yjfinMarquee:first em').each () ->
		console.log window.$(this).children('a, strong').text()

スクレイピング自体はjqueryだけでconsole上でできます。
今回はサーバーにてhtmlをgetしてDOMに変えて、jqueryでさがしたら簡単になるわけなんですが。npmで検索した結果がこれ。

  • jsdom: htmlをDOMに変えてくれる
    途中でjqueryを読みこむオプションがあって便利!
    以上、上のqiitaページのnodejsばーじょんでした。

しかし得られる情報がしょぼい!

いまどきのRSSで制限もよわいのにめっちゃ情報のってますやん。XMLぱーさー使ってるんだったら最初からRSSでいいやん!

# RSSから最新のマーケット情報を得る。
urler = new URL 'http://jpy.jp.fx-exchange.com/rss.xml'

http.get urler.toString(), (res) ->
	body = ''
	res.setEncoding 'utf-8'
	res.on 'data', (chunk) ->
		body += chunk

	res.on 'end', (res) ->
		parseXML body,
			trim: true
			explicitArray: false
		, (err, data) ->
			if err then throw err
			log data.rss.channel.item

うわ、とれたわ。
わんちゃんマーケットアプリ作ってひと儲けできるんかな。

以上、API探しの旅の記録でした。

2
3
0

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
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?