質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3075閲覧

Python - Form内のoption内容が変動する場合のparse

starrow1103

総合スコア137

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2017/05/23 05:33

環境

Python 3.6

BeautifulSoup4
requests

やっていること

BeautifulSoupとrequestsを使い、フォーム内の<select><option>の要素を取得しています。

例)

python

1from bs4 import BeautifulSoup 2import requests 3 4url = 'http://xxxxxxxxxxx/' 5html = requests.get(url) 6soup = BeautifulSoup(html.content,'html.parser') 7...

困っていること

ウェブページ上に複数の選択フォームがあり、片方を選択するとシームレスに片方のoptionが表示されるような仕組みの場合に、うまく取得ができません。

例えば・・・
https://data.j-league.or.jp/SFIX02/
このページはJリーグのデータサイトですが、デフォルトで開いた状態では、左のメニューを指定しないと、チーム選択ができないようになっています。
イメージ説明

実現したいこと

上のJリーグの例でいうと、左側のメニューのいずれかを選択した状態の右オプションを取得したいと考えています。

どなたか、良い方法をご存知でしたら、ご教授ください。

よろしくおお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

動的なページをrequestsを使った静的なアプローチでパースするのは「基本的には」難しいと思います。(できなくはないですがサイトのロジックを追っかけなければならないので骨が折れます。)

ので、seleniumを使用するアプローチに切り替えてはいかがでしょうか。

http://selenium-python.readthedocs.io

追記(スクレイピングはほどほどに)

python

1from contextlib import closing 2from operator import attrgetter 3from pprint import pprint 4from subprocess import DEVNULL 5from subprocess import Popen 6import time 7 8from selenium import webdriver 9from selenium.webdriver.common.keys import Keys 10 11 12data = {} 13 14try: 15 server = Popen("chromedriver.exe", stdout=DEVNULL) 16 with closing(webdriver.Chrome()) as driver: 17 driver.implicitly_wait(10) 18 driver.get("https://data.j-league.or.jp/SFIX02/") 19 lbox = driver.find_element_by_id("pullDown") 20 rbox = driver.find_element_by_id("teams") 21 22 def iter_opt_texts(box, start=0): 23 yield from map( 24 attrgetter("text"), 25 box.find_elements_by_tag_name("option")[start:], 26 ) 27 28 for ltext in iter_opt_texts(lbox, 1): 29 lbox.send_keys(Keys.ARROW_DOWN) 30 time.sleep(1) 31 data[ltext] = list(iter_opt_texts(rbox, 1)) 32finally: 33 server.terminate() 34 35pprint(data)

実行結果

{'J1リーグ': ['北海道コンサドーレ札幌', 'ベガルタ仙台', '鹿島アントラーズ', '浦和レッズ', '大宮アルディージャ', '柏レイソル', 'FC東京', '川崎フロンターレ', '横浜F・マリノス', 'ヴァンフォーレ甲府', 'アルビレックス新潟', '清水エスパルス', 'ジュビロ磐田', 'ガンバ大阪', 'セレッソ大阪', 'ヴィッセル神戸', 'サンフレッチェ広島', 'サガン鳥栖'], 'J2リーグ': ['モンテディオ山形', '水戸ホーリーホック', 'ザスパクサツ群馬', 'ジェフユナイテッド千葉', '東京ヴェルディ', 'FC町田ゼルビア', '横浜FC', '湘南ベルマーレ', '松本山雅FC', 'ツエーゲン金沢', '名古屋グランパス', 'FC岐阜', '京都サンガF.C.', 'ファジアーノ岡山', 'レノファ山口FC', 'カマタマーレ讃岐', '徳島ヴォルティス', '愛媛FC', 'アビスパ福岡', 'V・ファーレン長崎', 'ロアッソ熊本', '大分トリニータ'], 'J3リーグ': ['グルージャ盛岡', 'ブラウブリッツ秋田', '福島ユナイテッドFC', '栃木SC', 'Y.S.C.C.横浜', 'SC相模原', 'AC長野パルセイロ', 'カターレ富山', '藤枝MYFC', 'アスルクラロ沼津', 'ガイナーレ鳥取', 'ギラヴァンツ北九州', '鹿児島ユナイテッドFC', 'FC琉球', 'FC東京U-23', 'ガンバ大阪U-23', 'セレッソ大阪U-23']}

投稿2017/05/23 06:59

編集2017/05/23 10:32
YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

starrow1103

2017/05/23 07:07

ちょうどseleniumを検討していたところでした! 多くのサイトでphantomJSとの併用で紹介されているようですが、今回の場合seleniumと単体でできるのでしょうかね? ちょっとやってみます。
starrow1103

2017/05/23 23:54

実際のスクリプトまでご提示いただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問