Python で Yahoo 乗換案内の経路検索結果をスクレイピング

Python で Yahoo 乗換案内の経路検索結果をスクレイピングするコードのメモ

import urllib.request
from bs4 import BeautifulSoup
import urllib.parse
import re

# Yahoo乗換から検索結果をスクレイピングで抽出

startsta = '青森' # 出発駅
endsta = '秋田' # 到着駅
viasta1 = '' # 経由駅
viasta2 = ''
year = '2022'
month = '09' # 2桁でないとエラー
day = '26'
hh = '09'
m1 = '0'
m2 = '0'
type=4  # 出発1,到着4,始発3,終電2,指定なし5
ticket='ic' # 乗車券: normal, IC: ic
expkind=1 # 座席 自由席優先1, 指定席優先2, グリーン3
ws=2 # 歩く速度 急いで1 ~ ゆっくり4
s=0 # 到着が早い順: 0, 乗り換え回数順: 2, 料金が安い順: 1
# 以下,使用しない: 0, 使用する: 1
al=0 # 空路
shin=0 # 新幹線
ex=0 # 有料特急
hb=0 # 高速バス
lb=1 # 路線/連絡バス
sr=1 # フェリー

# encode
startstaen = urllib.parse.quote(startsta) 
endstaen = urllib.parse.quote(endsta)
viasta1en = urllib.parse.quote(viasta1)
viasta2en = urllib.parse.quote(viasta2)

url = f'https://transit.yahoo.co.jp/search/result?from={startstaen}&to={endstaen}&via={viasta1en}&via={viasta2en}&viacode=&viacode=&y={year}&m={month}&d={day}&hh={hh}&m1={m1}&m2={m2}&type={type}&ticket={ticket}&expkind={expkind}&userpass=1&ws={ws}&s={s}&al={al}&shin={shin}&ex={ex}&hb={hb}&lb={lb}&sr={sr}&mtf=1'


# print(url)

req = urllib.request.urlopen(url)
html = req.read().decode('utf-8')

soup = BeautifulSoup(html, 'html.parser')

print('[使用駅]')
li_station = soup.select("div.station > dl > dt > a") # 使用駅記載部分を抽出
# print(li_transprot)
transport = [None] * len(li_station)
for i in range(len(li_station)):
	transport[i] = li_station[i].text.strip()
print(transport)

print('[使用列車]')
li_transprot = soup.select("li.transport") # 列車記載部分を抽出
# print(li_transprot)
transport = [None] * len(li_transprot)
for i in range(len(li_transprot)):
	transport[i] = li_transprot[i].select_one('div').text.strip()
	transport[i] = transport[i].replace("[train]", "")
print(transport)

print('[所要時間]')
li_time = soup.select("li.time") # 到着時間の記載部分を抽出
# print(li_time)
# print(li_time[2])
trip_time = li_time[2].select_one('span.small').text.strip() # <span class="small">で囲まれたテキストを抽出
match = re.search(r'[0-9]+時間', trip_time)
if match is None:
	trip_time_h = "0"
else:
	trip_time_h = match.group().replace("時間", "")
match = re.search(r'[0-9]+分', trip_time)
if match is None:
	trip_time_min = "0"
else:
	trip_time_min = match.group().replace("分", "")
print(trip_time_h, "時間", trip_time_min, "分")

print('[金額]')
li_fare = soup.select("li.fare") # 運賃の記載部分を抽出
# print(li_fare)
# print(li_fare[0])
fare = li_fare[0].text.strip() # <span class="mark">で囲まれたテキストを抽出
fare = fare.replace(",", "")
# print(fare)
fare = re.search(r'[0-9]+', fare).group()
print(fare, "円")

print('[定期]')
li_com_pass = soup.select("div.detail") # 定期代の記載部分を抽出
# print(li_com_pass)
# print(li_com_pass[0])
li_com_pass = li_com_pass[0].select("dl > dd > ul > li > span")
# print(li_com_pass)
com_pass = [None]*3
for i in [0,1,2]:
	_ = li_com_pass[i].text.strip()
	_ = _.replace(",", "")
	com_pass[i] = re.search(r'[0-9]+', _).group()
	print(com_pass[i], "円")

参考文献

「【Python】Yahoo乗換をスクレイピングして駅到着時間を抽出する」あとをしNOTE https://atooshi-note.com/python-yahoo-trans-scraping/