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

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

詳細はこちら
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

selenium

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

Q&A

解決済

2回答

1249閲覧

ウェブサイトのリンクテキストを検索し、それと同じ構造内にある数値を取得したい。

Hiroms

総合スコア17

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

selenium

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

0グッド

0クリップ

投稿2021/01/13 23:58

編集2021/01/15 00:45

前提・実現したいこと

python seleniumでウェブサイトをスクレイピングするプログラムを作成しています。
次のようなHTMLで記述されたウェブサイトの数値を取得する方法を教えてほしいです。

下記のように、<li>...</li>でくくられた項目が複数あります。
その中の「item-name」を検索し、指定した文字と同じものがあった場合、
その下の「number」の数値を取得したいです。
例:検索文字が「ABCD」の場合、「5」の数値を取得したい。

初歩的な質問かと思いますが、よろしくお願いいたします。

HTMLの例

html

1<li> 2 <div class="item-name"> 3 ABCD 4 </div> 5 <div> 6 <span class="count"> 7 <i class="number">...</i> 8 <span>5</span> 9 </span> 10 <span>...</span> 11 </div> 12</li> 13<li> 14 <div class="item-name"> 15 EFGH 16 </div> 17 <div> 18 <span class="count"> 19 <i class="number">...</i> 20 <span>9</span> 21 </span> 22 <span>...</span> 23 </div> 24</li> 25<li>...</li>

試したこと

色々調べながらテキストを検索するとこまではできましたが、その後numberの数値を探す方法がわかりません。

python

1name = "ABCD" 2link = driver.find_element_by_partial_link_text(name) 3print('itemがあります')

補足情報(FW/ツールのバージョンなど)

python3.8
selenium 3.141

追記

頂いた回答を元に作成してみましたが、エラーが出てしまいます。
なにか考えられる原因ありますでしょうか?

python

1name = "ABCD" 2number = driver.find_element_by_xpath("//div[contains(text(), name)]/following-sibling::div/span[1]/span/text()") 3print(number)

とすると、エラー「Message: invalid selector: The result of the xpath expression "//div[contains(text(), name)]/following-sibling::div/span[1]/span/text()" is: [object Text]. It should be an element.」
が出ます。

"/text()"を除いて下記のようにした場合

python

1name = "ABCD" 2number = driver.find_element_by_xpath("//div[contains(text(), name)]/following-sibling::div/span[1]/span") 3print(number)

エラーは出ず、
<selenium.webdriver.remote.webelement.WebElement (session="xxxxxx", element="xxxxxx")>
と出力されます。(xxxxは数字とアルファベットの文字列)
「It should be an element(エレメントじゃないとダメ)」ということなのですが意味がよくわかりません。
申し訳ありませんがヒントを頂けますでしょうか。

解決方法

皆様から頂いた回答をベースに、希望する動作ができました。
最終的なものを記載しておきます。

python

1name = "ABCD" 2number = driver.find_element_by_xpath("//div[contains(text(), '" + name + "')]/following-sibling::div/span[1]/span") 3print(number.text)

※検索する文字を変数(name)に入れると、[contains(text(), name)] ではうまく行かなかったため
[contains(text(), '" + name + "')] としました。

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

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

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

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

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

guest

回答2

0

ベストアンサー

XPathを使って参照するのはどうでしょうか。

python

1number = driver.find_element_by_xpath("//li/div[@class='item-name' and contains(text(), 'ABCD')]/following-sibling::div/span[1]/span/text()")

投稿2021/01/14 01:52

plasticgrammer

総合スコア629

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

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

_whitecat_22

2021/01/14 01:55 編集

これですと一文で済みますし、'ABCD'の部分を変数にすれば、for文とかで回すこともできますね。 勉強になります。
Hiroms

2021/01/14 11:29

plasticgrammer様 ありがとうございます。xpathでこういう使い方もできるのですね。試してみます。
Hiroms

2021/01/14 13:03

plasticgrammer様の回答をベースに試してみましたがエラーが出てしまっています。質問に追記しましたので、なにかわかれば教えていただけますと助かります。よろしくお願いいたします。
_whitecat_22

2021/01/15 01:15 編集

試して頂いた1つ目: 「Message: invalid selector: The result of the xpath expression "//div[contains(text(), name)]/following-sibling::div/span[1]/span/text()" is: [object Text]. It should be an element.」 ⇒ 末尾に text() を指定したことで、elementじゃないとエラーとなりました。 試して頂いた2つ目:※text() 指定を外す 取得したelementをそのままprintしたことで、<selenium.webdriver.remote.webelement.WebElement (session="xxxxxx", element="xxxxxx")> と表示されました。 ただし、elementは正常に取得できています。 そこで、以下のように、取得したelement(ここではnumberへ代入)のtextを取得するために、number.text とおきます。それをprintすることで解消できます。 number = driver.find_element_by_xpath("//div[contains(text(), name)]/following-sibling::div/span[1]/span") print(number.text)
Hiroms

2021/01/15 00:25

ありがとうございます。教えていただいた方法(print(number.text))でうまくいきました。
Hiroms

2021/01/15 00:49

最終的にこの回答をベースに、希望する動作を実現することができました。色々教えていただきましたWhitecat_22様には申し訳ありませんが、ベースとさせていただいたPlasticgramer様の回答をベストアンサーにさせていただきました。皆様ありがとうございました。
_whitecat_22

2021/01/15 01:16

Hiroms さん、どういたしまして。 少しでお役に立てたならば嬉しく思います。 今回の件では、こちらも大変勉強になりました。 ありがとうございました。
guest

0

css_selector を用いて、以下のように書くことはできます。

number という変数へ、css_selector で指定した箇所の内容を代入します。

python

1number = driver.find_element_by_css_selector('li > div:nth-child(2) > span.count > span') 2 3もしくは 4 5number = driver.find_element_by_css_selector('span.count > span')

上記例で、1つめの<li></li>内の 'ABCD' に対して、number へ '5' が代入されるかと。


<ご参考>

投稿2021/01/14 01:10

編集2021/01/14 01:22
_whitecat_22

総合スコア1305

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

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

Hiroms

2021/01/14 11:28

返信遅くなりすみません。ご回答ありがとうございます。初心者なので理解に時間がかかりますが、試してみてまた返信させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問