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

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

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

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

selenium

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

Q&A

解決済

3回答

588閲覧

【selenium】class属性値を抽出したい

cheriraoka

総合スコア42

Python 3.x

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

selenium

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

0グッド

0クリップ

投稿2023/05/12 15:29

編集2023/05/13 08:07

実現したいこと

いつもお世話になっております。

画像の赤枠で囲ったclass属性値である「Type Type04」を抽出したいのですが、うまくできません。

イメージ説明

試したコード

url = 'https://race.netkeiba.com/race/newspaper.html?race_id=202305020504&rf=shutuba_submenu' browser.implicitly_wait(3) browser.get(url) dataindex_list = ["//*[@data-index='{}']".format(i) \ for i in range(len(browser.find_elements(By.CSS_SELECTOR, "dl.HorseList")))]#各レースにおける頭数 list_1 = [] list_2 = [] list_3 = [] list_4 = [] for dataindex in dataindex_list: #horse_idを抽出 elem_urls = [] elem = browser.find_element(By.XPATH, dataindex) elems = elem.find_elements(By.CLASS_NAME, 'Horse02') for elem in elems: elem_urls.append(elem.find_element(By.TAG_NAME, 'a').get_attribute('href')) horse_id = [] for elem_url in elem_urls: elem_url = re.findall(r'\d+', elem_url) horse_id.append(elem_url[0]) elem = browser.find_element(By.XPATH, dataindex) horse_id = horse_id * len(elem.find_elements(By.CLASS_NAME, 'Data01')) #前走の数だけhorse_idを取得 list_1.extend(horse_id) #馬が走ったrace_idを抽出 elem = browser.find_element(By.XPATH, dataindex) elems = elem.find_elements(By.CSS_SELECTOR, "span.RaceName") elem_urls = [] for elem in elems: elem_urls.append(elem.find_element(By.TAG_NAME, 'a').get_attribute('href')) race_id_list = [] for elem_url in elem_urls: elem_url = re.findall(r'\d+', elem_url) race_id_list.append(elem_url[0]) list_2.extend(race_id_list) #前半3Fタイムを抽出 elem = browser.find_element(By.XPATH, dataindex) elems = elem.find_elements(By.CSS_SELECTOR, "span.Data19") row = [] for elem in elems: text = elem.text text = re.findall(r'\d+\.\d+', text) text = "".join(text) row.append(text) list_3.extend(row) #脚質をスクリーニング elem = browser.find_element(By.XPATH, dataindex) elems = elem.find_elements(By.CSS_SELECTOR, '.Horse06.fc') div_class = [] for elem in elems: div_class = elem.find_element(By.CSS_SELECTOR, 'div.Type').get_attribute('class') div_class = div_class[-1] #Type Type01だったら1のみ抽出 list_4.extend(div_class) list_4 = [list_4[0]] * len(list_1) df = pd.DataFrame() df['horse_id'] = list_1 df['race_id'] = list_2 df['前半'] = list_3 df['脚質'] = list_4

上のコードで試しました。しかし、horse_id毎に1~4の脚質にしたいのですが、脚質がすべて同じになってしまいます(画像参照)。
イメージ説明

htmlについて

<dl class="HorseList" data-index="0" id="past_tr_8">  <dt class="Horse_Info orderfix" style="width: 179.52px;">   <dl class="fc">    <dt class="Horse06 fc">     <div class="Type Type01">      ::after     </div>

htmlについては上のような感じですhttps://race.netkeiba.com/race/newspaper.html?race_id=202305020412 の左側にある馬名欄にある◀印のものを抽出したいです。
dl classのdata-indexは馬名毎に番号が変わり、div classのTypeは◀の位置によってType01~04が付与させています。

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

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

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

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

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

guest

回答3

0

いろいろとコードをいじってたら、やりたいことができました!
コメントいただいたお二人に感謝申し上げます。

投稿2023/05/13 13:49

cheriraoka

総合スコア42

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

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

0

ベストアンサー

クラスが Horse06 fc である要素の配下にある、クラスが Type Type04 である div要素を取得するのは下記の様なコードでできるかと思います。

elem_urls = [] elems = driver.find_elements(By.CSS_SELECTOR, '.Horse06.fc') for elem in elems: type04 = elem.find_elements(By.CSS_SELECTOR, 'div.Type.Type04') if len(type04) > 0: elem_urls.append(type04)

投稿2023/05/12 16:17

編集2023/05/13 04:22
meg_

総合スコア10602

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

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

cheriraoka

2023/05/13 01:48

回答ありがとうございます。 いただいたコードを基に下記のコードを試しましたがエラーが出てしまいました。elemsまではきちんとできているようですが、クラスが Horse06 fc である要素の中には、Type04だけでなくType01~03の属性もあるため抽出できていないからだと思っていますが、for文で回せばいけますか。お知恵を貸していただけるとありがたいです。 elem_urls = [] elems = browser.find_elements(By.CSS_SELECTOR, '.Horse06.fc') for elem in elems: elem_urls.append(elem.find_element(By.CSS_SELECTOR, 'div.Type.Type04'))
meg_

2023/05/13 02:28

htmlをテキストで質問に追記いただければ検証できるかと思います。
cheriraoka

2023/05/13 03:18

htmlをテキストで追記しました。不足あればご指摘ください。何卒よろしくお願い申し上げます。
cheriraoka

2023/05/13 08:09

回答ありがとうございます。いただいたコードを参考に、質問の「試したコード」に記載したコードで試しましたが、うまくいきませんでした。 horse_id毎に別の脚質にしたいのですが、脚質がすべて同じになってしまいます(質問の画像参照)。
meg_

2023/05/13 08:19

> いただいたコードを基に下記のコードを試しましたがエラーが出てしまいました。 エラーについては解消されたのでしょうか? > horse_id毎に別の脚質にしたいのですが、脚質がすべて同じになってしまいます(質問の画像参照)。 これはスクレイピングの問題でしょうか?スクレイピングでの値の取得自体は出来ているのでしょうか?そこからおかしいのでしょうか?問題の切り分けをした方が良いかと思います。
cheriraoka

2023/05/13 09:40

エラーについては解消しました。 div_class = [ ]で定義したリストに入ってくる値が同じであること、list_1~3に入る数は同じであるのに脚質が最終的に入るlist_4だけ数が異なることから、スクレイピングの問題と思っています。
meg_

2023/05/13 09:47

> list_4 = [list_4[0]] * len(list_1) 上記コードの処理は意図通りになっていますか?
cheriraoka

2023/05/13 10:08

コードの最後でlist_1~4をそれぞれデータフレームに入れる際に、list_4のみ、list_1~3と長さが違ったので無理やりこちらの処理をしました。ただ、後で考えましたが、list_4の長さが他と違う時点でうまくlist_4のスクレイピングができていないと気づきました。
meg_

2023/05/13 11:39

"脚質"の情報はそもそも必ず存在するものなのでしょうか?(そのサイト(ページ)の構成上の話です)
meg_

2023/05/13 13:05

> コードの最後でlist_1~4をそれぞれデータフレームに入れる際に、list_4のみ、list_1~3と長さが違ったので無理やりこちらの処理をしました。 どこでリストの長さが合わなくなってしまったのかデバッグする必要があるかと思います。最初の質問内容と異なってきたようですので問題を整理して別の質問を建てられた方が良いかもしれません。
cheriraoka

2023/05/13 13:12

ありがとうございます。いったんこちらはクローズして、整理でき次第再度質問させていただきます。
guest

0

画像の赤枠で囲ったclass属性値である「Type Type04」を抽出したいのですが、うまくできません。

とお書きですが、コードをみると、属性値を抽出したいのではなくて、属性値を指定して要素を抽出したいと言うことでしょうかね?

class属性が複数ある場合は、CSSセレクターの書き方としてはピリオドでつないで書きます。
find_element(By.CSS_SELECTOR, 'div.Type.Type04'))

'div.Type Type04'と書くと、Type04はタグ名と解釈されます。div.Typeの子孫のType04タグですね。そんなタグはそこに無いと思いますが。

コメントを見ての追記

コメントの前半がよくわかりませんが、.Horse06.fcの下に、div.Typeの要素が必ずただ1つだけあるが、その要素のclass属性を調べたいと言うことですかね?
であれば、

Javascript

1elems = browser.find_elements(By.CLASS_NAME, 'Horse06 fc') 2for elem in elems: 3 div_class = elem.find_element(By.CSS_SELECTOR, 'div.Type').get_attribute('class') 4 div_class に "Type Type01" のような文字列が入るので、 5 2つ目のクラス名を取りたければ、div_class.split()[1] とかで分離して、 6 それを使ってやりたい処理をする

投稿2023/05/12 15:57

編集2023/05/13 04:05
otn

総合スコア84663

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

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

cheriraoka

2023/05/13 01:45

回答ありがとうございます。やりたいこととしては、上の画像で「div.Type.Type04」と表示されている◀を抽出したいと思っています。しかし、この◀は4マスのうち、どこに入るかによって「div.Type.Type01~div.Type.Type04」で分かれるため、◀の位置によって01~04という数字で抽出できないかと考えていました。 タグで囲まれている箇所は「::after」になっており、抽出が難しいと考えたためこのように考えていました。 いただいたコードを基に下記のコードを試しましたがエラーが出てしまいました。elemsまではきちんとできているようですが、Type04だけでなくType01~03の属性もあるため抽出できていないと考えているのですが、いかがでしょうか。 elem_urls = [] elems = browser.find_elements(By.CSS_SELECTOR, '.Horse06.fc') for elem in elems: elem_urls.append(elem.find_element(By.CSS_SELECTOR, 'div.Type.Type04'))
otn

2023/05/13 03:50 編集

まず、「エラーが出てしまいました」と書かれてもエラーメッセージが残ってないのでは、コメントのしようが無いです。エラーメッセージは失うくことなく必ず確保しましょう。 あとはコードがあるので、回答に追記しておきます。
cheriraoka

2023/05/13 08:15

回答ありがとうございます。回答のコードを参考に、質問の「試したコード」に記載したコードで試しましたが、うまくいきませんでした。 horse_id毎に別の脚質にしたいのですが、脚質がすべて同じになってしまいます(質問の画像参照)。 回答いただいたコードは「試したコード」に記載したコードのうち、「#脚質をスクリーニング」という箇所に記載しました。horse_id毎にrace_idと前半はうまくスクレイピングできているのに、脚質だけ同じになる原因がわかりません。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問