xpathを学んでミスミメンテbotのメンテ情報取得を改善した
困っていたこと
ミスミメンテbotが時々うまく動かないバグに困っていた.
動かなくなる状況を確認してみると, ミスミサイトでトラブルが発生し,ページ上部に緊急お知らせが出されるときに動かなくなる.
緊急お知らせがでてきた様子は こんな感じ.
赤枠の欄が緊急時のみ出現する. 赤枠のせいでレイアウトがずれるのが原因らしい.
もともとの取得方法
レイアウトがずれただけで動かなくなってしまうのは以下のようなやり方をしていたのが原因.
もともとは以下のようにメンテ情報を取得していた.
- chromeのデベロッパーツールでメンテお知らせ欄(青枠)のpathを探し出す
- 右クリックで出てくる画像赤枠の部分からxpathをコピー
- 青枠内の何番目にメンテ情報が記載されるか不明の為,青枠内を十分回数のforループで順番に取得
- "メンテナンス"という文字がある行の日時を取得してツイートに反映
このやり方だと,xpathは要素の位置の形式を使うことになる. 当然レイアウトがずれるとこの記述もかわるので正しく取得できないということになる.
実際のコードだと以下の行.
# メッセージを順番に取得 mescnt = 0 i = 1 for i in range(1,cnt): headings = html.xpath("string(/html/body/div[1]/div[3]/div[1]/div[1]/div/ul/li[" + str(i) + "])") if [headings]!=['']: message += [headings] mescnt += 1
改善した
「attention--infoというクラスで囲まれているので 順序ではなくタグとclass名でXPath指定すると結構ロバストになるよ(要約)」
というアドバイスをもらったので調べました. (xpathあんまりわからずに使っていた...)
調べたこと
以下のページがとても分かりやすかった.
xpathではXML文章をツリー構造としてとらえていて, (開発者が書いていれば)class属性がラベルのようにくっついている.
で,そのラベルを使った指定もできるらしい.できないと存在意味ない気がするのでそれはそうだけどとても便利.
上のページを見ると,コンテンツの文字列で検索しての指定や,指定要素の兄弟要素(○○の行の一個上とかが取得できそう)という指定方法もあるらしい.
書いてみたコード
これを読んで改善したコードを最後に貼る.
attention--infoというclass属性を指定するやり方で書いてみた. ちなみに,緊急お知らせ欄(赤枠)の属性はattention--notice.
xpath側で"メンテナンス"で検索をかけるようにするとプログラムがとても短くなりそう. ただ,ミスミサイト内の予想外の場所に"メンテナンス"という文字列が現れる可能性があるので,青枠内を取得する方針は維持することにした.
# メッセージを順番に取得 mescnt = 0 i = 1 for i in range(1,cnt): # メンテが予告される青枠部分を指定して取得 headings = html.xpath("string(//ul[@class='attention--info']/li[" + str(i) + "])") if [headings]!=['']: message += [headings] mescnt += 1 # print(mescnt) # メッセージ数 print(message)
備考
貼っている画像はすべて MISUMI-VONA | ミスミの総合Webカタログ のスクリーンショット.