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

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

詳細はこちら
Python 3.x

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

selenium

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

Q&A

解決済

1回答

8404閲覧

seleniumで取得したlist型要素をテキスト変換して結合させたい

john_doe_

総合スコア354

Python 3.x

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

selenium

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

0グッド

0クリップ

投稿2019/12/01 09:40

# seleniumで要素を取得 driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article') # 取得した10個の要素をテキスト化して、結合させたい [<selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="981d9fa1-7aa7-4f03-9191-9d8424ea1f15")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="d8ab2b29-ad93-4a1e-a62c-5678e3bb3baa")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="e4d5558c-c5a6-49eb-aafa-7e1903e5061f")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="3d48e296-23b1-4ae6-9fa6-0d6718618e51")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="ca920fa7-4ee3-4044-910e-7621dbf4eb4a")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="a4d1fb42-9bec-4492-9870-50a942478784")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="b086f1eb-ffac-424e-be45-83c2a13afcba")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="5a9bd3bd-13b2-4728-aeb3-23d327902793")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="4f1abc9d-03cf-461e-84db-24bf89cfe7cd")>, <selenium.webdriver.remote.webelement.WebElement (session="c5478f098015ed3c442d6f9a2a200d5a", element="98ae5249-1dd6-4c20-b136-2fa8f51201df")>] # for文でループさせてテキスト化&加算して結合させることは可能 text = '' for i in driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article'): text += i.text

上記以外での結合方法を検討していますが、見つけられずにおります。

  • join()は文字列しか扱えない
  • map()で取得要素をstr型に変換してしまうと、テキスト化できなくなってしまう

稚拙な質問かとは存じますが、ご教示いただけましたら幸甚です。
何卒よろしくお願い申し上げます。

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

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

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

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

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

Takumiboo

2019/12/01 09:58

前の質問からですが、なぜfor文のループではいけないのかの説明が無いと、他の方も回答しづらいと思いますが。 なにか条件があるのならそれを先に提示するべきです。
guest

回答1

0

ベストアンサー

内包表記とjoinを組み合わせるといいと思います。

python

1joined_text = 'つなげる'.join([article_tag.text for article_tag in driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article')]) 2print(joined_text)

これでそれぞれのarticle要素のテキストがa,b,c,...の場合、
printの出力結果は aつなげるbつなげるcつなげる ... yつなげるz となります。
つなぎに文字を使いたくない場合は'つなげる'を''に変えてください。

コメントを受けて追記

じゃあこんな感じでどうですかね。

python

1content = [] 2for url in urls: 3 driver.get(url) 4 content.append('つなげる'.join([article_tag.text[2:-1] for article_tag in driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article')]))

内包表記を使わずに分かりやすく書くなら、

python

1content = [] 2for url in urls: 3 this_page_text = '' 4 driver.get(url) 5 for article_tag in driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article')])): 6 this_page_text += article_tag.text[2:-1] 7 content.append(this_page_text)

スライスは2:-1じゃなくて3:-2かもしれないです。
¥nが1文字として判定されるか2文字として判定されるか
やってみないとよく分からないです。


私は直接DOMを見ていないので推測で答えますが、
各article配下は

html

1<article> 2 <p>1</p> 3 <p>テキスト</p> 4 <p></p> 5</article>

あるいは

html

1<article> 21 3 テキスト 4 5</article>

といった具合に目的のテキスト以外に余計なものが何かしら加わっているのでないでしょうか。
それらをまんま繋げてやると1\nテキスト\n2\nテキスト\n3\nテキストが出てきてます。

つまり1つのarticle要素に含まれているテキストは「数字¥nテキスト¥n」の可能性が高いです。
スライスを使ってこれらを取り除きましょう。

ページ毎に微妙に異なったり、数字が2桁になるようでしたら、
大人しく正規表現で取り除いてやるといいでしょう。
以下に例を乗っけておくので考えてみてください。

ちなみにreのsubという関数は、第3引数の文字列のうち、第1引数の正規表現に当てはまる文字列を、全て第2引数に置換する関数です。

python

1import re 2 3text = 'aa10aiiiu9uu¥n¥neee¥nooo' 4print(text) # aa10aiiiu9uu¥n¥neee¥nooo 5 6new_text = re.sub('([0-9]|¥n)', '', text) 7print(new_text) # aaaiiiuuueeeooo

pythonのreにはsub以外にも様々な正規表現に関する関数が用意されているので、
気になったら調べてみてください。

投稿2019/12/01 11:53

編集2019/12/01 16:12
shirai

総合スコア1290

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

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

john_doe_

2019/12/01 12:00

article_tag.text for article_tag in driver.find_elements_〜 こんなfor文の書き方があるのですね。 プログラミングを始めて2ヶ月ぐらいなので、基礎構文を勉強したいと思います。 大変助かりました。誠にありがとうございます。
john_doe_

2019/12/01 13:10

結合箇所に謎の数字が含まれるのは何故でしたでしょうか? 出力結果: 1 テキスト 2つなぐ2 テキスト 1つなぐ3 テキスト お手すきの際で構いませんので、ご教示いただけましたら幸甚です。 何卒よろしくお願い申し上げます。
shirai

2019/12/01 13:28

↓これを実行したらどうなりますか? # for文でループさせてテキスト化&加算して結合させることは可能 text = '' for i in driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article'): text += i.text ptint(text)
john_doe_

2019/12/01 14:00

下記のようになります。 出力結果: 1\nテキスト\n2\nテキスト\n3\nテキスト 他の方よりご指摘いただいた通り、言葉足らずで恐縮でございます。 上記のテキストデータをページごとにappendすることが目的なのですが、 複数ページで実行すると、全ページのテキストデータが結合されてしまうので、 今回のご質問をさせていただいた次第です。
shirai

2019/12/01 15:27

ページごとにappendするとはどういうことですか? ['テキストテキストテキストテキスト', 'テキストテキストテキスト', 'テキストテキストテキスト'] というようにページ数と同じ長さのリスト1つが欲しいということですか?
john_doe_

2019/12/01 15:40

説明不足で申し訳ございません。上述のご認識の通りでございます。 下記で実行してしまうと、ページごとのテキスト情報がどんどん加算されてしまい、 どのように処理すべきかと検討しておりました。 urls comment = '' contents = [] for url in urls: for elem in driver.find_elements_by_class_name('wrap_box')[2].find_elements_by_tag_name('article'): contents.append(comment += elem.text)
shirai

2019/12/01 16:12

追記しました。
john_doe_

2019/12/02 00:59

遅い時間にもかかわらず、大変親切丁寧にご教示いただきまして誠にありがとうございます。 内包表記を利用しない場合の記載例も紹介いただき大変助かりました。 1番目に紹介いただいた内容で目的は達成できました。 おかげさまで一人でも、ある程度はスクレイピングを楽しめるようになり、 ご助言の数々、感謝の念に堪えません。 ご教示いただいた内容は、自己解決できずにおる私と同じような初心者の方に共有したいと考えております。 引き続き何卒よろしくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問