先日、noteでこちらの記事を公開しましたが、スクレイピングとテキストマイニングで1年間のニュースを振り返るの結構効率的だなと思ったので書きます。
主にプログラムと使った技術のこと書きます。
ニュース記事のスクレイピングとテキストマイニングの仕組み
ニュース記事振り返り効率化の仕組み
仕組みを簡単に図示したものが以下。
処理の流れとしては以下。
① スクレイピングできそうなITメディアサイト選出
② サイト別にスクレイピングする(タグ名とか違うからしょうがない)
③ Spread Sheetに出力する
④ テキストマイニング(出現率高い単語で記事名検索)
⑤ 抽出された記事名/リンクをもとに記事書く
UserLocalのテキストマイニングツールは文章をコピペするだけで無料でテキストマイニング→結果をビジュアル化してくれるので有益。
わりと簡単な仕組みでニュースの振り返り作業を効率化できるのでオススメです( ・v・)b
各ニュースメディアからのスクレイピングのコードも載せておきますね。
ニュース記事のスクレイピング
今回は、以下のニュースメディアをスクレイピングしました。
・Tech Crunch
・Yahoo! News IT
・日経XTECH
・techable
・GIZMODE
・GIGAZINE
・POSTD
他にも対象にしたメディアはあったのですが、Ajax通信で次のページを取得しているからスクレイピングをしづらかったり、タグ名が明らかにスクレイピングを嫌っているなというメディアは対象外にしました。
ニュース記事振り返り効率化のプログラム
プログラムはSeleniumを活用しました。
一例として、Tech Crunchのスクレイピング・Spread Sheet書き出しコードがこちら。
techcrunch_news.py
# coding=utf-8 import os from time import sleep from selenium import webdriver from selenium.webdriver.common.keys import Keys SCOPE_URL = 'https://spreadsheets.google.com/feeds' CREDENTIAL_FILE_NAME = 'spread_sheet_credential.json' TEMPLATE_FILE_NAME = 'spread_sheet_credential_template.txt' SHEET_PROJECT_ID = os.environ['SHEET_PROJECT_ID'] SHEET_PRIVATE_KEY_ID = os.environ['SHEET_PRIVATE_KEY_ID'] SHEET_PRIVATE_KEY = os.environ['SHEET_PRIVATE_KEY'] SHEET_CLIENT_EMAIL = os.environ['SHEET_CLIENT_EMAIL'] SHEET_CLIENT_ID = os.environ['SHEET_CLIENT_ID'] SHEET_CLIENT_X509_CERT_URL = os.environ['SHEET_CLIENT_X509_CERT_URL'] def write_news(sheet, link, max_loop_count): driver = webdriver.PhantomJS() driver.get(link) loop_count = 0 while loop_count < max_loop_count: loop_count += 1 print('-------------- \{\}回目のページアクセス... --------------'.format(loop_count)) # Spread Sheet書き込み write_techcrunch_news_elements(driver, sheet) # 次のページへアクセス driver = access_to_next(driver) def access_to_next(driver): next = driver.find_element_by_link_text('次へ') # タイムアウトが発生したら新しくページにアクセスする page_content = '/page/' url = driver.current_url splited_url_contents = url.split(page_content) next_url = splited_url_contents[0] + page_content + str(int(splited_url_contents[1].split('/')[0]) + 1) try: next.click() except Exception as e: print('Timeoutが発生したので新しく「\{\}」にアクセスする。'.format(next_url)) driver = webdriver.PhantomJS() driver.get(next_url) return driver def write_techcrunch_news_elements(driver, sheet): # ページが完全に読み込まれるまでの時間を加味して最大10秒間待つ driver.set_page_load_timeout(10) title_dict = {} blocks = driver.find_elements_by_class_name('river-block') count = 0 for block in blocks: count += 1 ad_contain = None print('----- \{\}個目のriver-blockは... -----'.format(count)) try: ad_contain = block.find_element_by_class_name('ad-contain') except Exception as e: try: news_title = block.find_element_by_class_name('post-title').find_element_by_tag_name('a').text news_time = block.find_element_by_tag_name('time').get_attribute('datetime') title_dict[news_title] = news_time print('News No.\{\} title:\{\} date:\{\}'.format(count, news_title, news_time)) except Exception as e: print('スポンサー記事だった.'.format(count)) continue if ad_contain is not None: print('広告だった.??'.format(count)) write_to_sheet(sheet, title_dict) def write_to_sheet(sheet, dict): keys = list(dict.keys()) values = list(dict.values()) titles = sheet.col_values(1) start_row_num = len(titles) + 1 start_row = str(len(titles) + 1) end_row = str(len(keys) + start_row_num) # Spread Sheetに書き込み update_cells_with_list(sheet, 'A'+start_row, 'A'+end_row, keys, value_input_option='USER_ENTERED') update_cells_with_list(sheet, 'B'+start_row, 'B'+end_row, values, value_input_option='USER_ENTERED') def access_to_sheet(gid): # 書き込み用ファイル credential_file = open(CREDENTIAL_FILE_NAME, 'w') # テンプレートファイルを読み込み、書き込みファイルに書き込み template_file = open(TEMPLATE_FILE_NAME) template_file_lines = template_file.readlines() line_num = 0 for line in template_file_lines: line_num += 1 if line_num == 3: line = line.format(SHEET_PROJECT_ID) elif line_num == 4: line = line.format(SHEET_PRIVATE_KEY_ID) elif line_num == 5: line = line.format(SHEET_PRIVATE_KEY) elif line_num == 6: line = line.format(SHEET_CLIENT_EMAIL) elif line_num == 7: line = line.format(SHEET_CLIENT_ID) elif line_num == 11: line = line.format(SHEET_CLIENT_X509_CERT_URL) credential_file.writelines(line) template_file.close() credential_file.close() credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDENTIAL_FILE_NAME, SCOPE_URL) client = gspread.authorize(credentials) return client.open_by_key(gid) def update_cells_with_list(sheet, from_cell, to_cell, id_list, value_input_option): cell_list = sheet.range('\{\}:\{\}'.format(from_cell, to_cell)) count_num = -1 for cell in cell_list: count_num += 1 try: val = id_list[count_num] except Exception as e: continue if val is None: continue cell.value = val print('\{\}から\{\}まで書き込むよ'.format(from_cell, to_cell)) sheet.update_cells(cell_list, value_input_option=value_input_option) # 書き込みしたいSpread SheetのシートID sheet_gid = 'xxxxx' sheet_name = 'Tech Crunch' target_link = 'https://jp.techcrunch.com/page/149/' max_loop_count = 50 # Spread Sheetの書き込みできる一番上の行番号を確認する sheet = access_sheet(sheet_gid).worksheet(sheet_name) write_news(sheet, target_link, max_loop_count)
spread_sheet_credential_template.txt
{ "type": "service_account", "project_id": "{}", "private_key_id": "{}", "private_key": "-----BEGIN PRIVATE KEY-----{}-----END PRIVATE KEY-----\n", "client_email": "{}", "client_id": "{}", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "{}" }
.env
SHEET_PROJECT_ID=xxxxx SHEET_PRIVATE_KEY_ID=xxxxx SHEET_PRIVATE_KEY=xxxxx SHEET_CLIENT_EMAIL=xxxxx SHEET_CLIENT_ID=xxxxx SHEET_CLIENT_X509_CERT_URL=xxxxx
ファイルを作成したら「xxxxx」の箇所を適宜書き換え、必要なライブラリをpipでインストールして、foregoを使ってPythonファイルを動かせば、スクレイピングをじゃんじゃんしてSpread Sheetに書き込みしていってくれます。
Spread Sheetへの認証方法やPythonのプログラミング方法は、以下のnoteを参考にしてください。
他のメディアに関しても、「write_techcrunch_news_elements()」メソッドと「access_to_next()」メソッドの中身の要素の取得方法を書き換えて、URLの指定を変更すればスクレイピングできる。
以上、「スクレイピング × Spread Sheet書き出し × 作業」は、ほんと有益だよという話でした。
まだまだ効率化できる作業は多そうだし、試してみたい。
Pythonをしっかり学びたい方向け
最後に、Pythonをしっかり学びたいという方向けにおすすめの学習ツールを紹介しておきます。
スッキリわかるPython入門 スッキリわかるシリーズ
そもそもPythonの書き方が分からないという方はこちら、安いし分かりやすいのでオススメです。
プログラミング言語 Python 3 入門
このコースで学べること
- Pythonの基礎(データ、制御フロー、関数、データ構造、モジュール、例外(エラー)、クラス、入力と出力、標準ライブラリ)
- ターミナルを使用したPythonの実行
- PyCharmを使用したPython ファイルの作成・デバッグ実行
Pythonの基礎の基礎が丁寧に開設されていて、Python初心者の方でもPythonへの理解が深まりやすいUdemyのコースです。
Pythonの仕組みを基礎からしっかりと理解しておきたい方にオススメです。
【プログラミング言語 Python 3 入門】をUdemyで見てみる
Pythonで作業の自動化・効率化
Pythonでのプログラミング学習中の方向けに、Noteでより詳細なプログラミングチュートリアルを配信しているので、そちらもチェックしてみてください( ・v・)/
では!