Skip to content

Instantly share code, notes, and snippets.

@tomo0611
Last active May 6, 2024 01:59
Show Gist options
  • Save tomo0611/f377358c32b7cdac0eaf075e23b239ae to your computer and use it in GitHub Desktop.
Save tomo0611/f377358c32b7cdac0eaf075e23b239ae to your computer and use it in GitHub Desktop.
Mobile Suica Python Extractor
import requests
import bs4
import re
import datetime
print("JRE Mobile Suica History Extractor v0.1")
print("Developed by @tomo0611_dev\n")
session = requests.Session()
class SuicaHistory:
def __init__(
self,
date,
in_type,
in_station,
out_type,
out_station,
balance,
amount,
):
self.date = date
self.in_type = in_type
self.in_station = in_station
self.out_type = out_type
self.out_station = out_station
self.balance = balance.replace("\\", "").replace(",", "")
self.amount = amount.replace(",", "")
def as_csv(self):
return f"{self.date},{self.in_type},{self.in_station},{self.out_type},{self.out_station},{self.balance},{self.amount}"
def __str__(self):
return f"{self.date} {self.in_type} {self.in_station} {self.out_type} {self.out_station} {self.balance} {self.amount}"
def save_image(url, file_path):
response = session.get(
url,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
},
)
with open(file_path, "wb") as file:
file.write(response.content)
print("[MobileSuica] Start login process")
url = "https://www.mobilesuica.com/index.aspx"
response = session.get(
url,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
},
)
# find form with beautifulsoup
soup = bs4.BeautifulSoup(response.text, "html.parser")
form = soup.find("form", id="form1")
# find image and save it
print("[MobileSuica] Getting captcha image and save it\n")
image = form.find("img")
save_image("https://www.mobilesuica.com/" + image["src"], "captcha.png")
post_url_action = form.get("action")
# print(post_url_action)
# list input fields
input_fields = form.find_all("input")
data = {}
for input_field in input_fields:
data[input_field.get("name")] = input_field.get("value")
# print(data)
print("You need to login to Mobile Suica")
data["MailAddress"] = input("Enter your email: ")
data["Password"] = input("Enter your password: ")
print("View captcha.png and enter captcha code")
captcha_code = input("Enter captcha: ")
data["WebCaptcha1_clientState"] = "[[[[null]],[],[]],[{},[]],null]"
data["WebCaptcha1__editor_clientState"] = (
"|0|01" + captcha_code + '||[[[[]],[],[]],[{},[]],"01' + captcha_code + '"]'
)
data["WebCaptcha1__editor"] = captcha_code
data["LOGIN"] = "%83%8D%83O%83C%83%93"
print("")
print("[MobileSuica] Post login data to server")
response = session.post(
"https://www.mobilesuica.com/" + post_url_action,
data=data,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
},
)
# ログイン可否の判定
if "<title>JR東日本:モバイルSuica>会員メニュー</title>" not in response.text:
print("[MobileSuica] Login failed")
exit(1)
# ログイン成功
print("[MobileSuica] Authentication successful")
# find post url
soup = bs4.BeautifulSoup(response.text, "html.parser")
href = (
soup.find("div", id="btn_sfHistory")
.find("a")
.attrs["href"]
.replace("javascript:StartApplication('", "")
.replace("')", "")
)
print("[MobileSuica] Redirect to business function (ViewHistory)")
# 業務機能へ転送遷移
response = session.post(
href,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
},
)
# find text javascript:StartApplication('https://www.mobilesuica.com/iq/ir/SuicaDisp.aspx?returnId=SFRCMMEPC03')
href = re.search(r"javascript:StartApplication\('(.+?)'\)", response.text).group(1)
print("[MobileSuica] Get history data\n")
response = session.post(
href,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
},
)
# get historyTable
soup = bs4.BeautifulSoup(response.text, "html.parser")
empty_elem = bs4.BeautifulSoup("<font></font>", "html.parser").find("font")
history_table = soup.find("td", attrs={"class": "historyTable"}).find_all("tr")
histiory_list = []
for row in history_table:
# find font with sentence
data = row.find_all("font")
if len(data) != 7:
data = [
data[0],
empty_elem,
empty_elem,
empty_elem,
empty_elem,
empty_elem,
empty_elem,
]
history_item = SuicaHistory(
data[0].text.strip(),
data[1].text.strip(),
data[2].text.strip(),
data[3].text.strip(),
data[4].text.strip(),
data[5].text.strip(),
data[6].text.strip(),
)
histiory_list.append(history_item)
print(history_item)
print("\n[MobileSuica] Save history data to history.csv")
with open(
"history_" + datetime.datetime.now().strftime("%Y%m%d") + ".csv",
"w",
encoding="shift-jis",
) as file:
for history in histiory_list:
file.write(history.as_csv() + "\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment