プログラミング」カテゴリーアーカイブ

Node.jsで指定したWebページをダウンロードする

Node.jsを使って簡単にWebページをダウンロードしてみます。

getpage.js

// requireモジュール取り込み
var http = require('https'); // HTTPモジュール
var fs = require('fs'); // ファイル関連モジュール

// 保存先指定
var savepath = "download.html";
// 出力先指定
var outfile = fs.createWriteStream(savepath);
// 引数の受け取り
var url = process.argv[2];

if(url === undefined){
	console.log("引数がありません:",url);
	return;
}

// 非同期でURLからファイルダウンロード
http.get(url, function(res){
	res.pipe(outfile);
	res.on('end', function(){
		outfile.close();
		console.log("complete");
	});
});

こんな感じで、引数にURLを渡して実行すると渡したURLからダウンロードを実行してくれます。

$ node getpage.js https://yoda56.com
complete

とりあえずWebスクレイピング前の基本として

–自分用の処理順メモ–
Node.jsは非同期で実行するので、処理完了を待ちません。
なので、この場合だとhttp.get(url)のリクエストを出して処理を戻します。
処理が終わるとコールバック関数のfunction(res)が呼ばれます。
res.pipe(outfile)で保存するように指示を出します、ここでまた処理を戻します。
処理が終わるとres.on(‘end’, function()の部分が呼ばれ処理が完了する。

【広告】

npm ERR! EPROTO: protocol error, symlink ‘../semver/bin/semver’ -> ‘hogehoge/node_modules/.bin/semver’

vagrant環境でnpm installかけたらハマりました。

事象について

npm install --save-dev cheerio-httpcli
--------------略--------------
├── @types/cheerio@0.17.31  extraneous
├── @types/node@6.0.63  extraneous
├── async@2.1.4  extraneous
├── cheerio@0.22.0  extraneous
├── constants@0.0.2  extraneous
├── foreach@2.0.5  extraneous
├── he@1.1.1  extraneous
├── iconv-lite@0.4.15  extraneous
├── jschardet@1.4.1  extraneous
├── object-assign@4.1.1  extraneous
├── os-locale@1.4.0  extraneous
├── prettyjson@1.2.1  extraneous
├── request@2.79.0  extraneous
├── require-uncached@1.0.3  extraneous
├── rsvp@3.3.3  extraneous
├── spawn-sync@1.0.15  extraneous
├── type-of@2.0.1  extraneous
└── valid-url@1.0.9  extraneous

npm WARN 02_downloadweb@1.0.0 No description
npm WARN 02_downloadweb@1.0.0 No repository field.
npm ERR! Linux 3.10.0-229.14.1.el7.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "--save-dev" "cheerio-httpcli"
npm ERR! node v6.9.4
npm ERR! npm  v3.10.10
npm ERR! path ../semver/bin/semver
npm ERR! code EPROTO
npm ERR! errno -71
npm ERR! syscall symlink

npm ERR! EPROTO: protocol error, symlink '../semver/bin/semver' -> '/hogehoge/node_modules/.bin/semver'
npm ERR! 
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /hogehoge/npm-debug.log

結論

vagrantで共有を張っているフォルダに対してnpm installをかけるときは「–no-bin-links」オプションをつけましょう。

–no-bin-linksとは

名前の通り、シンボリックリンクを作成しないことを指示するコマンド

どういうことか

npm installをかけるとフックして依存パッケージに含まれるbin module packageをインストールしてpathを通そうとする。
vagrantは共有ファイルに対し、シンボリックリンクを張ることを禁止している..っぽい

意外とそこらへんの仕様の絡みがよく分かっておらず、結構苦労しました。
みなさんも気を付けましょう

参考

https://github.com/npm/npm/issues/5874
【npm】【Vagrant】Vagrantの共有フォルダ上でnpm installすると失敗する原因と、–no-bin-linksオプションをつけると成功する理由

【広告】

VagrantのCentOS7.1にNode.jsをインストール

Node.jsとは

もともとはWebサーバなどのネットワークプログラムを記述するために開発されたJavaScript実行環境
通常利用するWebブラウザーに搭載されているJavaScriptは、セキュリティに配慮されているので、処理の制限がされているが、Node.jsはわりと何でもできちゃう
すごーい!

インストール

vagrantで作成したCentOS7.1環境にてインストールを実施
そこまで難しくもない

$ sudo yum install nodejs --enablerepo=epel

このインストールの仕方だと若干古いバージョンになるが、まぁ動かせればいいのでよしとする。

$ node -v
v6.9.4
$ npm -v
3.10.10

とりあえずインストール完了

$ node
> 1+1
2
>
> .exit

こんな感じで実行できます。

バージョン確認で試したnpmはNode.jsのモジュール管理をするパッケージマネージャです。
Node.js用に作られたツールをインストールすることもできます。

位置情報を送信したら近辺の麺屋の情報を返すLINE BOTを作った

こんにちは、表題のとおりです。

実はLINEBOTを作ってみたらやってみようと思っていたのですが、やはり先駆者がたくさんおられました笑

なので二番煎じなのをご了承ください。
よかったら使ってみてください。

近くの麺屋検索

QRコード

友達追加

友だち追加

概要と使い方

友達追加後に「+」ボタンから位置情報を送信するだけです。
送信後に情報があれば最大5件まで表示します。
情報をぐるなびAPIから取得しています、なのでぐるなびに掲載されていない店舗は出力されません。
URLをGoogleAPIにて短縮してあります。
いじくるので時々使えなくなるかもしれません。

使ったもの

・PHP
・Heroku
・ぐるなびAPI
・Google API

割と苦労した点

デバッグ、出すためにわざわざerror_log関数を仕込んでHerokuにpushして試してました。
多分もっといいやり方があった気がする。

今後の対応

位置情報から近い順にソートして出力させます。

参考にしたサイト

【LINE BOT API】位置情報を送ると近くのラーメン屋さんを教えてくれるBOTを作ってみました
誰でも簡単にできる! LINE Botの作り方

みなさん使ってみてください。

ではでは

This API does not support parsing form-encoded inputになった話

なんか小1時間ぐらい悩んでしまった。

結論

GoogleのAPIから送信する時は「Content-Type: application/json; charset=UTF-8」を付けましょう。

事象

PHPでCURLを使ってGoogleのURL短縮のAPIへのリクエストをしていたのですが、以下のようなエラー

{
  "error": {
    "errors": [
     {
      "domain": "global",
      "reason": "parseError",
      "message": "This API does not support parsing form-encoded input.
     }
   ],
   "code": 400,
   "message": "This API does not support parsing form-encoded input.
  }
}

で、その時にリクエストしていたCURLのロジックはこちら

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $uri);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 証明書の検証を行わない
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postData));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
$response = curl_exec($curl);

なので↓を足したらちゃんと通りました

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $uri);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 証明書の検証を行わない
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postData));
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=UTF-8')); //←☆これ
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
$response = curl_exec($curl);

ちゃんとjsonということを明示しないと怒られてしまうそうです。
(デフォルトだとapplication/x-www-form-urlencodedで送信されているそう)

GoogleのAPIを使うときは気を付けましょう。