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

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

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

3回答

3213閲覧

【Python 3.8.0】 cssselectで要素が取得できない 原因:JavaScript

y-oming

総合スコア7

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2019/11/22 06:53

編集2019/11/22 14:32

前提・実現したいこと

Pythonを用いてヤフオク!の送料を取得したいと思っています。
つい最近プログラミングを学び始めたため、言葉の節々におかしい点があるかもしれませんがご容赦ください。

#【HTML】

<dd class="BidModal__postageDetail" id="method0"> <div class="BidModal__postageDetail" style="background-color: white;">

"2,980円"
<span class="BidModal__postageTax">(税込み)</span>

</div>

こちらは対象ページの送料を含むHTMLの一部になります。
ページURL:
[https://page.auctions.yahoo.co.jp/jp/auction/u290078820]

CSSセレクタを用いて、送料をスクレイピングしようと思ったのですが、それがかないません。

発生している問題・エラーメッセージ

【実行結果】 IndexError: list index out of range

該当のソースコード

Souryou

1import requests 2import lxml.html 3 4URL = "https://page.auctions.yahoo.co.jp/jp/auction/u290078820" 5response = requests.get(URL) 6HTML = lxml.html.fromstring(response.text) 7SOURYOU = HTML.cssselect('#method0 > div')[0].text.strip() 8print(SOURYOU) 9

試したこと

同ページ内の即決価格"4,350円"もほぼ同じ構造でデータが収納されていたので、試しに、下記のコードを実行したところ"4,350円"は取得することができました。

【即決価格を含むHTML】

<dl class="Price__body Price__body--none"> <dt class="Price__title">即決価格

<\dt>

<dd class="Price__value">

"
4,350円"
<span class="Price__tax">(税 0 円)<\span>
<\dd>

SokketsuKakaku

1import requests 2import lxml.html 3 4URL = "https://page.auctions.yahoo.co.jp/jp/auction/u290078820" 5response = requests.get(URL) 6HTML = lxml.html.fromstring(response.text) 7 8KAKAKU = HTML.cssselect('#l-sub > div.ProductInformation > ul > li.ProductInformation__item.js-stickyNavigation-start > div > dl > dd.Price__value')[0].text.strip() 9 10print(KAKAKU)

送料と即決価格で構造がほとんど同じのため、なぜ即決価格の"4,350円"が取得でき、送料の"2,980円"だけが取得できないのかがどうしてもわかりませんでした。

お力添えよろしくお願い致します。

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

Python 3.8.0

Microsoft Windows 10
バージョン 1903

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

ページ上で「詳細」という箇所をクリックする→送料が表示される
というJavascriptの仕組みがあるせいで取得が行えないようです。

Seleniumというライブラリを使って、Google ChromeをPythonで動かしてJavascriptを実行させた後に、出現したHTMLを取得すればよいようですね。

参考ブログ:
Python Webスクレイピング テクニック集「取得できない値は無い」JavaScript対応
[https://qiita.com/Azunyan1111/items/b161b998790b1db2ff7a]

投稿2019/11/22 14:34

y-oming

総合スコア7

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

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

0

ベストアンサー

div要素のテキストですから

python

1import lxml.html 2HTML = lxml.html.fromstring("""<dd class="BidModal__postageDetail" id="method0"> 3 4<div class="BidModal__postageDetail" style="background-color: white;"> 5 6"1,280円" 7<span class="BidModal__postageTax">(税込み)</span> 8</div></dd> 9""") 10y = HTML.cssselect('#method0 > div')[0].text.strip()

でいいのでは。

plain

1>>> import lxml.html 2>>> HTML = lxml.html.fromstring("""<dd class="BidModal__postageDetail" id="method0"> 3... 4... <div class="BidModal__postageDetail" style="background-color: white;"> 5... 6... "1,280円" 7... <span class="BidModal__postageTax">(税込み)</span> 8... </div></dd> 9... """) 10>>> y = HTML.cssselect('#method0 > div')[0].text.strip() 11>>> print(y) 12"1,280円" 13>>> print(y[1:-1]) 141,280円

投稿2019/11/22 07:36

quickquip

総合スコア11231

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

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

y-oming

2019/11/22 13:36 編集

ご回答ありがとうございます。 作成していただいたコードで再度ヤフオク!のページから取得してみましたが結果は空白のリスト[]が帰ってくるだけでした。 私が質問ページに入力したHTMLだと"1,280円"がdiv要素のテキストになっていること、 そして、取得ができることを確認したのですが、同様のコードで実際のヤフオク!ページから取得すると空のリストが返却されます。 もしや自分がHTMLを読み間違えて質問をしてしまったのかと三度実際のページを確認してきたのですが、どうしても違いや原因がわかりませんでした。 ・[https://page.auctions.yahoo.co.jp/jp/auction/u290078820] こちらが問題のページになります。 検証画面でBidModal__postagePriceをXpathの検索にかけると問題の"1280円"を持つdiv要素を見つけることができると思います。 ・同ページ内の現在価格の"1円"もほぼ同じ構造でデータが収納されていたので、試しに KAKAKU = html.cssselect('#l-sub > div.ProductInformation > ul > li.ProductInformation__item.js-stickyNavigation-start > div > dl > dd.Price__value')[0].text.strip() print(KAKAKU) このコードを実行したところ"1円"は取得することができました。 送料と現在価格で構造が同じに見えるので、なにが原因で送料の"1,280円"だけ取得できないのかがわかりません。 またご助言いただけますと幸いです。 よろしくお願いいたします
quickquip

2019/11/22 12:58

これは質問に追記するべきですね
quickquip

2019/11/22 13:22

冒頭の #l-sub がないから一切ヒットしないですね。 html.cssselect('.decTxtAucPrice.Price__value')[0].text でいいんじゃ、と思いました。
y-oming

2019/11/22 13:41

申し訳ありません。 当初、提示させていただいていたペ-ジはオークションの期間が終了し、ページ全体のHTMLが変わってしまったため、現在価格が取得できない状態です。 オークションの終了していない新しいページの https://page.auctions.yahoo.co.jp/jp/auction/u290078820 で取得を行うと"4,350円"がヒットします。 ですが相変わらず送料は同様の手法で取得が行えません。
quickquip

2019/11/22 13:56

JavaScriptで差し挟まれている部分なので、htmlをparseしてもその部分にはコンテンツがないのですね。
y-oming

2019/11/22 14:08

ご返信ありがとうございます。 JavaScriptはあまり詳しくないのですが、 ページ上で「詳細」という箇所をクリックする→送料が表示される という仕組みがあるせいで取得が行えないのでしょうか。 この場合送料を取得するにはjavascriptをparseできるオブジェクトをほかに用意しなくてはならないのでしょうか。 よろしくお願いします。
y-oming

2019/11/22 14:20 編集

自分で調べてみました。 Seleniumというライブラリを使って、Google ChromeをPythonで動かしてJavascriptを実行させた後に、出現したHTMLを取得すればよいようですね。 参考ブログ: Python Webスクレイピング テクニック集「取得できない値は無い」JavaScript対応 [https://qiita.com/Azunyan1111/items/b161b998790b1db2ff7a] また知らないものが出て道のりが遠ざかりましたが、これで頑張ってみたいと思います。 ここまでヒントと助言をいただきありがとうございました。
guest

0

サンプル

python

1from selenium import webdriver 2from selenium.webdriver.chrome.options import Options 3from bs4 import BeautifulSoup 4 5options = webdriver.ChromeOptions() 6options.add_argument('--headless') 7options.add_argument('--no-sandbox') 8options.add_argument('--disable-dev-shm-usage') 9 10driver = webdriver.Chrome('chromedriver', options=options) 11driver.implicitly_wait(10) 12 13driver.get('https://page.auctions.yahoo.co.jp/jp/auction/g387158539') 14 15# クリック 16driver.find_element_by_class_name('Price__postageLink.js-modal-show.rapidnofollow').click() 17 18# 送料確認 19print(driver.find_element_by_class_name('BidModal__postagePrice').text) 20 21# 送料のみ取り出し 22html = driver.page_source.encode('utf-8') 23 24soup = BeautifulSoup(html, 'html.parser') 25 26souryou = soup.select_one("div.BidModal__postagePrice").contents[0] 27 28print(souryou) 29 30driver.quit()

seleniumで子要素を取得するのは大変そうなのでbeautifulsoupのでいいかもしれません。

How to get text of an element in Selenium WebDriver, without including child element text?
https://stackoverflow.com/questions/12325454/how-to-get-text-of-an-element-in-selenium-webdriver-without-including-child-ele

投稿2019/11/23 06:24

編集2019/11/23 08:25
barobaro

総合スコア1286

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問