具体的には、(Discover Meteor book を調べて作成した非常にシンプルなアプリを使用して)Hacker News から投稿をスクレイピングし、それらを Meteor Collection に挿入して、「New Posts」ページを更新して 20 ほどの新しい記事をスクレイピングしようとしています。ハッカーニュースのトップページ。
Meteor.call イベントに接続されたヘッダーにボタンがあります。
Template.header.events({
'click .hnPull': function() {
Meteor.call('getHnArticles');
}
});
これにより、getHnArticles という名前の Meteor.methods 関数が (正常に) 呼び出されます。
getHnArticles: function() {
hn_result = Meteor.http.get('http://news.ycombinator.com');
console.log(hn_result);
$ = cheerio.load(hn_result.content);
var result_set = [];
$('span.comhead').each(function(i, element){ //for ever <span class='comhead'>, do the following
var a = $(this).prev();
var rank = a.parent().parent().text();
var title = a.text();
var url = a.attr('href');
var subtext = a.parent().parent().next().children('.subtext').children();
var points = $(subtext).eq(0).text();
var username = $(subtext).eq(1).text();
var comments = $(subtext).eq(2).text();
//parsed metadata object
var metadata = {
rank: parseInt(rank),
title: title,
url: url,
points: parseInt(points),
username: username,
comments: parseInt(comments)
};
result_set.push(metadata);
});
console.log(result_set);
for (var i = 0; i<20; i++) {
var hn_post = result_set[i];
var postAttributes = {
url: hn_post.url,
title: hn_post.title,
message: 'Scraped automatically from Hacker News'
};
var user = Meteor.user(),
postWithSameLink = Posts.findOne({url: postAttributes.url});
// ensure the user is logged in
if (!user)
throw new Meteor.Error(401, "You need to login to post new stories");
// Make sure the post has a title. it can't be blank
if (!postAttributes.title)
throw new Meteor.Error(422, 'Please fill in a headline');
// Make sure this isn't a duplicate post or repost
if (postAttributes.url && postWithSameLink) {
throw new Meteor.Error(302,
'This link has already been posted',
postWithSameLink._id);
}
// pick out the whitelisted keys
// This keeps a nefarious client from monkeying around with our db
var post = _.extend(_.pick(postAttributes, 'url', 'title', 'message'), {
userId: user._id,
author: user.username,
submitted: new Date().getTime(),
commentsCount: 0,
upvoters: [],
votes: 0
});
Posts.insert(post);
}
},
その結果、Hacker News のトップ ランクの投稿が見事に挿入されました。しかし、それから他のどれも。
result_set という配列を console.log に送信すると、フロント ページが出力されます。
I202504-11:50:57.551(-5)? [ { rank: 1,
I202504-11:50:57.551(-5)? title: 'Is iOS7 jailbroken yet?',
I202504-11:50:57.551(-5)? url: 'https://isios7jailbrokenyet.com/',
I202504-11:50:57.551(-5)? points: 37,
I202504-11:50:57.552(-5)? username: 'sethbannon',
I202504-11:50:57.552(-5)? comments: 12 },
I202504-11:50:57.552(-5)? { rank: 2,
I202504-11:50:57.552(-5)? title: 'Valve joins the Linux Foundation',
I202504-11:50:57.552(-5)? url: 'http://thenextweb.com/insider/2013/12/04/valve-joins- linux-foundation-prepares-linux-powered-steam-os-steam-machines/',
I202504-11:50:57.553(-5)? points: 276,
I202504-11:50:57.553(-5)? username: 'kwestro',
I202504-11:50:57.554(-5)? comments: 117 },
I202504-11:50:57.554(-5)? { rank: 3,
I202504-11:50:57.555(-5)? title: 'Google Acquires Seven Robot Companies, Wants Big Role in Robotics',
I202504-11:50:57.555(-5)? url: 'http://spectrum.ieee.org/automaton/robotics/industrial-robots/google-acquisition-seven- robotics-companies#.Up9CGN-hd98.hackernews',
I202504-11:50:57.555(-5)? points: 71,
I202504-11:50:57.555(-5)? username: 'eguizzo',
I202504-11:50:57.555(-5)? comments: 29 },
I202504-11:50:57.556(-5)? { rank: 4,
I202504-11:50:57.556(-5)? title: 'Evading Airport Security',
I202504-11:50:57.556(-5)? url: 'https://www.schneier.com/blog/archives/2013/12/evading_airport.html',
I202504-11:50:57.556(-5)? points: 87,
等々。素敵な大きな配列を取得します。
ここで何がうまくいかないのですか?Meteor Collections のコードがループするため、レコードの挿入が速すぎますか? それとも、Mongo の挿入の問題ですか?
ありがとう!私は Meteor を初めて使いましたが、気に入っています。しかし、私はまだ Meteor 内で非同期ノードを使用することに頭を悩ませています。
編集:MongoDBインスタンスにクエリを実行すると、トップリンクのみが挿入されていることを追加するのを忘れました。