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

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

新規登録して質問してみよう
ただいま回答率
85.35%
スクレイピング

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

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

Python

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

selenium

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

Q&A

解決済

1回答

1329閲覧

Pythonスクレイピング:urlリストからfor文を回す際のエラーについて

gomasan

総合スコア96

スクレイピング

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

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

Python

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

selenium

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

0グッド

1クリップ

投稿2020/08/24 02:53

編集2020/08/24 03:03

前提

Pythonを使ってスクレイピングを行っています。
ライブラリ:selenium
概要:ふるさと納税サイトの口コミ集計

実現したいこと

最終ゴール:自治体毎に口コミ集計を行う

【想定している流れ】
①自治体ページから各商品のリンクを一覧で抽出
②①で抽出したリンクをbrowser.get(url)して各商品でそれぞれ口コミ集計処理を行う

現状ゴール:商品毎のページに行って、商品のタイトルを取得、一覧でprint抽出

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

Traceback (most recent call last): File "/Users/xxx/Desktop/紋別市/choice/choice.py", line 27, in <module> link_title = browser.find_element_by_class_name('ttl-h1__text inline') File "/Users/xxx/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 564, in find_element_by_class_name return self.find_element(by=By.CLASS_NAME, value=name) File "/Users/xxx/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element 'value': value})['value'] File "/Users/xxx/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/Users/xxx/anaconda3/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".ttl-h1__text inline"} (Session info: chrome=84.0.4147.135)

該当のソースコード

python

1from selenium import webdriver 2import time 3import csv 4import datetime 5 6# ブラウザを開く 7browser = webdriver.Chrome() 8# URLを開く 9url = "https://www.furusato-tax.jp/city/product/01219/0" 10browser.get(url) 11 12# citygoods_goods = 「紋別市の全てのお礼の品」←ここから抽出していく 13elems_item = browser.find_element_by_class_name('citygoods_goods') 14# citygoods_goods の中の各商品ごと 15elems = elems_item.find_elements_by_class_name('card-product') 16 17# ①各商品ごとのリンクをリストで抽出 18# ②で抽出したリストをfor文で回して一つずつurlを見に行って集計処理をする 19product_link = [] 20title = [] 21for elem in elems: 22 elem_product_link = elem.find_element_by_class_name('card-product__link') 23 product_link.append(elem_product_link.get_attribute('href')) 24 for link in product_link: 25 browser.get(link) 26 time.sleep(1.0) 27 link_title = browser.find_element_by_class_name('ttl-h1__text inline') 28 print(link_title) 29 30browser.close()

エラーとなっている箇所

python

1link_title = browser.find_element_by_class_name('ttl-h1__text inline')

原因が分からず...
ご教示いただけますと幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

find_element_by_class_nameではそもそも複数の要素の指定ができません。
どうしてもという場合、find_elements_by_css_selectorを使うなどして複数指定しましょう。
ただしfind_elements_by_css_selectorは配列が返りますので、
内部要素を使いたい場合[0]を使ってアクセスする必要があります。

python

1・・・ 2# ①各商品ごとのリンクをリストで抽出 3# ②で抽出したリストをfor文で回して一つずつurlを見に行って集計処理をする 4product_link = [] 5title = [] 6for elem in elems: 7 elem_product_link = elem.find_element_by_class_name('card-product__link') 8 product_link.append(elem_product_link.get_attribute('href')) 9 for link in product_link: 10 browser.get(link) 11 time.sleep(1.0) 12 link_title = browser.find_elements_by_css_selector('.ttl-h1__text.inline') 13 print(link_title[0]) 14・・・

追記
そこは質問のエラー部分とは関係ありません。
elemが親ページのエレメントであるにも関わらず、下のbrowser.getで別ページに遷移してから、
再度elemから要素を取得しようとするとオブジェクトの内容が変わってしまっているためそのエラーになります。
ページ遷移する前にelemsから得られるhrefの内容をリストに全て格納してしまってからそれをループ処理した方がいいですね。
このソースで指定されているclassにある商品名?を取得することができます。

python

1title = [] 2product_link = [pl.get_attribute('href') for pl in [elem.find_element_by_class_name('card-product__link') for elem in elems]] 3for link in product_link: 4 browser.get(link) 5 time.sleep(1.0) 6 link_title = browser.find_elements_by_css_selector('.ttl-h1__text.inline') 7 print(link_title[0].text)

投稿2020/08/24 04:48

編集2020/08/24 06:45
yureighost

総合スコア2183

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

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

gomasan

2020/08/24 06:19

ご回答くださりありがとうございます。 教えていただいた通りにやってみたのですが、以下の通りエラーとなります。 ``` selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=84.0.4147.135) ``` エラーの箇所は、 ``` elem_product_link = elem.find_element_by_class_name('card-product__link') ``` です。こちらは又違うエラーなのでしょうか..?
gomasan

2020/08/24 07:35

> elemが親ページのエレメントであるにも関わらず、下のbrowser.getで別ページに遷移してから、 >再度elemから要素を取得しようとするとオブジェクトの内容が変わってしまっているためそのエラーになり >ます。 >ページ遷移する前にelemsから得られるhrefの内容をリストに全て格納してしまってからそれをループ処理 >した方がいいですね。 →やっと根本的な考え方の間違いに気がつきました。確かにそうですね...教えていただいた通り実行し、無事に商品名をリストでとってくることができました。エラーの原因もやっと理解することができました。本当にありがとうございます...!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問