🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

1回答

1995閲覧

seleniumで取得した情報をpandasでdataframeに格納したい

john_doe_

総合スコア354

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

1グッド

0クリップ

投稿2019/11/05 10:46

編集2019/11/05 11:01

下記サイトの場合、大学名と複数ある学科名を取得してdataframeに格納したいと考えています。
https://shingakunet.com/searchList/ksl_daitan/ql_ld010/qm_lc111/qs_v3660/

当該事例に関わらず項目ごとに取得情報の数が合わずdataframeに格納できないことは、
scrapingをする上でよく直面する課題となっています。

from selenium import webdriver import pandas as pd driver = webdriver.Chrome() driver.get('https://shingakunet.com/searchList/ksl_daitan/ql_ld010/qm_lc111/qs_v3660/') names = [] div = [] for i in driver.find_elements_by_class_name('__shi_m_heading_primary'): names.append(i.text) for i in driver.find_elements_by_class_name('gakkaSearchScCst__hdg'): div.append(i.text) len(names) 20 len(div) 43 df = pd.DataFrame() df['names'] = names df['div'] = div

divの数に合わせて、nameを取得すれば、datafameにできると思うのですが、
下記ようにしてもnameは同じものを取得してしまいます。

for i in driver.find_elements_by_class_name('gakkaSearchScCst__hdg'): div.append(i.text) elem = driver.find_element_by_class_name('__shi_m_heading_primary') name.append(elem.text)

とても初歩的な質問となりますが、ご教示いただけましたら幸甚です。
何卒よろしくお願い申し上げます。

matuxan👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

大学数と学科数が異なるのでそもそもpythonでの値の持たせ方自体に疑問があります。
辞書型がベストでしょう。
keyは大学名で、valueは学科名を集合型で持たせるといいと思います。

具体的には

python

1university = {'京都美術工芸大学':{'建築学科','ビジュアルデザインコース','インテリア・空間デザインコース'}, '名古屋学芸大学':{'デザイン学科'}}

といった具合です。


スクレイピングも少し変えましょう

python

1 2# 空の辞書を宣言 3university = {} 4 5while True: 6 7 for university_box in driver.find_elements_by_class_name('gpack'): 8 9 # まぎれを削除 10 if not '__shi_m_gakubu_casette_override_bdtn' in university_box.get_attribute('class'): 11 12 # 大学名を取得 13 university_name = university_box.find_element_by_tag_name('h2').text 14 15 # 学科名を取得 16 subjects = set() 17 for h4_tag in university_box.find_elements_by_tag_name('h4'): 18 subjects.add(h4_tag.text) 19 20 # 大学名と学科のペアを辞書型に追加 21 university[university_name] = subjects 22 23 # 次のページを読みにいく 24 try: 25 driver.find_element_by_link_text('次のページへ').click() 26 time.sleep(10) 27 except NoSuchElementException: 28 # 全ページ読み終わり 29 break 30 31# ここからpandas処理

これでdfに入れてみてください。
参考サイト

コメントを受けて追記

では直接URLで指定してみましょう。

URLを開いたあと次のページへを一回クリックすると
URLの最後に?pn=2とついたのがわかると思います。
これがページ番号を決めているようですね。

?pn=1でも最初のページと同じページが出てきますが、
全部で6ページしかないので、
?pn=7としてやると、検索結果がない旨を示す
赤い枠が出てくると思います。

この赤い枠が出てきたら読み込み終了としてやりましょう。

python

1# 空の辞書を宣言 2university = {} 3 4# ページカウンタ 5page_num = 0 6 7# 最初のページのURLを取得 8page_url = driver.current_url + '?pn=' 9 10while True: 11 12 # 最終ページかどうか判定 13 if len(driver.find_elements_by_class_name('dataNone')) > 0 14 break 15 16 # ページ遷移 17 page_num += 1 18 driver.get(page_url + str(page_num)) 19 time.sleep(5) 20 21 for university_box in driver.find_elements_by_class_name('gpack'): 22 23 # まぎれを削除 24 if not '__shi_m_gakubu_casette_override_bdtn' in university_box.get_attribute('class'): 25 26 # 大学名を取得 27 university_name = university_box.find_element_by_tag_name('h2').text 28 29 # 学科名を取得 30 subjects = set() 31 for h4_tag in university_box.find_elements_by_tag_name('h4'): 32 subjects.add(h4_tag.text) 33 34 # 大学名と学科のペアを辞書型に追加 35 university[university_name] = subjects 36 37# ここからpandas処理

投稿2019/11/05 16:17

編集2019/11/06 04:53
shirai

総合スコア1290

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

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

john_doe_

2019/11/06 00:51

辞書型で情報取得する方法を初めて知りました。大変勉強になります。 些細ことになりましたが、ページ遷移でElementClickInterceptedExceptionのエラーが発生しました。 driver.find_element_by_class_name('__next').click() 、に書き換えてみても同様のエラーが発生します。 driver.find_element_by_class_name('__next').click()、で次のページを各ページでクリックはできるのですが、、、、
shirai

2019/11/06 02:04

それはwhile文が何回回った時のことでしょうか。 カウンタを持たせて計測していただけないでしょうか。
john_doe_

2019/11/06 03:51

お返事ありがとうございます。2ページ目で読み込みが止まります。
shirai

2019/11/06 04:54

追記しました。
john_doe_

2019/11/06 13:59

丁寧にご教示いただきまして誠にありがとうございます。 こんなやり方があるのかと大変勉強になっております。 追記でのご質問になりますが、下記の作業で最終ページかどうかを何故判断できるのか理解できません。 # 最終ページかどうか判定 if len(driver.find_elements_by_class_name('dataNone')) > 0 break 最終ページを開いて、len(driver.find_elements_by_class_name('dataNone'))、を実行すると、 0 が返ってきました。 > 0 が成り立たないのに、何故breakと認識されるのか理解できませんでした。
shirai

2019/11/06 14:48

あなたの言う所の最終ページというのは6ページ目、?pn=6のところです。 検索結果105件に対して1ページにつき20個ずつ表示していくサイトなので 全部で6ページあるわけで、この6ページ目には「次のページへ」という ボタンは存在しません。 しかしこのプログラムではURLを直接指定して叩いているので、 仮想的に7ページに飛ぶことができます。 https://shingakunet.com/searchList/ksl_daitan/ql_ld010/qm_lc111/qs_v3660/?pn=7にアクセスしてみて下さい。 そこには赤い枠があり、そのclass属性はdataNoneとなっています。
john_doe_

2019/11/06 15:04

他のサイトでも同様の表示がされることを確認しました。 大変勉強になりました。丁寧にご教示いただき誠にありがとうございました。 参考にして活用させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問