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

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

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

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

Python

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

selenium

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

HTML

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

Q&A

解決済

2回答

1935閲覧

Pythonで特定なテキストが含んでいたらコメントボックスをクリックしたい

fideo

総合スコア55

Python 3.x

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

Python

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

selenium

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

HTML

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

0グッド

0クリップ

投稿2021/11/03 06:09

編集2021/11/04 11:35

seleniumとBeautifulSoupを使って、APPLE用語を含んでいる
特定のサイトへコメントをクリックしたいです。
その後はコメントする処理したいです。

下記のコードで行いましたが毎回コメントする度にコメント投稿IDが変化するので、上手くクリックされずエレメントが見つからないです。

「APPLE」という文字を含むリンクの要素を取得するためにこちらのように指定しています。

#テキストが含んでいるclass_タグを検索します found = soup.find_all(class_=['selectable msg-text-box _compile ng-scope', 'message-input-inner comment-input trigger-input ng-binding ng-scope']) print(found) [<span class="selectable msg-text-box _compile ng-scope">APPLE</span>, <div class="message-input-inner comment-input trigger-input ng-binding ng-scope" ng-click="onModeEditor()" ng-if="isWriteAbleComment" ng-switch-when="button" style="">ここにメッセージを記入 (Shift + エンター キーでテキストボックス内で改行)</div>, <span class="selectable msg-text-box _compile ng-scope">ORANGE</span>, <div class="message-input-inner comment-input trigger-input ng-binding ng-scope" ng-click="onModeEditor()" ng-if="isWriteAbleComment" ng-switch-when="button" style=""> ここにメッセージを記入 (Shift + エンターキーでテキストボックス内で改行)</div>, <span class="selectable msg-text-box _compile ng-scope">BANANA</span>, <div class="message-input-inner comment-input trigger-input ng-binding ng-scope" ng-click="onModeEditor()" ng-if="isWriteAbleComment" ng-switch-when="button" style="">ここにメッセージを記入 (Shift + エンターキーでテキストボックス内で改行)</div>, <span class="selectable msg-text-box _compile ng-scope">APPLE</span>, <div class="message-input-inner comment-input trigger-input ng-binding ng-scope" ng-click="onModeEditor()" ng-if="isWriteAbleComment" ng-switch-when="button" style="">ここにメッセージを記入 (Shift + エンターキーでテキストボックス 内で改行)</div>]

テキストボックス内でクリックしたい要素です。そのあとコメントを記載します。

[<span class="selectable msg-text-box _compile ng-scope">APPLE</span>, <div class="message-input-inner comment-input trigger-input ng-binding ng-scope" ng-click="onModeEditor()" ng-if="isWriteAbleComment" ng-switch-when="button" style="">ここにメッセージを記入 (Shift + エンター キーでテキストボックス内で改行)

CODE

# coding:utf-8 from selenium import webdriver from selenium.webdriver.common.keys import Keys import time from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.select import Select from selenium.webdriver.remote.webelement import WebElement from bs4 import BeautifulSoup #headless background option = Options() option.add_argument('--headless') #Getting Default Adapter failed error message option.add_experimental_option('excludeSwitches', ['enable-logging']) URL= "https://www.example.com/landing/jp/signin/" # ブラウザを開く。 #options=option background driver = webdriver.Chrome(executable_path="C:\Program Files\chromedriver_win32\chromedriver.exe") # Googleの検索TOP画面を開く。 driver.get(URL) #2秒待機 time.sleep(2) #login_idを入力 login_id = driver.find_element_by_name("email") login_id.send_keys("example@.com") #passwordを入力 password = driver.find_element_by_name("unknown") password.send_keys("12345") #ログインボタンをクリック login = driver.find_element_by_xpath('//*[@id="__next"]/div/div[1]/form/button') login.click() #1秒待機 time.sleep(2) #ボタンをクリック button = driver.find_element_by_xpath('/html/body/div[1]/article/div/section[2]/article/ul/li/dl/dd[1]') button.click() time.sleep(5) #他のURL指定 driver.get("https://example.com/app/#!/zoom/123456") time.sleep(10) #BeautifulSoup指定 html = driver.page_source.encode('utf-8') soup = BeautifulSoup(html, 'html.parser') #テキストが含んでいるclass_タグを検索します found = soup.find_all(class_=['selectable msg-text-box _compile ng-scope', 'message-input-inner comment-input trigger-input ng-binding ng-scope']) print(found) #top post click 特定の文字を含んでいる場合、コメントボックスをクリック toppost = driver.find_element_by_xpath(found*[contains(text(),'APPLE')]) toppost.click() # #top post click こちらだと問題なくコメントボックスクリックできるが、特定の文字がある場合クリックできません。 # toppost = driver.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/chat-panel/div/article/div[1]/div[2]/div[1]/div[3]/div/div/div') # toppost.click() # #クリック後コメントします。 # a = driver.find_element_by_xpath("/html/body/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/chat-panel/div/article/div[1]/div[2]/div[1]/div[3]/div/div/div/div[1]/form/div[2]") # a.send_keys("test")

Error code

line 73, in <module> toppost = driver.find_element_by_xpath(found*[contains(text(),'APPLE')]) NameError: name 'contains' is not defined

コメントボックスのHTMLになります。

<!-- article body START --> <div class="article-body"> <div class="article-title fn-16"> <span class="selectable">TEST4</span> </div> <!-- article-contents START --> <div class="article-contents"> <!-- 게시글 본문 --> <span class="selectable msg-text-box _compile ng-scope">APPLE</span> <!-- 게시글 본문 (끝) --> </div> <!-- article-contents END --> <div class="_compile ng-scope"> </div> <!-- article extra START --> <div class="article-extra _compile ng-scope"> <!-- unread or read count --> <!-- 아래 케이스 일 경우 1개의 클래스만 할당 1) 메시지 수신확인 : 모든 메시지 보기 설정 시 'message-read-type' 클래스 할당 / data-unread-count 어트리뷰트에 '읽음 n' 형태로 표현 2) 메시지 수신확인 : 내 메시지만 보기 설정 시 타인의 글일 경우 'card-read-count-disabled' 클래스 할당 / data-unread-count 어트리뷰트에 '읽음 n' 형태로 표현 --> <div class="msg-read-container ng-isolate-scope" message-id="1862374024" message-writer="17515244" message-count=""><span class="card-unread-count _unreadCount _showUnreadModal message-read-type" data-unread-count="" ng-class="{ &#39;card-read-count-disabled&#39;:isListBtnDisabeld, &#39;message-read-type&#39;: isReadTypeAll || (isReadTypeMine &amp;&amp; !isListBtnDisabeld), &#39;is-opened&#39;: dropdownStatus.isOpen, &#39;is-dm&#39;: isOneOnOne }" style=""></span><!-- ngIf: isListDirective --><div class="dropdown-container _messageCountDropDown ng-scope" ng-if="isListDirective" style=""><jnd-selectbox-read-unread-member-list><div><!-- ngIf: dropdownStatus.isOpen --></div></jnd-selectbox-read-unread-member-list></div><!-- end ngIf: isListDirective --></div> <!--<span class="card-unread-count card-read-count-disabled _unreadCount" data-unread-count="읽음 2"></span>--> <div class="article-action flex-fix fn-16 "> <div class="snb-menu-like _compile ng-scope"><div class="confirmable-action non-selectable _likeAction ng-isolate-scope" ng-class="{ &#39;has-like-count&#39;: message.likedCount &gt; 0, &#39;is-liked&#39;: message.isLiked }" data-id="1860359798 1860359798"><!-- ngIf: !message.likedCount --><span ng-if="!message.likedCount" class="msg-like-count-info cursor_pointer _showLikeList ng-scope" style=""><!-- <i class="icon-like"></i> --><i class="icon-ic-good"></i></span><!-- end ngIf: !message.likedCount --> <!-- ngIf: message.likedCount > 0 --> <!-- <span class="msg-button-divider"></span> --> <!-- ngIf: !message.isLiked --><span class="msg-like-button cursor_pointer _toggleMessageLike ng-scope" ng-if="!message.isLiked" like-label="いいね!" style=""></span><!-- end ngIf: !message.isLiked --> <!-- ngIf: message.isLiked --><!-- ngIf: message.likedCount > 0 --></div></div> </div> </div> <!-- article extra END --> </div> <!-- article body END --> </div> <!-- article-container END --> <div class="_compile ng-scope"> <board-comment message-id="1862374024" class="ng-isolate-scope"><!-- article-comments-container START --><!-- ngIf: comments && comments.length > 0 --></board-comment> </div> <!-- article-comments-container END --> <!-- article-comment-input-container START --> <div class="_compile ng-scope"> <div class="article-comment-input-container message-input-container _commentInputForm ng-isolate-scope" ng-show="isWriteAbleComment" post-id="1862374024" message-id="1860359798"><div class="message-input-wrapper board-comment-creator-wrap" ng-switch="" on="isEditorMode" ng-class="{&#39;focus&#39; : isEditorMode == &#39;editor&#39;}"><!-- 버튼 역활을 하며, 클릭시, 아래의 입력창을 노출 합니다. --><!-- ngSwitchWhen: button --><!-- ngIf: isWriteAbleComment --><div class="message-input-inner comment-input trigger-input ng-binding ng-scope" ng-switch-when="button" ng-if="isWriteAbleComment" ng-click="onModeEditor()" style="">ここにメッセージを記入 (Shift + エンターキーでテキストボックス内で改行)</div><!-- end ngIf: isWriteAbleComment --><!-- end ngSwitchWhen: --><!-- ngSwitchWhen: editor --></div></div> </div> <!-- article-comment-input-container END --> </div> <div id="1862224652" class="message article selectable self _message" content-type="post"> <!-- article-container START article-container 에는 게시글의 헤더 & 콘텐트 & 첨부 파일 까지 포함 --> <div id="section-post-1862224652" class="article-container _updatedData"> <!-- article hedaer START --> <div class="article-header _profileAnchor flex-row-box "> <!-- 사용자 프로필 컨테이너 (medium) --> <div class="user-profile-container size-large flex-fix _user _profileImage " data-id="17515244"> <!-- 사용자 프로필 이미지 --> <img class="img-user-profile" src="./TEST4 _ example_files/f0b6e5c90870c2fb50290fd3152b7b2a" onerror="this.onerror=null;this.src=&#39;https://cdn.example.com/app/assets/images/b4084919.profile_default_240_20180830.png&#39;" alt="user profile image"> <!-- 부재중 상태 표시 레이어 --> <div class="overlay-user-profile"> <i class="icon-svg ico-away"></i> </div> <!-- 차단된 상태 표시 레이어--> <div class="overlay-user-profile blocked"> <i class="icon-ic-block"></i> </div> </div> <div class="article-profile flex-rel ellip-1"> <div class="fn-user-name member-name selectable cursor_pointer fn-13 _profileName _user">TA bot<span class="member-state-meessage"></span></div> <div class="article-date fn-11"> <span class="ng-binding">2021/11/03 12:23</span> </div> </div>

もし分かる方がいましたら、教えていただけると幸いです。

お手数ですが、よろしくお願い致します。

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

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

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

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

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

melian

2021/11/03 06:46

XPATH の指定は文字列にする必要があります。driver.find_element_by_xpath("found*[contains(text(),'APPLE')]") また、"found*[..." という表記は XPATH としては不適合の様な気もしますが。
fideo

2021/11/03 08:37

ご回答ありがとうございます。上記のように修正しましたが、やはり上手くクリックできないです。 SyntaxError: Failed to execute 'evaluate' on 'Document': The string 'found*[contains(text(),'APPLE')]' is not a valid XPath expression.
guest

回答2

0

foundというのはBeautifulSoupのノードなので、Seleniumでは使えません。なるほど、混用するとこういう間違いも出てくるんですね。
また、XPathもでたらめです。

BeautifulSoupを使わず、

Python

1found = driver.find_element_by_xpath("//*[@class='selectable msg-text-box _compile ng-scope' or @class='message-input-inner comment-input trigger-input ng-binding ng-scope']") 2 3toppost = found.find_element_by_xpath("//*[contains(text(),'APPLE')]")

ただ、HTMLを見ると、そもそもこれでは駄目で、

Python

1found = driver.find_elements_by_xpath("//*[(@class='selectable msg-text-box _compile ng-scope' or @class='message-input-inner comment-input trigger-input ng-binding ng-scope') and contains(text(),'APPLE')]")

でしょうか。

投稿2021/11/03 10:24

編集2021/11/05 00:01
otn

総合スコア85901

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

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

fideo

2021/11/03 11:03 編集

回答ありがとうございます。 早速下記の方法で行いましたが、下記のようにSyntaxErrorが表示されます。 お手数ですが、ご確認をお願い致します。 found = driver.find_elements_by_xpath("//*[(@class='selectable msg-text-box _compile ng-scope' or @class='message-input-inner comment-input trigger-input ng-binding ng-scope') and contains(text(),'APPLE')]) ^ SyntaxError: EOL while scanning string literal
otn

2021/11/03 11:06

最後の引用符を漏らしてしまいました。
fideo

2021/11/03 11:20

早速ご確認ありがとうございます。 'APPLE')”]のように最後の引用符を使えましたが、今度は下記のエラーが表示されます。 リストをクリックできないようです。 , line 79, in <module> found.click() AttributeError: 'list' object has no attribute 'click'
otn

2021/11/03 11:22

find_elements_by_xpathの返すのはリストなので、クリックするならその要素です。
fideo

2021/11/03 12:24 編集

コメントをクリックする際のHTMLの詳細画像を追加しました。クリックするテキストボックスのクラスをrich-placeholder ng-binding ng-scopeを追加し、下記のように入れもクリックできないです。 あともう少しXpathを調整できればできると思います。 もし分かれば教えていただけるとありがたいです。 found = driver.find_elements_by_xpath("//*[(@class='selectable msg-text-box _compile ng-scope' or @class='rich-placeholder ng-binding ng-scope') and contains(text(),'APPLE')]") AttributeError: 'list' object has no attribute 'click'
otn

2021/11/03 12:36 編集

コメント見てないのでしょうか? find_elements_by_xpathの返すのはリストなので、クリックするならその要素です。
fideo

2021/11/03 12:48

失礼しました。良く意味分かっていないですが、クリックのxpathを修正する必要ありますか。
otn

2021/11/05 00:07

条件に該当するHTMLノードが複数あるのではと思って、find_elements_by_xpathにしてみたので、このメソッドが返すのは、HTML要素のリストです。 クリックするのは、「HTML要素のリスト」じゃなくて「HTML要素」です。 Pythonにおけるリストの意味が理解できていないのなら、その旨コメントください。 条件に合うノードが1つしなかいのであれば、find_elements_by_xpath じゃなくて find_element_by_xpath を使えば返すのは「HTML要素」なのでそのままクリックできます。 あと、回答やコメントが理解できない時は、無視するので無く、理解できない旨を書きましょう。
fideo

2021/11/05 04:39

ご指摘ありがとうございます。先ほどこちら解決できましたので、回答いたしました。
guest

0

自己解決

本件、下記の方法で解決できました。
毎回コメントする度にコメント投稿IDが変化するので、先ずはそのIDを取得します。
その後にID取得しましたら、XPATHへ代入しコメントをクリックできるようになりました。

Beutifulsoupを使って、コメントにAPPLE用語が含んでいたら
ID取得を行います。
こちらがCodeになります。

for i in soup.find_all(class_=['selectable msg-text-box _compile ng-scope']): if 'APPLE' in i.text:          find_id=i.parent.parent.parent.get('id').split('-')[-1] print(find_id) # 1862374024

その後にID取得しましたら、XPATHへ代入しコメントをクリックをseleniumで行います。

time.sleep(2) #top post click driver.find_element_by_xpath("//*[@id="+find_id+"]/div[3]/div").click()

投稿2021/11/05 04:38

編集2021/11/05 04:41
fideo

総合スコア55

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問