2019/04/14
前回の続きです。前回は日経電子版の個人ページにログインし、調べたい内容を検索し、リストを作成する所までお話しました。今回は具体的に記事をダウンロードし、その内容を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上に情報がありますので、今回は一緒に収集しました。

79行目から記載している④の個別ページは以下の通りです。余分な情報がありますので、この中から記事タイトルと本文のみを抽出し、テキストファイルに個別に保存しました。

スクレイピング上の注意点は次の二点でした。一点目は検索ページの制約なのか?、一度に表示できるのは最大200件でした。そのため、検索件数が200件を超えるものについては、記事の抽出期間を短くする必要がありました。二点目は連続的に膨大なデータをスクレイピングし続けると、セキュリティ上の問題なのか?、しばらく検索できない状況になりました。時間をおいて再実行すると正常に動作しました。
IoTに関する記事(2018年1月分)をスクレイピングし、
以前お話した方法でword2vecで分析した結果は以下の通りでした。

それなりの興味深い結果が出ているように思えました。もう一歩踏み込みたい所ですが、直近のアイデアがないので、しばらく試行錯誤します・・。