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

bz0のにっき

quick and dirty prototype

2017/04/24

個人開発

昨日はコード書いてない。。。

「いますぐ実践! Linux システム管理」のメルマガのバックナンバーを
読んでやってみていた。(No.13~15)



http://www.usupi.org/sysad/013.html

tcp_wrapperとは
 ・TCP または UDP の接続を,監視・制限するためのもの
 ・inetd経由で起動されるデーモンが対象だったが
  sshdsendmailなどinetdに依存せずに動作するデーモンへも対応
 ・パケットフィルタリング(iptables)との違い
  ・ドメイン名を用いた柔軟な設定を行える
  ・アクセスがあったときに様々なアクションを起こすことができる
  ・多層防御という点でも有効

  ・ tcp_wrapper は,プログラム(tcpd あるいは自分自身)がアクセス制限などを行う
  ・ パケットフィルタリングは,OS の TCP/IP スタックの中で行われる

・/etc/hosts.allow と /etc/hosts.deny
http://www.astec-x.com/FAQ/hosts_deny.html

・メルマガには書いてなかったですが、xinetdを修正したら再起動しないと
 修正が反映されなかった。

/etc/init.d/xinetd restart

telnetはポート23番
http://www.infraexpert.com/study/tea5.htm

・/etc/xinetd.d/telnetを設定
loggerでtelnetでアクセスされたときに/var/log/messagesへログ出力

2017/04/22

個人開発

個人開発で、Twitter APIからデータ収集してDBに入れるPGMが
どんどん汚くなってきたので、きれいに書き直す為にDIについてや命名について
見直しながらリファクタしていた。現時点で、まだ終わってない。。。

DIとは
http://blog.a-way-out.net/blog/2015/08/31/your-dependency-injection-is-wrong-as-I-expected/
http://tototoshi.hatenablog.com/entry/2015/12/03/232343

あるオブジェクト(=サービス)を別のオブジェクト(=クライアント)に渡すパターンがDIパターンです。

pimple DIコンテナを簡単に使えるライブラリ
http://pimple.sensiolabs.org/


クラス名の命名規則 - あのね、Util なの? Utils じゃないの?
http://d.hatena.ne.jp/moriyoshi/20070311/1173675288

Ethna の作者である藤本さんは「あるモデルを複数格納するジェネリックなコンテナ」には
複数形を用いず、「List」を接尾にするのが習慣

データベースオブジェクトの命名規約
http://qiita.com/genzouw/items/35022fa96c120e67c637

2017/04/21

仕事

自分の技術力のなさから、運用でカバーしなきゃいけない事が増えている。

今できることで、取り敢えず対処してしまうことによって短期的には
会社の利益になるかもしれないけれど長期的にみると、運用でカバーする時間が増えていく為に
新規開発や機能追加に回せる時間が減ってしまい、開発スピードがどんどん鈍化していく。

負のスパイラルを自分で生み出してしまっているという実感があり
設計時に、ベストな方法は何かを模索することを早く作らないといけないという
プレッシャーに負けて、さぼっちゃいけないなと痛感しています。

個人開発

Twitterのいいねランキング開発

 TwitterAPIを利用して、ホームタイムラインを1時間ごとに取得してDBに格納するPGMを書きました。
 Twitter API hometimeline ホームタイムライン 自分の「つぶやき」一覧 表示 取得 php oauth接続 | TRYPHP!

 下記データに分けてDBに格納してます。

 ・ホームタイムラインのツイート(リツイート含む)
 ・元ツイート(元ツイートのみ)
 ・ユーザ情報
 ・ハッシュタグ

MySQL 5.1→5.6へアップデート

 4バイト文字を格納するために、utf8mb4で入れたかったのでアップデートしました。
 5.1だとutf8mb4が使えないようだった為。
 MySQL5.1から5.7にバージョンアップさせるための手順 - Qiita

 5.7にしたかったのですが、間違えて一度データをふっとばしてしまった為
 5.6でとりあえずは目的果たせるのでよいかと。

webスクレイピング対策への対処について

サイト管理者が立てるであろうスクレイピング対策

サイト管理者の目線で、行うであろうスクレイピング対策から
スクレイピングする側で、どう対処すべきか考えてみます。

スクレイピング対策しているという事は、マジで迷惑だから辞めろやという事だと思うので
 スクレイピングするなという話ではありますが。。。)

考え方

結論

機械的なアクセスをしない。人間的なアクセスに近づける。

参考

悪質なボットによるアクセスの見分け方
http://markezine.jp/article/detail/9834


・ アクセスしてくるURLのパターンからボットを見分ける

・同じIPアドレスからのアクセスの間隔が常にほぼ同じ秒数間隔
 ・同じIPアドレスから、同じユーザーエージェントで大量にアクセスが行われているか
 ・ 人間らしくないきっちりしすぎるアクセス

・ アクセス元のIPアドレスを集計している
・ 何度もアクセスしてきているのに、セッションクッキーを絶対に送ってこない
リファラーがまったくない
・ HTMLだけにアクセスしてJavaScriptCSS、画像にまったくアクセスしていない
 ・ ブラウザも設定次第でクッキーやリファラー、画像、JavaScriptなどを切ることができるので
   決めつけるのは早計ですが、そのほかの行動パターンと組み合わせるときの証拠の1つにはなる

参考)
検索ロボットの見分け方[Apache 生ログ]
http://ecsiter.com/bot

最近のスクレイピング対策

アンチスクレイピングサービス

普及して欲しくないアンチスクレイピングサービス
http://happyou-info.hatenablog.com/entry/2014/12/04/005504

・HTML構造を頻繁に変える

やはり普及してはならないアンチスクレイピングサービス
http://happyou-info.hatenablog.com/entry/2016/12/22/002439

・BotDefender
  ・競合他社との価格競争を防ぐ為に、自社サイトの価格表示を
    スクレイピングさせない仕組み

   ・一部情報だけ、別サーバに切り出してJSからAPI経由で取得?(想像です)
   ・HTMLに重要な情報を残さない

  ・CSSでわざと非表示にすることで、スクレイピングしたデータに偽情報を仕込む
  ・ 自社のウェブサイトをヒューマンリーダブルだけどマシンリーダブルにはしない。
   一般のユーザさんには影響がない程度の毒を自社サイトに混ぜることでコピーされるのを防ぐ
   機械お断りというオープンデータとは真逆の流れが生まれてくる

ブラウザの自動化

くだらないAPIなんていらないよ – 2016年のウェブスクレイピング事情
くだらないAPIなんていらないよ – 2016年のウェブスクレイピング事情 | プログラミング | POSTD

・ブラウザの自動化(selenium等)によるスクレイピング
 一番信頼できる。。。

しかし、賢く作り込まれた今どきのサイトを相手にして、インターネットから
データを掘り当てるための信頼できる方法はといえば、ブラウザの自動化だけなのですよねえ。
最近のサイトは、スクレイピングやデータマイニングの試みを阻止するのがうまくなってきました。
AngelListはPhantomJSすら検出してしまいます(今のところ、他のサイトでそこまでの例は見ていません)。
でも、ブラウザ経由での正確なアクションを自動化できたとしたら、サイト側はそれをブロックできるでしょうか?

スクレイピング対策への対処として考えられる方法

アクセスする側の情報を偽装

アクセスする側の情報として、下記がスクレイピングするサイトに渡されます。
これを偽装することで、単純なスクレイピング対策に対処できます。

・アクセスする側の情報

 ・IP / ドメイン
 ・リクエストヘッダ
  ・ユーザエージェント
  ・リファラ
  ・クッキー
  ・ホスト
 等

ユーザエージェントを偽装する

単純ですが、ユーザエージェントを偽装する(ブラウザにする)ことで
ブラウザであると偽装します

リクエストヘッダを偽装する

ブラウザで問題なくアクセスできる場合に、ブラウザでアクセスしたときの
リクエストヘッダを利用して、偽装します。

chromeであれば、デベロッパツールの「ネットワーク」から
リクエストヘッダを取得することが可能です。

クッキー / セッションを取得して利用

・有名なサイトであれば、ブラウザでのアクセスでレスポンスが重くなったけど
 クッキー消したら早くなった等の情報が落ちているかも。

 その場合、サイト内でクッキー / セッションによる処理が走っていて
 有効なクッキー以外はbotとして判定され、処理待ちさせている可能性がある。

・クッキーを継続的にアクセスするときに持たせる

 PHPであれば、guzzleを用いてスクレイピング時のクッキーの取り回しを楽にするとよさそう
 PHP: Guzzle 6 で Cookie を扱う - Sarabande.jp
 [PHP]HTTPクライアントGuzzle6でレスポンスで返されたCookieを取得する | 遊び場

アクセスが人間的か

機械にしかできない動きをしていないか

・同じIPアドレスから、同じユーザーエージェントで大量にアクセスが行われているか
・ 人間らしくないきっちりしすぎるアクセス

・ アクセス元のIPアドレスを集計している
 ・ 何度もアクセスしてきているのに、セッションクッキーを絶対に送ってこない
 ・ リファラーがまったくない

JavascriptCSSが読み込まれない為に重くなるようにしている?

JavascriptCSSスクレイピングで取得できないので、それがbotの判定条件になっている?

ヘッドレスブラウザでのスクレイピングを試してみる。
http://tech.quartetcom.co.jp/2016/04/07/php-phantomjs/


IP制限がかかっている?

普段スクレイピングしないサーバでスクレイピングしてみる

ネットワークの遅延

サイトのスクレイピング対策への対処ではありませんが、
ネットワーク上で遅延が起きている可能性もあるかも?

-bash-4.1# traceroute search.rakuten.co.jp

tracerouteで経路上で時間がかかっているところがないかチェックする。

スクレイピングしようとしているページがそんなにデータ量がなければ
tracerouteでわかるレスポンス時間から、明らかに時間がかかってないかについて
推測できると思います。

習慣化しようとしているタスク

最近考えている、習慣化しようとしているタスクについて書いてみる。


ポモドーロテクニック
 http://gihyo.jp/dev/serial/01/continue-power/0004?page=1

 ・タスクを全て書き出す
 ・時間を区切って作業に取り組む
 ・作業単位ごとに5分休憩をとる(頭をリラックスさせることで気づくこともある)

 ・最も重要なことに集中する
  ・重要なタスクは何かを明確にする



・知識を増やす
 http://language-and-engineering.hatenablog.jp/entry/20110411/p1

 3つのインプット:

  • (1)健康と体力を意識し続ける。
  • (2)仕事術を実践し続ける。
  • (3)技術を収集し続ける。

 ・毎日この3つのインプットを継続する
 ・1日30分インプット時間に充てる
  ・帰りにカフェに寄る
 ・本を読んで、情報をマインドマップにまとめる
  手書きでOK。
  http://d.hatena.ne.jp/higepon/20080811/1218456629
 ・復習の習慣づけ



・自分の個人開発プロジェクトを進捗させる
 ・なぜやるのかを明確にする
 ・習慣化する
  http://careerhack.en-japan.com/report/detail/152

 ・仕事上の課題を個人学習で解決する
  ・よくわからないところが出てきたらストックしておく
  ・個人開発プロジェクトを進める気持ちが湧かないときはそちらを
   考えてみるようにする



・体力をつける
 どちらかをやる

 ・筋トレ(時間ないとき・外に出る気が起きないとき)
  サーキットトレーニング7分
  https://www.youtube.com/watch?v=56pAZSu6mww
  上半身サーキットトレーニング6分
  https://www.youtube.com/watch?v=po0x8fEas_w

 ・ジョギング 30分(余裕があるとき)



・週報を書く
 自己学習の振り返り
 http://cross-black777.hatenablog.com/entry/2016/07/16/090000

UI設計をするときにやること

自分のメモなので偏りあるし、抜け漏れも多そう。やっていく中で継ぎ足していきたい。

目的とゴールの明確化を行う

  • そのサービスを作ることでどんな問題が解決できるのか?
  • そのサービスを作る前と後でどう変わるか?(Before / After)
  • ゴールはどこか?
  • サービスがユーザに貢献できているかどうかの評価の指標を決める

画面遷移

  • 変えられない部分はあるか?
    • 前提として、どこから呼び出される等制限はあるか?
  • 処理の視点から考える
    • 入力されるデータと出力されるデータは何か?
    • どのようなステップを踏む必要があるか?
  • 簡単に画面の流れを紙に書いてみる

画面構成

  • 表示する要素は何か、リスト化してみる
  • xmindで要素を階層構造にしてみる
  • 要素の階層構造を、h1~落とし込む

UIモックを書く

配置

リード文

対象ユーザはどんな人か?

なぜ把握しておく必要があるか
どこまで説明すべきか?を明確にする為

リテラシー高い人?低い人?

[どうする?]
低い人なら、汎用的なIT用語も噛み砕いて説明する必要がある

専門分野のキーワードを利用する場合、分かるか?

[どうする?]

  • わからないなら、補足説明をつける必要がある
  • 専門分野のキーワードをなるべく使わない

ツール独自のワードはないか?

何の事前情報もなしに伝わるキーワードか?
ツールの文言をキーワード単位に切り取って確認する。

伝わらないなーっと思ったら、別のワードで伝わらないか考えてみる。

ルフレビュー

UIモックを画面ごとに印刷して、何も知らない人を装って
そのサービスを使ってみる(紙で)

文字列のHTMLからタグ名を全て抽出

文字列のHTMLからタグ名を全て抽出するJavascriptです。
再帰関数を利用しているので階層が深くなってもすべて取得することが出来ます。

再帰関数とは
再帰関数を学んでワンランク上のJavaScriptエンジニアになろう! - Qiita

・$.parseHTML 文字列をHTML要素に変換します
jQuery リファレンス:jQuery.parseXML

var taglist = {
  tags: [],
  h: function(html){
    Object.keys(html).forEach(function (key) {
      if (html[key].tagName){
        taglist.tags.push(html[key].tagName);
	if (html[key].childNodes.length>0){
            taglist.h(html[key].childNodes);
        }
      }
    });
  }
};
var str = "<div>aa<b>aaa</b>aa</div><table><thead><tr><td>aaaa<td><td>bbbb<td></tr></thead><tbody><tr><td>cccc</td><td>ddddd</td></tr></tbody></table>";
var html = $.parseHTML(str);
taglist.h(html);
console.log(taglist.tags);

「taglist.tags」に配列でタグ名が入ります。

Array[13]
0:"DIV"
1:"B"
2:"TABLE"
3:"THEAD"
4:"TR"
5:"TD"
6:"TD"
7:"TD"
8:"TD"
9:"TBODY"
10:"TR"
11:"TD"
12:"TD"