fc2ブログ

東京、鎌倉、横浜を散策する

 平成も残り10分足らずです。TVの番組やニュースでは年越しさながらのカウントダウンが行われており、少し冷めた気分で興醒めしています。時代の移り変わりで「自分自身も新しく生まれ変わるんだ」「いいことがあるんだ」と世の中が浮かれている?ことに私自身は賛否はないですね・・。時代が変わろうが、変わるまいが、要は「自分の日々の気の持ちよう」だと思いますし、日々の生活も1日で大きくは変わりませんからね。

 とはいえ、10連休の真っ只中ですね。気持ちは変わらなくても、長い休暇で生活のリズムが変わっています・・。
 私自身、インドアの趣味を持っていますが、家にじっとしているのも耐えられない性分です。私の奥さんも今回の10連休に対して、機嫌があまりよろしくありません。そこで、1泊2日で東京方面へ旅行に連れ出しました。日々の家事の慰労を兼ねて、気分転換をしてもらうのが目的です。

 1日目は東京駅で別れて個別に行動し、夕方に落ち合って食事を取り、ホテルで就寝。2日目は東京から足を伸ばして鎌倉に一緒に行きました。その後、鎌倉で別れて個別行動し、再度横浜で落ち合いました。山下公園や中華街をぶらぶらして、夕食後に帰途につきました。

 今回、二人の子供に留守番をしてもらい、初めて夫婦だけで旅行をしました。旅行をしていてよく分かったのですが、お互いに干渉しない時間(個別行動の時間)も必要ということ。一緒にいると、些細なことでもめてしまうんです・・。一人行動なら文句を言う人がそばにいないので、じっと黙っているしかない・・。それが続くと精神衛生上良くないかもしれないので、バランスが重要です(これが難しい・・)。

 長い長い?いつもの前置きはこれぐらいにして、短い?本題に移ります。

 今回の旅のベスト3は以下の通りです。
 第三位は「鎌倉」。観光客の多さに閉口しましたが(私もその一人・・)、鶴岡八幡宮と鎌倉大仏の定番は抑えました。Tsurugaoka-shrine_190429.pngkamakura-daibutsu1_190429.png大仏は内部(胎内)にも入れるんですね。不思議な気持ちでしたが、つなぎ目から大仏の製法が良く分かりました。また、螺髪(らほつ)部分も内部から拝見するとへぇーこうなっているのか、なるほどです。kamakura-daibutsu2_190419.jpg 第二位は「原鉄道模型博物館」。横浜駅から徒歩5分の横浜三井ビルディング2Fにある原信太郎氏の製作した鉄道模型等を展示している博物館です。まず、驚いたのが、何と言っても「作品のクオリティが高い!」こと。国内外から様々な資料を集めて、良く研究されており、精巧に作られていました。小学六年生の頃から、海苔やお茶の缶を使って模型を作り始めたとのこと。その当時の模型もありましたが素晴らしいものでした。架線に電気を流し、パンタグラフで取り入れて模型電車を走らせると言う、趣味の領域を超越して、技術+芸術を感じた展示でした。
 第一位は「チームラボ」。初めて見ましたが、すごくよかったですね。欧米系の外国の方も多かったです。非現実的な映像なのですが、世界に引き込まれ、体から魂が抜け出て天国に登っていく様な感じを受けました。精神浄化でき、日頃の疲れも吹っ飛びました。TeamLab_190428.png 1泊2日の短い旅行でしたが、密度が濃く、良く歩きました(2日で27km歩いていた・・)。奥さん共々、気分転換になりました。GWの後半は私だけまたもや別行動で実家に帰ります・・。年寄りの話し相手になるためです。
スポンサーサイト



MacにArduino実行環境を作る(1)

 しばらく電子工作から離れていました。この3月、4月と公私ともに超多忙な日々を送っています。そのような日々から逃避するために「電子工作」の久々の復活です。
 かれこれ2年近くのブランクです・・。過去のblogを振り返ると、Wi-FiモジュールのESP8266やPICを使って何か複雑なことをしていました。単品のESP8266でもある程度のことができたのですが、いろいろ試行錯誤した形跡?があります・・。
 2年前と変わったことは、メインの作業PCが「Windows」から「Mac、Linux(Ubuntu)」になったことです。Windows PCは会社で使うのみで、自宅では精神衛生上?(過度なストレスがかかるので)使っていません。

 今回は再度ESP8266を使ってみようと思い立ち、MacにArduinoの実行環境を作るところからスタートです。手順は以前のblogでWindows版のArduinoをセットアップした方法と同じです。ダウンロードサイトからArduinoを取ってきて、起動後、ESP8266ボードの設定を行いました。Arduino_mac_setup190421.png まず、メニューの「Arduino - Preferences」で「環境設定」を立ち上げ、「追加のボードマネージャのURL」に以下のURLを追加します。
http://arduino.esp8266.com/stable/package_esp8266com_index.json
ESP8266_setting1_190421.png 次にメニューの「ツール - ボード - ボードマネージャ」を選択し、ESP8266_setting2_190421.pngESP8266のボード情報をインストールします。ESP8266_setting3_190421.pngインストール後、再度「ツール - ボード」から「Generic ESP8266 Module」を選択します。ESP8266_setting4_190421.png
 次にプログラムを書き込むためのシリアルポートの設定です。PC(MacBook Air)とArduino(ESP8266)をRS-232Cケーブルで接続し、Macコンソール上で以下のコマンドを実行すると
$ ls -l /dev/tty.*
シリアルポートの情報(usbserial-FTB4XJSL)を得ることができます。mac_serial_setting190421.pngこの情報をボード設定に反映させておきます。ESP8266_comm_setting190421.png
 準備は整いましたので、定番のLチカで動作検証です。ネットによくあるコードを拝借して、書き込みました。LED_Flicker_prog190421.pngLED_Flicker190421.png バラック配線でビニールテープ貼り貼りで美しくありませんが、問題なく動作しました。MacでのArduino動作環境も問題なく構築できたようです。次のステップに進めそうです。

日経電子版記事をスクレイピングする(2)

 前回の続きです。前回は日経電子版の個人ページにログインし、調べたい内容を検索し、リストを作成する所までお話しました。今回は具体的に記事をダウンロードし、その内容をword2vecで処理する所までお話します。

 前回のPythonプログラムは修正・追記しました。
実行環境は、前回と同じUbuntu環境下でFireFoxのWebdriverを使いました。
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
import time
import sys

#Firefox setting
options = Options()
options.set_headless()
driver = webdriver.Firefox(options=options, executable_path=r"/home/drbobt/anaconda3/..../geckodriver")

# Login Page
driver.get('https://r.nikkei.com/login')
time.sleep(2)

username = "mail_address"
password = "password"

login_username = driver.find_element_by_id("LA7010Form01:LA7010Email")
login_username.clear()
login_username.send_keys(username)

login_password = driver.find_element_by_id("LA7010Form01:LA7010Password")
login_password.clear()
login_password.send_keys(password)

driver.find_element_by_class_name('btnM1').click() # Login button click
time.sleep(2)

# Search condition
startdate_y = '2018'
startdate_m = '01'
startdate_d = '01'
enddate_y = '2018'
enddate_m = '01'
enddate_d = '31'
search_word = 'IoT'

# Search url
target_url='https://r.nikkei.com/search...(cut)...' + enddate_y + '%2F'+ enddate_m +'%2F' + enddate_d + '++from%3A'+ startdate_y + '%2F' + startdate_m +'%2F'+ startdate_d + '++...(cut)...+'+ search_word + '+-...(cut)...&volume=200'
driver.get(target_url)
time.sleep(2)

# BeautifulSoup
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')

# Articles count
sel0 = soup.find_all("p",attrs={"class":"search__result-count"})
for i in sel0:
count= int(i.text)
print (count)

# Article's title
sel1 = soup.find_all("h3",attrs={"class":"nui-card__title"})
# Article datetime
sel2 = soup.find_all("a",attrs={"class":"nui-card__meta-pubdate"})

# Result output
out_number = []
out_url = []
out_title = []
out_datetime = []

if len(sel1) != len(sel2):
sys.exit()

for i in range(0, len(sel1)):
cnt = str(i+1)
out_url_temp = sel1[i].a.get("href")
out_title_temp = sel1[i].a.get("title")
out_number.append(cnt)
out_url.append(out_url_temp)
out_title.append(out_title_temp)
out_datetime.append(sel2[i].time.get("title"))

# Target page
driver.get(out_url_temp)
time.sleep(3)
html1 = driver.page_source
soup1 = BeautifulSoup(html1, 'html.parser')
# Article title
sel11 = soup1.find_all("span",attrs={"class":"cmnc-middle JSID_key_fonthln m-streamer_medium"})
# Article content
sel12 = soup1.find_all("div",attrs={"class":"cmn-article_text a-cf JSID_key_fonttxt m-streamer_medium"})
for j in sel11:
title_str = j.text
for j in sel12:
content_str = j.text
# Each Article output
out_txt_name = str(i+1) + '_' + title_str + '.txt'
with open(out_txt_name, mode='w') as f:
f.write(title_str + '\n' + content_str)

print(cnt + "/" + str(count) + " : " + out_title_temp)

# Result output
resdata = np.vstack([out_number, out_title, out_datetime, out_url])
df = pd.DataFrame(data=resdata).T
df.to_csv('result.csv', header=False, index=False, mode='a')

driver.quit()
プログラムの流れは、以下の通りです。
 ① 日経電子版にログイン(有料会員で)
 ② 検索ワードと記事の抽出期間を設定して検索実行
 ③ 検索件数を取得し、記事のタイトルと日時、URLの結果をリストを保存
 ④ 個別記事のタイトルと本文を個別のテキストファイルに保存
①は前回と同じで、②③は一部修正、④は今回新規作成しました。①は9〜30行目、②は32〜44行目、③は46〜77、99〜102行目、④は79〜95行目に対応します。

 ②③の検索ページは以下の通りで、検索ワードと検索条件(記事の抽出期間等)を入力し検索すると、検索件数が出力されますので、その件数分の記事を収集しました。③の記事の日時もhtml上に情報がありますので、今回は一緒に収集しました。SearchPage_190414.png 79行目から記載している④の個別ページは以下の通りです。余分な情報がありますので、この中から記事タイトルと本文のみを抽出し、テキストファイルに個別に保存しました。ArticlePage_190414.png スクレイピング上の注意点は次の二点でした。一点目は検索ページの制約なのか?、一度に表示できるのは最大200件でした。そのため、検索件数が200件を超えるものについては、記事の抽出期間を短くする必要がありました。二点目は連続的に膨大なデータをスクレイピングし続けると、セキュリティ上の問題なのか?、しばらく検索できない状況になりました。時間をおいて再実行すると正常に動作しました。

 IoTに関する記事(2018年1月分)をスクレイピングし、以前お話した方法でword2vecで分析した結果は以下の通りでした。word2vec_result_190414.pngそれなりの興味深い結果が出ているように思えました。もう一歩踏み込みたい所ですが、直近のアイデアがないので、しばらく試行錯誤します・・。

日経電子版記事をスクレイピングする(1)

 日経新聞は購読し始めの頃は紙面でしたが、この6年ぐらいは電子版を利用しています。読む時間は会社の休み時間が主で、関心のあるテーマについてキーワードを登録をしておき、その記事が「Myニュース」に入ってくるので、それを短時間で読む感じです。タイトルだけ読み、興味がある記事をpdfに落とす毎日です。じっくり読み込めていないのでもったいない感じもします(反省・・)。
 日経電子版は有料会員ならば10年近く前の記事から読み返すことができるので、スクレイピングを使って、興味のある分野について効率良く読み込んでいこうと思いました。word2vecを使って分析するも良しです。スクレイピングは以前のブログで行ったやり方を参考に進めました。

 一部つまづいた所もありましたが、最終コードは以下の通りです。実行はUbuntu環境でFireFoxのWebdriverを使いました。つまづいた所は後で詳しくお話します。
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
import time

options = Options()
options.set_headless()
#Firefoxを操作
driver = webdriver.Firefox(options=options, executable_path=r"/home/drbobt/anaconda3/..../geckodriver")
username = "mail_address"
password = "password"

# Login Page
driver.get('https://r.nikkei.com/login')
time.sleep(2)
#driver.save_screenshot("ss1.png")

login_username = driver.find_element_by_id("LA7010Form01:LA7010Email")
login_username.clear()
login_username.send_keys(username)
login_password = driver.find_element_by_id("LA7010Form01:LA7010Password")
login_password.clear()
login_password.send_keys(password)
driver.find_element_by_class_name('btnM1').click() # Login button click
time.sleep(2)
#driver.save_screenshot("ss2.png")

# Search word (ex. IoT, 200 articles)
target_url='https://r.nikkei.com/search...(cut)...IoT&volume=200'
driver.get(target_url)
time.sleep(5)
html = driver.page_source

# BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
sel = soup.find_all("h3",attrs={"class":"nui-card__title"})

# CSV file output
out_number = []
out_url = []
out_title = []

for i in range(0, len(sel)):
out_number.append(str(i))
out_url.append(sel[i].a.get("href"))
out_title.append(sel[i].a.get("title"))

resdata = np.vstack([out_number, out_title, out_url])
df = pd.DataFrame(data=resdata).T
df.to_csv('result.csv', header=False, index=False)

driver.quit()
このプログラムを実行すると検索ワード「IoT」にヒットする直近の200件の記事のタイトルとURLがcsvファイルに保存されます。こんな感じです。SearchWord_IoT_190407.png記事の日付も入れておくべきでしたね・・。後日、要修正です。

つまづいた所は、ログインページの選択です。まず、プログラムの16行目で、日経トップページ(https://www.nikkei.com/)を指定すると、こんな感じで「広告ページ」が邪魔してしまい、seleniumで削除したかったのですが、うまく行きませんでした。NikkeiTopPage1_190407.png 次に、別の?トップページ(https://r.nikkei.com)をトライすると、広告は出なくなりました。ただ、ログインボタンを押して表示されるログインページのURLのcidの値が毎回変わることが分かりました。これもseleniumで使えません。NikkeiTopPage2_190407.png 最終的に落ち着いたのが、トップページを介さずに直接ログインページ(https://r.nikkei.com/login)を呼び出す方法です。Nikkei_Login_190407.png始めからそうしたら良かったですね・・。毎回、URLのcidの値は変わりますが、このページは呼び出せますので問題なしです。
 20〜26行目の「LA7010Form01:」や「btnM1」はログインページのメールアドレス、パスワード、ログインボタンのそれぞれの要素名を拾っています。31行目が検索ワードを指定して検索した際のページのURLです。直接指定します。実行すると無事に自分の閲覧環境で検索結果が表示できました。
 37行目以降はBeautifulsoupを用いて、必要な情報(検索ワードにヒットする記事のタイトルとURL)を吸い上げて、ファイルに書き出すコードです。約10年分の記事の整理も簡単にできそうです。
 今後は、記事を保存し、word2vecで処理してみようと思います。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

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

月別アーカイブ

メールフォーム

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