見出し画像

電験二種の過去問をPythonで取得する方法


注意事項

Pythonを用いて、電気技術者試験センター(以下、試験センター)の過去問掲載ページにある過去問を一括取得する方法を解説する。勉強用に取得するのは、問題ないが、過去問を勉強以外に使用する際は、試験センターのHPで過去問の使用について確認、もしくは試験センターへ問い合わせを行ってほしい。
試験センターQ&A
https://www.shiken.or.jp/qa.html

必要な外部ライブラリ

今回は外部ライブラリとしてBeautifulsoup4というライブラリを使用する。そのため、インストールしていない場合は、以下のコマンドでインストールする必要がる。

pip用

pip install beautifulsoup4

Anaconda用

conda install beautifulsoup4

プログラム

必要ライブラリのimport

Beautifulsoup4以外は標準ライブラリなので、インストールしなくても使用できる。

from bs4 import BeautifulSoup
import urllib.request as req
import urllib
import os
import time
from urllib.parse import urljoin

aタグを取得

urlに電験二種の過去問掲載ページのurlを指定する。

url = "https://www.shiken.or.jp/answer/index_list.php?exam_type=20"
res = req.urlopen(url)
soup = BeautifulSoup(res, "html.parser")
result = soup.select("a[href]")

リンクのみ取得

link_list =[]
for link in result:
    href = link.get("href")
    link_list.append(href)

PDFのみ取得

電験の場合は、ファイルの拡張子がPDFとpdfがある。

pdf_list = [temp for temp in link_list if temp.endswith(('pdf', 'PDF'))]

試験問題の取得

# 一次試験と二次試験の過去問ファイル名
pdf_str= ['S1-R', 'S1-D', 'S1-K', 'S1-H', 'S1%28R%29', 'S1%28D%29', 'S1%28K%29', 'S1%28H%29', \
           'S2-K', 'S2-D', 'S2%EF%BC%88D%EF%BC%89', 'S2%EF%BC%88K%EF%BC%89', 'S2%28D%29', 'S2%28K%29']
for y in range(2009,2012):
    pdf_str.append(f'S1R_{y}')
    pdf_str.append(f'S1D_{y}')
    pdf_str.append(f'S1K_{y}')
    pdf_str.append(f'S1H_{y}')
    pdf_str.append(f'S2D_{y}')
    pdf_str.append(f'S2K_{y}')
for y in range(2022,2024):
    pdf_str.append(f'S2-K_{y}')
    pdf_str.append(f'S2-D_{y}')
# 解答
for y in range(2009,2024):
    if y == 2023:
        pdf_str.append(f'{y}_2_1')
    else:
        pdf_str.append(f'{y}_2_1')
        pdf_str.append(f'{y}_2_2')

test_pdf_list = [temp for temp in pdf_list if os.path.splitext(os.path.basename(temp))[0] in pdf_str]

相対URLを絶対URLにする

abs_pdf_list = []
for relative in test_pdf_list:
    temp_url = urljoin(url, relative)
    abs_pdf_list.append(temp_url)

保存用のファイル名を決める

# 保存用のファイル名
filename_list = []
for y in range(2023,2008,-1):
    if y == 2023:
        filename_list.append(f'二次電力管理{y}.pdf')
        filename_list.append(f'二次機械制御{y}.pdf')
        filename_list.append(f'理論{y}.pdf')
        filename_list.append(f'電力{y}.pdf')
        filename_list.append(f'機械{y}.pdf')
        filename_list.append(f'法規{y}.pdf')
        filename_list.append(f'解答一次{y}.pdf')
    else:
        filename_list.append(f'二次電力管理{y}.pdf')
        filename_list.append(f'二次機械制御{y}.pdf')
        filename_list.append(f'解答二次{y}.pdf')
        filename_list.append(f'理論{y}.pdf')
        filename_list.append(f'電力{y}.pdf')
        filename_list.append(f'機械{y}.pdf')
        filename_list.append(f'法規{y}.pdf')
        filename_list.append(f'解答一次{y}.pdf')

保存用のディレクトリ作成

target_dir = "ここに保存先の絶対パスを指定する"
savepath_list = []
for filename in filename_list:
    savepath_list.append(os.path.join(target_dir, filename))

ダウンロードの実施

ダウンロード先のサイトに負荷を掛けないように、1回あたり2秒間の間隔をあける。

for (pdflink, savepath) in zip(abs_pdf_list, savepath_list):
    urllib.request.urlretrieve(pdflink, savepath)
    time.sleep(2)

コード全体

保存先のディレクトリを設定するのを、忘れないようにご注意ください。

from bs4 import BeautifulSoup
import urllib.request as req
import urllib
import os
import time
from urllib.parse import urljoin

# <a>タグを取得
url = "https://www.shiken.or.jp/answer/index_list.php?exam_type=20"
res = req.urlopen(url)
soup = BeautifulSoup(res, "html.parser")
result = soup.select("a[href]")


# リンクのみ取得
link_list =[]
for link in result:
    href = link.get("href")
    link_list.append(href)


# pdfのみ取得
pdf_list = [temp for temp in link_list if temp.endswith(('pdf', 'PDF'))]

# 一次試験と二次試験の過去問ファイル名
pdf_str= ['S1-R', 'S1-D', 'S1-K', 'S1-H', 'S1%28R%29', 'S1%28D%29', 'S1%28K%29', 'S1%28H%29', \
           'S2-K', 'S2-D', 'S2%EF%BC%88D%EF%BC%89', 'S2%EF%BC%88K%EF%BC%89', 'S2%28D%29', 'S2%28K%29']
for y in range(2009,2012):
    pdf_str.append(f'S1R_{y}')
    pdf_str.append(f'S1D_{y}')
    pdf_str.append(f'S1K_{y}')
    pdf_str.append(f'S1H_{y}')
    pdf_str.append(f'S2D_{y}')
    pdf_str.append(f'S2K_{y}')
for y in range(2022,2024):
    pdf_str.append(f'S2-K_{y}')
    pdf_str.append(f'S2-D_{y}')
# 解答
for y in range(2009,2024):
    if y == 2023:
        pdf_str.append(f'{y}_2_1')
    else:
        pdf_str.append(f'{y}_2_1')
        pdf_str.append(f'{y}_2_2')

test_pdf_list = [temp for temp in pdf_list if os.path.splitext(os.path.basename(temp))[0] in pdf_str]


# 相対URLを絶対URLにする
abs_pdf_list = []
for relative in test_pdf_list:
    temp_url = urljoin(url, relative)
    abs_pdf_list.append(temp_url)
    

# 保存用のファイル名
filename_list = []
for y in range(2023,2008,-1):
    if y == 2023:
        filename_list.append(f'二次電力管理{y}.pdf')
        filename_list.append(f'二次機械制御{y}.pdf')
        filename_list.append(f'理論{y}.pdf')
        filename_list.append(f'電力{y}.pdf')
        filename_list.append(f'機械{y}.pdf')
        filename_list.append(f'法規{y}.pdf')
        filename_list.append(f'解答一次{y}.pdf')
    else:
        filename_list.append(f'二次電力管理{y}.pdf')
        filename_list.append(f'二次機械制御{y}.pdf')
        filename_list.append(f'解答二次{y}.pdf')
        filename_list.append(f'理論{y}.pdf')
        filename_list.append(f'電力{y}.pdf')
        filename_list.append(f'機械{y}.pdf')
        filename_list.append(f'法規{y}.pdf')
        filename_list.append(f'解答一次{y}.pdf')


# 保存用のディレクトリ作成
target_dir = "ここに保存先の絶対パスを指定する"
savepath_list = []
for filename in filename_list:
    savepath_list.append(os.path.join(target_dir, filename))


# ダウンロード
for (pdflink, savepath) in zip(abs_pdf_list, savepath_list):
    urllib.request.urlretrieve(pdflink, savepath)
    time.sleep(2)

参考にした記事

https://degitalization.hatenablog.jp/entry/2020/08/02/193536

関連記事

電験三種の過去問をPythonで取得する方法
https://note.com/elemag/n/nfdba4ff3112d?sub_rt=share_pw

電験一種の過去問をPythonで取得する方法
https://note.com/elemag/n/n9f86c492dcc9?sub_rt=share_pw

サイト

https://sites.google.com/view/elemagscience/%E3%83%9B%E3%83%BC%E3%83%A0


この記事が気に入ったらサポートをしてみませんか?