fc2ブログ

Heliumを使う

 ブラウザの自動操作ツールのSeleniumのラッパーでHeliumというものがあり、大変便利だという情報がありましたので、早速使ってみました。SeleniumとHelium、双方、原子名で合わせていますね。Seleniumは原子番号34で元素記号はSe、Heliumは原子番号2で元素記号はHeです(どうでもいい話ですが・・)。

 何はともあれ、日経電子版の個人のページにログインして「Myニュース」の最新記事のタイトルをcsvファイルに保存するコードを書いてみました。
from helium import *
import bs4
import re
import csv
import time

# Helium
url = 'https://www.nikkei.com/'
driver = start_chrome(url)

click('ログイン')
write('my mail address', into='メールアドレス')
write('my password', into='パスワード')
click('ログイン')
click('Myニュース')

time.sleep(10) # time wait

# Beautiful soup4
html = driver.page_source
soup = bs4.BeautifulSoup(html, "lxml")

# Items search
item = soup.find_all('h3')

# Delete Tags
for i in range(0, len(item)):
item_temp = re.sub(r'<h3.*>\n', '', str(item[i]), 1)
item_temp = re.sub(r'<a href.*">', '', item_temp, 1)
item_temp = re.sub(r'</a>\n</h3>', '', item_temp, 1)
item[i] = re.sub(r'\u3000', ' ', item_temp, 1)
print(item[i])

# Results output
with open("items.csv", 'w') as f:
writer = csv.writer(f, delimiter='\n')
writer.writerow(item)

time.sleep(5) # time wait

kill_browser()
 9行目で8行目のURLに接続します。Helium1_210613.pngこのページの「ログイン」を11行目でクリックします。コードも直感的で分かりやすいです。あえて「ログインボタン」のオブジェクト名やIDを探しに行かなくて良いのは非常に楽です。ログインボタンを押すと、ログイン画面が出てきますので、Helium2_210613.png12、13行目でメールアドレスとパスワードを入力(write)して「ログイン」ボタンを押すと(click)、個人ページが表示されるので、Helium3_210613.pngその中の「Myニュース」ボタンを押します(click)。Helium4_210613.png Myニュースが表示されるまで時間がかかるので、10秒程度待ちを入れました。

 Heliumでは記事の中身もある程度抽出できるようですが、不慣れで時間がかかりそうだったので、定番のBeautiful Soupでこのページ情報を取得し、目的部分を抽出しました。コードの20行目以降です。27〜32行目はタグを除き、必要な部分の文字列を抽出しています。最後にcsvファイル出力し、ブラウザを閉じます。結果のcsvファイルは以下の通りです。Helium5_210613.png問題なく目的の記事タイトルを抽出できました。

Seleniumに比べ、直感的にブラウザの操作のコードを書くことができ、非常に分かりやすいと思いました。また、Webスクレイピングする時に利用してみようと思います。
スポンサーサイト



Rustを触る(1)

 最近、ネット記事を読んでいて何となく気になっていたのがプログラミング言語の「Rust(ラスト)」です。Rust自身は「さび」という意味で「わび・さび」の「さび」ではなく、鉄錆の「さび」です。名前はともかく、Wikipediaさんによると、

『Rust(ラスト)は、性能、メモリ安全性、安全な並行性を目指して設計されたマルチパラダイムのプログラミング言語である。C言語、C++に代わるシステムプログラミング言語を目指しており、構文的にはC++に似ているが、「ボローチェッカー」(borrow checker) で参照の有効性を検証することによってメモリ安全性を保証できる。Rustはガベージコレクションなしでのメモリ安全性を達成しており、必要な場面で参照カウントを使うこともできる。』

ということらしいですが、用語の定義が良く分からないので、知っている内容も含め、復習も兼ねて再度チェック!

メモリ安全性
 バッファオーバーフローやダングリングポインタなど、メモリアクセスに対処する際のさまざまなソフトウェアバグやセキュリティの脆弱性から保護されている状態のこと。

バッファオーバーフロー
 データをバッファに書き込み中に、バッファの境界をオーバーランしたり、隣接メモリ位置に上書きするプログラムの異常のこと。

ダングリングポインタ(dangling pointer)
 無効なメモリ領域を指すポインタのことで、とりわけ、本来有効だったメモリ領域が解放処理などによって無効化されたにもかかわらず、そのメモリ領域を参照し続けているポインタのこと。

マルチパラダイムのプログラミング言語
 プログラミングパラダイムとは、プログラムの見方や模範(概念)を与えるもので、構造化プログラミング、命令型プログラミング、オブジェクト指向プログラミング、関数型プログラミング、ジェネリックプログラミングなどがある。マルチパラダイムプログラミング言語は複数のパラダイムに対応したもの。

ボローチェッカー(borrow checker)
  一つのリソースは一つの所有者(変数やブロック)のみに関連付けされるというRust特有の制約を管理する機能。

ガベージコレクション
 コンピュータプログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能。

参照カウント
 メモリオブジェクトのライフサイクル(寿命)管理に使用される方式のひとつ。ガベージコレクションの実装方法およびガベージコレクタの動作方法のひとつとしても利用される。

メモリ管理・利用に関する部分が強化、効率化された言語という認識で良いのでしょうか??
個人的には画像処理をやっていたので、C++で書く場合はメモリ確保してから解放するまで気を使いましたね。C#で書く時はガベージコレクション任せで何とかなっていた感もあります。

結局、いまいち「Rust」というプログラミング言語がピンと来なかったので、実際に環境を作って触ってみることにしました。またまたいつもの思い付きで興味の赴くまま進んでいます。

 セットアップするパソコンはMac mini (M1-chip), macOS Big Sur 11.2.3です。
セットアップの流れはホームページにある以下のコマンドを入力するだけでOKです。VScodeのターミナルから実行しました。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
途中で以下の選択をする必要がありますが、defaultを選びました。
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1
すぐにセットアップが完了しましたので、早速定番のHello Worldをrustcでコンパイルして実行しました。Rust_hello_world_210606.pngまた、cargoというプロジェクトのビルドツールおよびパッケージマネージャでも実行することができます。
 まず、hello_cargoというパッケージを作成しました。
cargo new hello_cargo --bin
Rust_cargo1_210606.pngVScodeで編集するとデフォルトでgitの管理下になるようですね。ソースコード(main.rs)を編集し、Rust_cargo2_210606.pngビルドすると
cargo build
Rust_cargo3_210606.pngdebugフォルダに実行ファイルが作成されるので、それを実行させると
cargo run
Rust_cargo4_210606.png正常に動作しました。操作自体はMacやUbuntuで「.NET Core」のプログラムを実行しているような感じです。

Rustのオンラインマニュアルにある「数当てゲームのプログラミング」も流れに沿ってやってみました。プログラムはマニュアルそのままですが、こんな感じです。
use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main(){
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1..101);
//println!("The secret number is: {}", secret_number);

loop{
println!("Please input your guess.");

let mut guess = String::new();

io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");

let guess: u32 = match guess.trim().parse(){
Ok(num) => num,
Err(_) => continue,
};

println!("You guessed: {}", guess);

match guess.cmp(&secret_number){
Ordering::Less => println!("Too Small!"),
Ordering::Greater => println!("Too Big!"),
Ordering::Equal => {
println!("You Win!");
break;
}
}
}
}
実行結果は以下の通りです。Rust_cargo5_210606.png
 まだまだ、Rustの本丸を攻めて行けていませんが、今回はまず導入して触れた所までです。時間を見つけて続きをやっていこうと思います。

あわや危機一髪!

 最近、車運が悪いのか、車で帰宅している時にトラブルに遭遇します。疲れているのかな??

 先日、雨の日に街灯のない周囲が暗い田舎のコンビニに車で右折して入る際に、両前輪が縁石に乗り上げてしまいました。一瞬何が起こったのか分からない状態でした。なぜ縁石を乗り上げてしまったのか・・、数秒間思考停止しました。
 幸い、勢いよくバックすることで両前輪も縁石を越えることができ、元の状態に戻り、事なきを得ました。車も大丈夫でした。

 ところが今日はあわや車と衝突しかけました。法定速度で直進中に左側から急に左折する車があり、衝突する直前で急ブレーキを踏みました。相手の脇見運転ですね。車が止まる直前はスローモーションでした。幸い、衝突せずに車も無傷でしたが、心のダメージは大きかったですね。ぐったりです。ドライブレコーダの映像はこんな感じです。また、ドライブレコーダが記録している速度と加速度は以下の通りです。Dangerous210602.png急激に減速したことが分かると思います。

 5月中旬ごろから体調を崩しており、自律神経のバランスも悪いです。睡眠も質が悪そう・・。土日もゆっくり休めていないのもあるのかな?愚痴る前に早く寝ないといけませんね。何はともあれ、大きな事故にならなくて良かったと思いました。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: