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

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

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

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

Python

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

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

1895閲覧

Pythonを用いて、html内からCSSセレクターを使用してキーワードを抽出する際の「nth-of-type(n)」の記述方法について

SK.12914232

総合スコア9

Beautiful Soup

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

Python

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

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/04/19 04:08

編集2020/04/19 04:09

前提・実現したいこと

Pythonを用いて、html内からCSSセレクターを使用してキーワードを抽出する。

ここに質問の内容を詳しく書いてください。
Pythonを使ったCSSセレクターの「nth-of-type(n)」での指定方法について

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

下記のようなfruits.vegetables.htmlというシンプルなhtmlがあったとします。
PythonのBeautifulSoupを用いてhtmlを解析後、
soup.select_one("li:nth-of-type(n)").string
<li>タグから該当の要素を抽出したいと考えています。

nth-of-type(4)を指定すると「オレンジ」が抽出されます。
nth-of-type(5)を指定すると、全体で上から5番目の<li>タグである、「ダイコン」が抽出されて欲しいのですが、9番目の「レンコン」が抽出されてしまう原因を知りたいです。
なお、nth-of-type(6)を指定すると下記のようなエラーメッセージが出るため、

<ul id="fr-list">内の4つを読んだ後、次の<ul id="ve-list">の<li>タグの最後にいきなり飛んでしまっているようです。
エラーメッセージ AttributeError: 'NoneType' object has no attribute 'string'

該当のソースコード

・Pythonプログラム
from bs4 import BeautifulSoup
fp = open("./fruits-vegetables.html",encoding="utf-8")
soup = BeautifulSoup(fp, "html.parser")
print(soup.select_one("li:nth-of-type(6)").string)

・上記で開いた「fruits.vegetables.html」のソースコード

<html><body> <div id="main-goods" role="page"> <h1>フルーツや野菜</h1> <ul id="fr-list"> <li class="red green" data-lo="jp">リンゴ</li> <li class="purple" data-lo="us">ブドウ</li> <li class="yellow" data-lo="us">レモン</li> <li class="yellow" data-lo="jp">オレンジ</li> </ul> <ul id="ve-list"> <li class="white green" data-lo="jp">ダイコン</li> <li class="red green" data-lo="us">パプリカ</li> <li class="black" data-lo="jp">ナス</li> <li class="black" data-lo="us">アボカド</li> <li class="white" data-lo="cn">レンコン</li> </ul> </div> <body></html>

試したこと

ここに問題に対して試したことを記載してください。
上記では

<ul id="fr-list"> と <ul id="ve-list"> の2つのul idに分かれていますが、これを1つに統合すると、nth-of-type(5)の指定でちゃんとダイコンが出てくるようになりました。恐らくul idが2つ分かれているからが原因なのだと思いますが、何故このような挙動になってしまうのかが知りたいです。 (nth-of-type(5)でエラーになるならまだ分かるのですが、何故いきなりダイコン〜アボカドを飛ばし、レンコンが出てきてしまうのか・・・) ### 補足情報(FW/ツールのバージョンなど)

特になし

よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

何故このような挙動になってしまうのかが知りたいです。

そういう仕様です。nth-of-typeは、兄弟要素の中での順番を数えるセレクタです(W3C)。

投稿2020/04/19 05:46

maisumakun

総合スコア146018

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

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

maisumakun

2020/04/19 05:47 編集

> nth-of-type(5)でエラーになるならまだ分かるのですが、何故いきなりダイコン〜アボカドを飛ばし、レンコンが出てきてしまうのか・・・ 上のulにはliが4つしかないので、「5番目」としては何もヒットしません。下のulに属する5番目のliである「レンコン」だけヒットします。
SK.12914232

2020/04/19 06:38

ご回答、ありがとうございました。 2つ目にいただいたアンサーでハッとして、疑問点が完全に解決しました。兄弟要素の中での順番を数えるセレクタであるのは理解していたのですが、5番目に指定すると上のulには5番目がそもそも存在しないので、(内部的)下のulから拾ってくれる仕様になっているので、どう頑張ってもこの記述方法では「ダイコン」は出てこないということなのですね。 print(soup.select_one("#ve-list > li:nth-of-type(1)").string)と指定してあげたところ、ちゃんとダイコンが出てきました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問