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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python

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

selenium

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

Q&A

解決済

1回答

2211閲覧

beautiful soupで特定のIDを取得したい

fideo

総合スコア55

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python

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

selenium

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

1グッド

1クリップ

投稿2021/11/04 07:52

編集2021/11/04 11:59

Pythonを使ってBeutifulSoupでチャットIDを取得したいです。
取得条件としてはチャットメッセージに”ORANGE”の用語が含んでいましたら、
ID取得したいです。

HTML

<div id="section-post-1862374024" 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="https://example-box.com/files-profile/f0b6e5c90870c2fb50290fd3152b7b2a?size=80" onerror="this.onerror=null;this.src='https://cdn.example.com/app/assets/images/b4084919.profile_default_240_20180830.png'" 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 13:28</span> </div> </div> <div class="article-action flex-fix fn-16 "> <ul class="snb-menu-group board-snb"> <li class=""> <div class="board-menu-btn"> <i class="icon-ic-more _postMore _posBottom"></i> </div> </li> <li class=""> <div class="board-menu-btn"> <i class="icon-ic-star _star _star-1860359798 off"></i> </div> </li> </ul> </div> </div> <!-- article hedaer END --> <!-- 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">ORANGE</span> <!-- 게시글 본문 (끝) --> </div> <!-- article-contents END --> <div class="_compile ng-scope"> </div>

実現したい結果

id="section-post-1862374024"もしくはpost-id="1862374024" 1862374024の数字IDを取得したいです。

下記方法で行いましたが、取得したいID何も表示されないです。

現在の結果

[]

複数条件でIDを取得する為に何を修正すれば良いでしょうか。
もし分かる方がいましたら、教えていただけると幸いです。

# 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 datetime import datetime as dt, date, timedelta import pyautogui 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']) #strDate = dt.now().strftime("%Y%m%d") 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("12131") #ログインボタンをクリック 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') time.sleep(5) # #全てのチャットIDを検索します # found = soup.find_all(id=['chat-messages']) # print(found) # #テキストが含んでいるclass_タグを検索します # found2 = soup.find_all(class_=['selectable msg-text-box _compile ng-scope']) # print(found2) foundID = soup.find_all(class_=['selectable msg-text-box _compile ng-scope'],id=['chat-messages']) print(foundID)

fondとfond2の出力結果

# #全てのチャットIDを検索します # found = soup.find_all(id=['chat-messages']) # print(found) <div class="article-comment-input-container message-input-container _commentInputForm ng-isolate-scope" message-id="1860359798" ng-show="isWriteAbleComment" post-id="1862374024"><div class="message-input-wrapper board-comment-creator-wrap" ng-class="{'focus' : isEditorMode == 'editor'}" ng-switch="" on="isEditorMode"><!-- 버튼 역활을 하며, 클릭시, 아래의 입력창을 노출 합니다. --><!-- ngSwitchWhen: button --><!-- ngIf: isWriteAbleComment --><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><!-- end ngIf: isWriteAbleComment --><!-- end ngSwitchWhen: --><!-- ngSwitchWhen: editor --></div></div> </div> # #テキストが含んでいるclass_タグを検索します # found2 = soup.find_all(class_=['selectable msg-text-box _compile ng-scope']) # print(found2) <!-- article-contents START --> <div class="article-contents"> <!-- 게시글 본문 --> <span class="selectable msg-text-box _compile ng-scope"><a href="http://example.com" rel="nofollow" target="_blank">ORANGE</a></span> <!-- 게시글 본문 (끝) --> </div> <!-- article-contents END --> <div class="_compile ng-scope"> </div>

追記
もう一つのORANGE HTMLになります。

<div id="section-post-1862223699" 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="https://example-box.com/files-profile/f0b6e5c90870c2fb50290fd3152b7b2a?size=80" onerror="this.onerror=null;this.src='https://cdn.example.com/app/assets/images/b4084919.profile_default_240_20180830.png'" 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:22</span> </div> </div> <div class="article-action flex-fix fn-16 "> <ul class="snb-menu-group board-snb"> <li class=""> <div class="board-menu-btn"> <i class="icon-ic-more _postMore _posBottom"></i> </div> </li> <li class=""> <div class="board-menu-btn"> <i class="icon-ic-star _star _star-1860206267 off"></i> </div> </li> </ul> </div> </div> <!-- article hedaer END --> <!-- article body START --> <div class="article-body"> <div class="article-title fn-16"> <span class="selectable">TEST</span> </div> <!-- article-contents START --> <div class="article-contents"> <!-- 게시글 본문 --> <span class="selectable msg-text-box _compile ng-scope">ORANGE</span>

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

SigmaDelta👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問のhtmlの構成でしたら下記で取得可能かと思います。

Python

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

【コメントを受けての追記】
最初に見つかった要素のidを取得します。

Python

1target = soup.find(class_=['selectable msg-text-box _compile ng-scope']) 2if 'ORANGE' in target.text: 3 print(target.parent.parent.parent.get('id').split('-')[-1])

投稿2021/11/04 11:14

編集2021/11/04 13:35
meg_

総合スコア10760

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

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

fideo

2021/11/04 11:44 編集

いつも回答ありがとうございます。 上記の方法で問題なくできました。 因みにORANGEの用語が2個以上があるばIDも2個以上として表示されます。 最初の1個だけ取得したい場合 find_allからfindやselectへ変更しましら下記のエラーが表示されます。 AttributeError: 'NavigableString' object has no attribute 'text' TypeError: select() missing 1 required positional argument: 'selector' もしこちらも分かれば教えていただけると幸いです。 よろしくお願い致します。
meg_

2021/11/04 11:51

>因みにORANGEの用語が2個以上があるばIDも2個以上として表示されます。 どんな状況でしょうか? htmlを追記いただければ確認できるかもしれません。
fideo

2021/11/04 12:01

早速ご確認ありがとうございます。 ORANGEの用語が2個以上がある場合、下記のように2個のIDが表示されます。 1862374024 1862223699 HTMLも追記致しました。 お手隙の際にご確認をお願い致します。
meg_

2021/11/04 12:17

> ORANGEの用語が2個以上がある場合、下記のように2個のIDが表示されます。 すみませんが状況が分かりません。 取得したいidが違っていたということですか?
fideo

2021/11/04 12:26

説明不足で申し訳ありません。 下記のようにID2つ表示される理由はOrange2回チャットへ投稿しているからです。 1862374024 最新IDの投稿 1862223699 古いIDの投稿 最新IDの1862374024だけを取得したいです。
fideo

2021/11/09 03:49 編集

ありがとうございます、上記の方法で試してみます。
fideo

2021/11/09 03:52 編集

度々、すいません。追記で質問した件ですが下記の方法で行いましたが、 printでIDが表示されないです。 もし分かれば、教えて頂けるとありがたいです。 target = soup.find(class_=['selectable msg-text-box _compile ng-scope']) if 'ORANGE' in target.text: print(target.parent.parent.parent.get('id').split('-')[-1]) FORをつけると問題なく取得できます。
meg_

2021/11/10 00:11 編集

> printでIDが表示されないです。 何が表示されましたか?エラーは発生しましたか? htmlの構成が変わると対応できなくなるのでidを取得してからテキストをチェックした方が良いかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問