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

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

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

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

Python 3.x

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

Python

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

selenium

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

HTML

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

Q&A

解決済

3回答

1380閲覧

Beautifulsoupのfind_allでhtmlの中の一部分(とあるセレクタ)の中だけ検索したい

Aki1000

総合スコア78

Beautiful Soup

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

Python 3.x

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

Python

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

selenium

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

HTML

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

0グッド

0クリップ

投稿2020/11/20 16:45

編集2020/11/20 16:51

BeautifulSoupで以下のようにしてxxxxxxを含むimgタグを抽出しています。driverはseleniumです。

html = driver.page_source.encode('utf-8') soup = BeautifulSoup(html, "html.parser") elems = soup.find_all('img', alt=re.compile('xxxxxx'))

しかし、探すべき表のところ以外に余計なところにxxxxxxを含むタグがあるので、検索する範囲を絞りたいです。

なので、そのページの中のとあるセレクタとかX-Path中に含まれるxxxxxxを含むimgタグを抽出することはできるでしょうか?
セレクタかX-Pathの中身を一回抽出して、その中をfind_allする感じにできればいいのですが。
よろしくお願いします。

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

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

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

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

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

NagaseTomohiko

2020/11/21 01:29

取得対象の具体的な例を提示できませんでしょうか。
guest

回答3

0

ベストアンサー

python

1from bs4 import BeautifulSoup 2html = ''' 3<body> 4 <p class="target">DUMMY1</p> 5 <div id="wrapper"> 6 <p class="target">TARGET1</p> 7 <p class="target">TARGET2</p> 8 </div> 9 <p class="target">DUMMY2</p> 10</body> 11''' 12soup = BeautifulSoup(html, "html.parser") 13wrapper = soup.find('div', id='wrapper') 14target = wrapper.find_all('p', class_='target') 15print(target) 16# [<p class="target">TARGET1</p>, <p class="target">TARGET2</p>]

こんな感じでどうでしょうか。

投稿2020/11/21 00:17

gasbombe

総合スコア204

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

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

Aki1000

2020/11/21 01:06

idって必ず設定されてるわけではないですよね……。そして、divは探したい所以外にも、いくつもある。 目的のエリアからだけ、検索するような事ができないかな、というのが聞きたいところでして、 それで、目的の範囲をセレクタやらXPATHで指定できるんじゃないかな。出来たらいいな、と。
gasbombe

2020/11/21 01:40 編集

select()ならセレクタで指定できます。 from bs4 import BeautifulSoup html = ''' <body> <p class="target">DUMMY1</p> <div> <p class="target">TARGET1</p> <p class="target">TARGET2</p> </div> <p class="target">DUMMY2</p> </body> ''' soup = BeautifulSoup(html, 'html.parser') wrapper = soup.select('body div')[0] target = wrapper.find_all('p', class_='target') print(target) # [<p class="target">TARGET1</p>, <p class="target">TARGET2</p>]
Aki1000

2020/11/21 02:51

ありがとうございます。findばかりでselect使った事ないです。 試しにやってみました。chromeでF12押して目的の表の部分がハイライトされるtdで囲まれた部分のところで、Copy Selectorをして、出てきた物をnth-childをnth-of-typeに書き換え下の様にやってみました。 tables= soup.select'body > table > tbody > tr > td > table:nth-of-type(2) > tbody > tr > td > table:nth-of-type(3) > tbody > tr:nth-of-type(1) > td') どうにもうまくいかないです。目的の部分が入っていないし、目的外の部分が入ってくる……。chromeから抜いてくるselectorとbeautifulsoupのsoup.selectで指定するのは本当に同じなのか……。driver.find_element_by_css_selectorだと、問題なくchromeからコピーしたセレクトで目的の部分が抜き出せるのに……。 何か私のやり方が間違っているんでしょうが……。 Xpathでも試したみたいですけどねXpath指定はないんですよね。
Aki1000

2020/11/21 18:06

cssとxpathの概念をよく理解していませんでした。 cssで指定してやろうとすると、下位の必要なところにclassやらidやらが設定されていないと、その部分だけを抜き出せない。なので、私がやりたかったのはxpathで指定した部分を解析したい、なのですね。 ですが、調べてみるとBeautifulsoupでxpathを使う方法というのはpython2だとurllib2というのでパースしてlxmlというので変換してやっている人がいるのですが、python3だとできなくなっている(urllib2がpython2専用)
gasbombe

2020/11/21 18:22

質問も付いていますが、具体的な対象が不明なので何を困っているのかわかりません。 Xpathで指定できる(対象HTMLの構造がわかっている)ならBeautifulsoupでも十分できると思いますよ。
Aki1000

2020/11/21 18:39

BeautifulsoupでX-path指定はないですよね……。 cssで指定しようとするとchromeで抜き出してきたセレクタは body > table > tbody > tr > td > table:nth-of-type(2) > tbody > tr > td > table:nth-of-type(3) > tbody > tr:nth-of-type(1) > td を指定しても、うまく選択されない。 Xpathの方は、 seleniumのdriverで elems = driver.find_elements_by_xpath('目的のxpath/table') などとすればelemsに必要部分は入るので、それをbeautifulsoupに入れることが出来ればいいのですがよく分かりません。 html = driver.page_source.encode('utf-8') soup = BeautifulSoup(html, "html.parser") としている一行目のhtmlのところに、elems = driver.find_elements_by_xpath('目的のxpath/table') をページソースをutf-8でエンコードするような事が出来ればいいのですが……
gasbombe

2020/11/21 19:50

Beautifulsoupでうまく選択されないと書いていますが、少なくとも以下のコードは正常動作しますので……。 soup.select('body > table > tbody > tr > td > table:nth-of-type(2) > tbody > tr > td > table:nth-of-type(3) > tbody > tr:nth-of-type(1) > td') seleniumのほうは詳しくないですが、 soup = BeautifulSoup(html, 'lxml') ではないですか?
Aki1000

2020/11/22 07:11

なんとなくは解決しました。結局soup.selectでセレクター指定でうまくいきました。 セレクターについて、 body > table > tbody > tr > td > table:nth-of-type(2) 以下略 のtable:nth-of-type(2) の番号(2)から(1)に変えたら想定していた所がセレクトされるようになりました。 つまり、chromeからCopy Selectorでコピーしてきたセレクタの中のnth-child(2)を単純にnth-of-type(2)に置き換えるだけじゃだめだということですね。 構造自体はちゃんとちゃんと取ってこれてるんだけどnth-childの何番目かという番号はずれることがあるということなんでしょうか。 いちいち、nth-of-typeの何番目になるのか、検証しないといけないというのは不便なんですが…… chromeの目的のセレクターに含まれるnthの番号とbeautirulsoupで指定するセレクターのnth番号の法則とか分かればいいのですが。
Aki1000

2020/11/22 07:37

https://lmn-blog.com/nth-of-type01/ 人のページを貼るのもなんなんですが、ここの解説で分かりました。table:nth-child(x)とtable:nth-of-type(x)では、childの方は親構造の下のtable要素と同列のtable以外の要素全てを含む要素の何番目かを指定し、typeではtable要素のみの何番目かという指定になる。 ここで番号がずれる。 Beautifulsoupがnth-childに対応してくれるか、chromeのコピーがnth-of-typeに対応してくれれば、ぱっと指定したセレクターを選択できるのですが、そうでないかぎり検証するか、余計な同列の構造の要素の数を数えるかしないと、想定したところのセレクトが失敗することがある。 勉強になりました。
guest

0

結局soup.selectでセレクター指定でうまくいきました。
セレクターについて、

soup.select('body > table > tbody > tr > td > table:nth-of-type(2) > tbody > tr > td > table:nth-of-type(3) > tbody > tr:nth-of-type(1) > td')

などchromeからCopy Selectorでコピーしてきたセレクタの中のnth-childをnth-of-typeに置き換えたものをBeautifulsoupのセレクタ指定に使っていたのですが、これだとうまくいかなかった。想定と違うところがセレクトされているようだった。

body > table > tbody > tr > td > table:nth-of-type(2) 以下略
のtable:nth-of-type(2) の番号(2)から(1)に変えたら想定していた所がセレクトされるようになりました。
つまり、chromeからCopy Selectorでコピーしてきたセレクタの中のnth-child(2)を単純にnth-of-type(2)に置き換えるだけじゃだめだということですね。
構造自体はちゃんとちゃんと取ってこれてるんだけどnth-childの何番目かという番号はずれることがあるということなんでしょうか。
いちいち、nth-of-typeの何番目になるのか、検証しないといけないというのは不便なんですが……
chromeの目的のセレクターに含まれるnthの番号とbeautirulsoupで指定するセレクターのnth番号の法則とか分かればいいと調べていたら以下のページにたどり着きました。

https://lmn-blog.com/nth-of-type01/
人のページを貼るのもなんなんですが、ここの解説で分かりました。table:nth-child(x)とtable:nth-of-type(x)では、childの方は親構造の下のtable要素と同列のtable以外の要素全てを含む要素の何番目かを指定し、typeではtable要素のみの何番目かという指定になる。
ここで番号がずれる。
Beautifulsoupがnth-childに対応してくれるか、chromeのコピーがnth-of-typeに対応してくれれば、ぱっと指定したセレクターを選択できるのですが、そうでないかぎり検証するか、余計な同列の構造の要素の数を数えるかしないと、想定したところのセレクトが失敗することがある。
勉強になりました。

投稿2020/11/22 07:42

編集2020/11/22 07:48
Aki1000

総合スコア78

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

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

0

セレクタかX-Pathの中身を一回抽出して、その中をfind_allする感じにできればいいのですが。

まさに、お書きの通り出来ます。
まずある要素を特定して、次にその子孫要素の中だけ検索したいとう事ですよね?
そのまま書けばいいです。

投稿2020/11/21 01:41

otn

総合スコア85901

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

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

Aki1000

2020/11/21 08:17

どうしてもうまくいかない……
Aki1000

2020/11/22 07:40 編集

やりたいのはX-Pathで指定の方だと気がつきました。でもBeautifulsoupでX-path指定はない。 seleniumのdriverで elems = driver.find_elements_by_xpath('目的のxpath/table') などとすればelemsに必要部分は入るので、それをbeautifulsoupに入れることが出来ればいいのですがよく分かりません。 elemsに目的の部分が入ることはelems.textを表示させて確認はしたのですが。
otn

2020/11/22 03:02

なぜseleniumだけでやらずbeautifulsoupを併用するのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問