趣味で計算流砂水理

趣味で計算流砂水理 Computational Sediment Hydraulics for Fun Learning

数値計算とか河川工学とかプログラミングのことを書いています

MENU

備忘録:webページ内の動的iframe内のデータをスクレイピングする

スポンサーリンク

webページ内の動的iframe内のデータをスクレイピングする方法のメモです。

サンプルwebサイト

河川屋さんにはお馴染みの水文水質データベースより水質・底質のデータをサンプルとしました。

http://www1.river.go.jp/cgi-bin/DspWquaData.exe?KIND=1&ID=404031284401010&KIJUN=01&BGNDATE=20210101&ENDDATE=20210531&KAWABOU=NO

わかりにくいですが、赤枠内がiframeです。

しかもURLは動的に振られる仕様になっています。

スクレイピング(2022/7/4:より簡単な方法を見つけたので修正します)

モジュール

定番のBeautifulSoupを使います。

import pandas as pd
from bs4 import BeautifulSoup
from urllib import request

手順1:BeautifulSoupで解析

BeautifulSoupでサイトの情報を取得します。

url = 'http://www1.river.go.jp/cgi-bin/DspWquaData.exe?KIND=1&ID=404031284401010&KIJUN=01&BGNDATE=20210101&ENDDATE=20210531&KAWABOU=NO'
response = request.urlopen(url)
soup = BeautifulSoup(response, features="lxml")

手順2:iframeに移動

iframeを検索してそのページに飛びます。

tmp = soup.findAll("iframe")[0]['src']
url2 = 'http://www1.river.go.jp' + tmp
response = request.urlopen(url2)

手順3:スクレイピング

pandasで読み込みます。

dfs = pd.read_html(response.read())
dfs[0]
年月日 時分 採水位置 採水時刻(時分) 採水位置.1 天候 水位(m) 流量(m3/sec) 全水深(m) 採水水深(m) ... 水温(℃) 外観(1) 外観(2) 外観(3) 外観(4) 臭気(冷時) 透視度(cm) 透明度(m) 干潮時刻(時分) 満潮時刻(時分)
0 2021年02月24日 09時00分 流心 09:00 流心 5.02 243.00 2.2 0.44 ... 0.6 淡黄色透 NaN NaN NaN 無臭 34 NaN NaN NaN
1 2021年05月19日 09時10分 流心 09:10 流心 6.17 187.62 3.5 0.70 ... 15.0 無白色濁 NaN 濁り多し NaN 無臭 21 NaN NaN NaN

修正前の記事

モジュール

定番のseleniumとBeautifulSoupを使います。 chromedriver_binaryのインストール方法は以下を参照。

computational-sediment-hyd.hatenablog.jp

from selenium import webdriver
import chromedriver_binary
from bs4 import BeautifulSoup
import pandas as pd

手順1:selenimで解析

いつもどおり、selenimでChromeを使ってサイトに接続します。

driver = webdriver.Chrome()
url = 'http://www1.river.go.jp/cgi-bin/DspWquaData.exe?KIND=1&ID=404031284401010&KIJUN=01&BGNDATE=20210101&ENDDATE=20210531&KAWABOU=NO'
driver.get(url)

手順2:iframeに移動

iframeを検索してそのページに飛びます。今回はcss_selectorを使いましたが何でもいいです。

  • 参考サイト:css_selectorを検索

Python Webスクレイピング テクニック集「取得できない値は無い」JavaScript対応@追記あり6/12 - Qiita

  • 参考サイト:iframeへswitch

Seleniumでiframeに出入りしてみた - Qiita

Seleniumでページ内のiframeを操作できない - Qiita

scss = 'body > center > p > iframe'
iframe = driver.find_element_by_css_selector(scss)
driver.switch_to.frame(iframe)

手順3:スクレイピング

ここからはいつもどおりに解析するだけです。 BeautifulSoupとpandasの2手法をまとめておきます。

方法1:BeautifulSoup
BeautifulSoup(driver.page_source, 'html.parser')
    <html><head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
    <meta content="text/css" http-equiv="Content-Style-Type"/>
    <title>任意期間水質検索結果</title>
    </head>
    <body bgcolor="#ffffff">
    <center>
    <table border="1">
    <tbody>
    <tr>
    <th bgcolor="#ccffff" nowrap="">年月日</th>
    <th bgcolor="#ccffff" nowrap="">時分</th>
    <th bgcolor="#ccffff" nowrap="">採水位置</th>
    <th align="center" bgcolor="#ccffff" nowrap="">採水時刻<br/>(時分)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">採水位置<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">天候<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">水位<br/>(m)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">流量<br/>(m3/sec)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">全水深<br/>(m)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">採水水深<br/>(m)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">気温<br/>(℃)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">水温<br/>(℃)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">外観(1)<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">外観(2)<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">外観(3)<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">外観(4)<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">臭気(冷時)<br/> </th>
    <th align="center" bgcolor="#ccffff" nowrap="">透視度<br/>(cm)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">透明度<br/>(m)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">干潮時刻<br/>(時分)</th>
    <th align="center" bgcolor="#ccffff" nowrap="">満潮時刻<br/>(時分)</th>
    </tr>
    <tr>
    <td align="center" bgcolor="#FFFFCC" nowrap="">2021年02月24日</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">09時00分</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">流心</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">09:00</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">流心</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""></td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">5.02</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">243</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">2.2</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">0.44</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">2.6</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">0.6</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">淡黄色透</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">無臭</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">34</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    </tr>
    <tr>
    <td align="center" bgcolor="#FFFFCC" nowrap="">2021年05月19日</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">09時10分</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">流心</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">09:10</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">流心</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""></td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">6.17</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">187.62</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">3.5</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">0.7</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">16.5</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">15</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">無白色濁</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">濁り多し</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">無臭</td>
    <td align="center" bgcolor="#FFFFCC" nowrap="">21</td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    <td align="center" bgcolor="#FFFFCC" nowrap=""> </td>
    </tr>
    </tbody>
    </table>
    </center>
    </body></html>
方法2:pandas
dfs = pd.read_html(driver.page_source)
dfs[0]
年月日 時分 採水位置 採水時刻(時分) 採水位置.1 天候 水位(m) 流量(m3/sec) 全水深(m) 採水水深(m) ... 水温(℃) 外観(1) 外観(2) 外観(3) 外観(4) 臭気(冷時) 透視度(cm) 透明度(m) 干潮時刻(時分) 満潮時刻(時分)
0 2021年02月24日 09時00分 流心 09:00 流心 5.02 243.00 2.2 0.44 ... 0.6 淡黄色透 NaN NaN NaN 無臭 34 NaN NaN NaN
1 2021年05月19日 09時10分 流心 09:10 流心 6.17 187.62 3.5 0.70 ... 15.0 無白色濁 NaN 濁り多し NaN 無臭 21 NaN NaN NaN