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

スクレイピングするのに調べたことまとめておく

CasperJS PhantomJS Selenium javascript

はじめに

最近スクレイピングするスクリプトを書く機会があったので次回のためにメモしておく。

・主にHTMLでコンテンツが作られているページ。
Javascriptでページを生成しているページ。
この2パターンに対応する必要があった。後者に対応しておけば前者もカバーできるのでいいかな。

で、調べるとPhantomJS、Seleniumあたりがたくさん出てきた。
ブラウザを操作してページを取得してくるようなイメージ。

・PhantomJS
npmでインストールできるのでセットアップが簡単。
PHP PhantomJSというライブラリもあってPHPからも使える。ページへ遷移してHTMLを取得してくるような簡単な処理ならすぐ実装できる。
ただ、サイトにログインとかして何かやるようにちょっと複雑なことをする場合はJavascriptで処理を書いてPHPからそのコマンドを叩くような処理になるのかなと思った。
しかもちょっと難しく感じた。。。

Selenium
自分の理解不足もあるが、セットアップがちょっと面倒だった。
今回やりたかったことはPhantomJSでほぼできたのであまり使わなかった。

・CasperJS
内部的にはPhantomJSを使ってるみたいだけどより簡単に色々できるみたい。
PhantomJS難しくかんじたけどCasperJSの方が簡単にいじれる印象でやりたいこともできた。

実装の方針

取得したHTMLやHTMLの解析結果はDBへ保存する必要があった。
PhantomJSやCasperJSからDBへ登録できるかできないはわからないけど、それはせず。

1. PHPで取得したいURLのリストをファイルへ出力。
2. PantomJSやCasperJSでそのURLリストファイルを読み込んでサイトにアクセスして取得したHTMLをファイルへ出力。
3. PHPで2.の結果ファイルを読み込んでsimple_html_domで解析してDBへ保存

simple_html_domは読み込みサイズの上限があるので解除しておいた方がよさそう。

例)サイズは適当

define('MAX_FILE_SIZE', 600000*10);

結論

PHPとCasperJS使うのが1番簡単そう。やりたいこともできた。以上です。

【CasperJS】ログインする方法メモ

CasperJS PhantomJS javascript

今回やりたかったのはログインが必要なページの取得。
単純にformをsubmitすればいいページとログインボタンをクリックするとjavascriptが動いてごにょごにょやってログイン処理へと遷移するパターンがあるのでそれぞれ実装してみたのでメモしておく。

formをsubmitするパターン

ログイン画面

<form action="/login/do" method="post">
  Email:<input type="text" name="email" id="email" />
  Password:<input type="text" name="password" id="password" />
  <input type="submit" value="Login" />
</form>

スクリプト

var casper = require("casper").create();

casper.start();
casper.open("http://example.com/login/");

casper.then(function() {
  this.fill('form[action="/login/do"', {
    document.querySelector("#email").value = "user@example.com";
    document.querySelector("#password").value = "1234567890";
  }, true);
});

casper.then(function() {
  // ログイン後にやりたい処理を記述
});

casper.run();
onclickするパターン

ログイン画面

<form>
  Email:<input type="text" name="email" id="email" />
  Password:<input type="text" name="password" id="password" />
  <button onclick="onLogin" id="btn-login">Login</button>
</form>
<script>
function onLogin() {
  // ログイン処理・・・
}
</script>

スクリプト

var casper = require("casper").create();

casper.start();
casper.open("http://example.com/login/");

casper.then(function() {
  this.evaluate(function() {
    document.querySelector("#email").value = "user@example.com";
    document.querySelector("#password").value = "1234567890";
    document.querySelector("#btn-login").click()
  }, true);
});

casper.then(function() {
  // ログイン後にやりたい処理を記述
});

casper.run();

以上です

【CasperJS】eachThenとthenOpenで順次スクレイピングしてファイル出力する

CasperJS PhantomJS javascript

今回やりたかったのはURLをリスト化しておいて順次サイトにアクセスしてレスポンスを取得するということ。当初はopenとthenを複数書いていたけどURLの一覧を別ファイル化したかったので今回やりたい経緯となった。ついでに取得したHTMLをファイルに保存する形にした。 

var casper = require('casper').create();
var fs = require("fs");

var urls = [
    {id:1, url:"http://example.com"},
    {id:2, url:"http://example2.com"},
    {id:3, url:"http://example3.com"},
];

casper.start();
casper.eachThen(urls, function(response) {
    var id = response.data.id;
    this.thenOpen(response.data.url, function(response) {
        this.wait(3000, function() {
            fs.write("/path/to/" + id + ".html", casper.getHTML());                                                                                                                                                
        });
    });
});

casper.run();

以上です

macでキャプチャを動画で撮れるLICEcap

よく使うのになぜか名前覚えられないのでメモっておく。
LICEcap

すごいシンプルでとても便利。
macて書いたけど、windowsもあるのか。
動画って書いたけどアニメーションGif。

以上です。

【bootstrap】モーダルが画面からはみ出ないようにサイズ調整する

bootstrap jquery
はじめに

bootstrapのモーダル使っててモーダルサイズが画面からはみ出るのが嫌だったので修正したときのメモ。
今回やったのは以下の2パターン
・テキストベースのモーダル
・画像を大きく表示するための画像ベースのモーダル

テキストベースのモーダル

修正前
f:id:yoppy0066:20170317004307g:plain

修正後
f:id:yoppy0066:20170317004400g:plain

修正後のHTML

<script>
function showModal() {
  $(".modal-content").css({
    "height": $(window).height() - 75,
    "overflow-y": "auto"
  });
  $("#myModal").modal("show");
}
</script>

・・・

<div class="modal fade" id="myModal">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-body">                                                                                                                                                                                     
        テキスト                                                                                                                                                                                                   
        テキスト                                                                                                                                                                                                   
        テキスト                                                                                                                                                                                                   
        ・・・                                                                                                                                                                                                     
      </div>                                                                                                                                                                                                       
    </div>                                                                                                                                                                                                         
  </div>                                                                                                                                                                                                           
</div>
画像ベースのモーダル

修正前
f:id:yoppy0066:20170317004435g:plain

修正後
f:id:yoppy0066:20170317004502g:plain

修正後のHTML

<script>
 function showModal() {
     var height = $(window).height() - 150;
     $("#image").css("max-height", height);
     $("#myModal").modal("show");
 }
</script>                                                                                                                                                                                                          

<div class="modal fade" id="myModal">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-body">
        <img id="image" class="img-responsive" style="margin:0 auto;" src="./sample.png"/>
      </div>
    </div>
  </div>
</div>

無理やりだけどcssでやりかたわからなかったのでjqueryで。
もっと簡単なやり方教えてください。以上です。

【php】Lineアカウントでのログインを実装する

php

はじめに

FacebookとかTwitterアカウントでのログインは何回かやったことあったけどLineは初めてだった気がしたのでメモしておく。
といっても、ちょっとしたアカウント情報取得するのはやり方どれも同じような感じですけど。

http://milk0824.hatenadiary.jp/entry/2016/04/08/021052
手順はここにわかりやすくまとまっていた。↑にあるように管理画面からLineアプリ作って、クライアントIDとシークレットキーを取得しておく。

実装

define.php

define("LINE_CLIENT_ID", "クライアントID");
define("LINE_CLIENT_SECRET", "シークレットキー");

line_login.php

$callback_url = "https://".$_SERVER["SERVER_NAME"]."/line_callback.php";

$url = sprintf(
    "https://access.line.me/dialog/oauth/weblogin"
    ."?response_type=code"
    ."&client_id=%s"
    ."&redirect_uri=%s"
    ,LINE_CLIENT_ID
    ,$callback_url
);

header("Location: {$url}");
exit;

これでLine側のページが表示されて、IDとパスワードを入力する。

line_callback.php

if (!$_GET["code")) {
    // エラー                                                                                                                                                                                                      
}

// アクセストークン取得
$url = "https://api.line.me/v1/oauth/accessToken";

$data = array(
    "grant_type" => "authorization_code",
    "client_id" => LINE_CLIENT_ID,
    "client_secret" => LINE_CLIENT_SECRET,
    "code" => $_GET["code"],
    "redirect_uri" => "",
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($ch);
curl_close($ch);
$result = (array)json_decode($response, true);

if (empty($result) || isset($result["error"])) {
    // エラー
}

print_r($result);
/*
Array
(
    [mid] => xxxxxxxxxxxxxxxxxxxxxxxxx
    [access_token] => xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    [token_type] => Bearer
    [expires_in] => 2568710
    [refresh_token] => xxxxxxxxxxxxxxxxxxxx
    [scope] =>
)
 */

// プロフィール情報を取得                                                                                                                                                                                          
$url = "https://api.line.me/v2/profile";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.line.me/v2/profile");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $result["access_token"]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);

$result = (array)json_decode($response, true);
if (empty($result) || empty($result["userId"])) {
    // エラー
}

print_r($result);
/*
Array
(
    [userId] => xxxxxxxxxxxxxxxx
    [displayName] => ユーザー名
    [pictureUrl] => ユーザー画像のURL
)
 */

あとは、取得した情報からシステム側でログインの制御とかすれば良さそう。以上です。

sslの開発環境を作る手順

ssl linux apache

はじめに

SSL環境での動作確認を行うための環境を作る手順をまとめておく。
これをたまにやろうとするたびに検索してオレオレ証明書作って。。。とかやってたけどなんかもともと入ってるみたいで。

いちおう今回の環境は、centos6.8でapache2.2

実装

mod_sslインストール

$ yum -y install mod_ssl

ssl.confの編集

以下の箇所をhttpd.confとかバーチャルホストごとの設定ファイルにごそっと移動したいので削除してどこかにコピペしておく。

# ここを追加
NameVirtualHost *:443

# ここから削除
<VirtualHost _default_:443>
〜
</VirtualHost>                                                                                                                                                                                                     
# ここまで削除                                                                                                                                                                                                     

httpd.confまたはバーチャルホストの設定が記述してあるファイルの編集
基本的に上で削除した部分をはりつける。

<VirtualHost *:443>                                                                                                                                                                                                
                                                                                                                                                                                                                   
  # ★ここは環境とかによって変える                                                                                                                                                                                 
  DocumentRoot "/var/www/html/example.com"                                                                                                                                                                         
  ServerName example.com:443                                                                                                                                                                                       
                                                                                                                                                                                                                   
  CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/example.com/ssl_access_log.%Y%m%d 86400 540" custom                                                                                                              
  ErrorLog "|/usr/sbin/rotatelogs /var/log/httpd/example.com/ssl_error_log.%Y%m%d 86400 540"                                                                                                                       
  LogLevel warn                                                                                                                                                                                                    
                                                                                                                                                                                                                   
  # 以下はssl.confのものをそのまま持ってきた                                                                                                                                                                       
  SSLEngine on                                                                                                                                                                                                     
  SSLProtocol all -SSLv2                                                                                                                                                                                           
  SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES                                                                                                                                                        
                                                                                                                                                                                                                   
  SSLCertificateFile /etc/pki/tls/certs/localhost.crt                                                                                                                                                              
  SSLCertificateKeyFile /etc/pki/tls/private/localhost.key                                                                                                                                                         
                                                                                                                                                                                                                   
  <Files ~ "\.(cgi|shtml|phtml|php3?)$">                                                                                                                                                                           
    SSLOptions +StdEnvVars                                                                                                                                                                                         
  </Files>                                                                                                                                                                                                         
  <Directory "/var/www/cgi-bin">                                                                                                                                                                                   
    SSLOptions +StdEnvVars                                                                                                                                                                                         
  </Directory>                                                                                                                                                                                                     
                                                                                                                                                                                                                   
  SetEnvIf User-Agent ".*MSIE.*" \                                                                                                                                                                                 
  nokeepalive ssl-unclean-shutdown \                                                                                                                                                                               
  downgrade-1.0 force-response-1.0                                                                                                                                                                                 
                                                                                                                                                                                                                   
  CustomLog logs/ssl_request_log \                                                                                                                                                                                 
  "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"                                                                                                                                                                
                                                                                                                                                                                                                   
</VirtualHost>

この中で、以下は最初から用意されているので自分で作る手順がいらなかった。
/etc/pki/tls/certs/localhost.crt
/etc/pki/tls/private/localhost.key

で、apache再起動すればokでした。以上です