📄
pythonでスクレイピングしてスプレッドシートに書きだす方法
手順
- Google cloud APIsの必要なAPIを有効化する
- 検索するコードを書く
- スクレイピングするコードを書く
- スプレッドシートに書きだすコードを書く
- スプレッドシートに権限を付与する
- 実行する
Google cloud APIsの設定を行う
有効化するAPI
・Google Sheets API
・Custom Search API
Google cloudコンソールのAPIとサービスから、上記2つを検索し、有効化する。
検索するコードを書く
search.py
from googleapiclient.discovery import build
import sys,os
from dotenv import load_dotenv
# envファイルの読み込み
load_dotenv()
# Google Custom Search APIを使うための情報
API_KEY = os.environ.get('API_KEY')
CSE_ID = os.environ.get('CSE_ID')
def get_search_results(query, start_index):
# Google Custom Search API
service = build("customsearch",
"v1",
cache_discovery=False,
developerKey=API_KEY)
# CSEの検索結果を取得
result = service.cse().list(q=query,
cx=CSE_ID,
num=10,
start=start_index).execute()
# 検索結果(JSON形式)
return result
def get_link_list():
# 検索結果を格納する配列
results_arr = []
# 10件ずつしか検索できないので、100件取得するためのインデックスの配列(1~10、11~20、、、というように10回に分けて取得する)
# index_arr = [1,11,21,31,41,51,61,71,81,91]
index_arr = [1]
# 検索する文字列(このpythonファイルを実行するときに入力する引数)
search_args = sys.argv[1]
for index in index_arr:
result_search = get_search_results(search_args,index)
for item in result_search["items"]:
if not "/rank/" in item["link"] and not "/rstLst/" in item["link"]:
results_arr.append(item["link"])
return results_arr
スクレイピングするコードを書く
scraping.py
from bs4 import BeautifulSoup
import requests
import bs4
def get_store_info(url):
try:
# urlにリクエストを送る
res = requests.get(url)
#取得したresをパース
soup = BeautifulSoup(res.content, "html.parser")
store_info = {}
# 食べログのリンク
store_info["link"] = url
# 店舗名
store_name = soup.find('div', class_='rstinfo-table__name-wrap').contents[1].contents[0]
# print(store_name)
store_info["store_name"] = store_name
# ジャンル
Genre = soup.find('th', string="ジャンル", class_='').next_sibling.next_sibling.contents[1].contents[0]
# print(Genre)
store_info["Genre"] = Genre
# 電話番号
tel_arr = soup.find_all('strong', class_='rstinfo-table__tel-num')
tel = ""
for tel_item in tel_arr:
if tel_item.contents[0].startswith("03-"):
tel = tel_item.contents[0]
break
else:
tel = tel_item.contents[0]
# print(tel)
store_info["tel"] = tel
# 住所
address_arr = soup.find('p', class_='rstinfo-table__address').contents
address = ""
for address_parts in address_arr:
if not type(address_parts) is bs4.element.NavigableString:
for address_parts_item in address_parts.contents:
if not type(address_parts_item) is bs4.element.NavigableString:
address += address_parts_item.contents[0]
else:
address += address_parts_item
else:
address += address_parts
# print(address)
store_info["address"] = address
return store_info
except:
return False
スクレイピングするコードに関しては、対象のサイトによって書くコードが変わるので、スクレイピングしたいサイトに応じてコードを書き換える。
スプレッドシートに書きだすコードを書く
output.py
import gspread
from gspread.exceptions import *
from oauth2client.service_account import ServiceAccountCredentials
import sys,os
from dotenv import load_dotenv
# envファイルの読み込み
load_dotenv()
def output_spreadsheet(store_info):
if not store_info:
return
secret_key = os.environ.get('SECRET_KEY')
book_name = '食べログスクレイピング'
sheet_name = 'シート1'
try:
sheet = get_gspread_book(secret_key, book_name).worksheet(sheet_name)
except SpreadsheetNotFound:
print('Spreadsheet: ' + book_name + 'が見つかりませんでした')
sys.exit()
except WorksheetNotFound:
print('Worksheet: ' + sheet_name + 'が見つかりませんでした')
sys.exit()
row = next_available_row(sheet)
print(row)
sheet.update_acell('A' + str(row), store_info["link"])
sheet.update_acell('B' + str(row), store_info["store_name"])
sheet.update_acell('C' + str(row), store_info["Genre"])
sheet.update_acell('D' + str(row), store_info["tel"])
sheet.update_acell('E' + str(row), store_info["address"])
def get_gspread_book(secret_key, book_name):
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name(secret_key, scope)
gc = gspread.authorize(credentials)
book = gc.open(book_name)
return book
def next_available_row(worksheet):
str_list = list(filter(None, worksheet.col_values(1))) # fastest
return str(len(str_list) + 1)
スプレッドシートに権限を付与する
スプレッドシートに書きだすためには、
Google cloudのプロジェクト>APIとサービス>認証情報
から、サービスアカウントを作成し、作成したサービスアカウントからjsonのキーを発行する。
このjsonファイルの中に、client_emailがあるので、このメールアドレスに、書きだしたいスプレッドシートの共有から権限を付与する。
こうすることで、APIがスプレッドシートを見つけ出しているんだと思う。
実行する
最後に実行するためのファイルを作成する。
index.py
from search import get_link_list
from scraping import get_store_info
from output import output_spreadsheet
from time import sleep
link_list = get_link_list()
for link in link_list:
store_info = get_store_info(link)
output_spreadsheet(store_info)
sleep(2)
このファイルを実行するのだが、実行時に引数を一つ渡して実行する。
この引数は、検索したい文字列になる。
terminal
python index.py "居酒屋 吉祥寺"
今回は検索エンジンを食べログに限定しているため、このように検索すると、吉祥寺の居酒屋の食べログのサイトが検索できる。
Discussion