プロが教えるわが家の防犯対策術!

pythonで記事の切り抜きを作っています。
BS4で、tagの属性ではない部分での検索方法は、どうしたらよいのでしょう?

reuterは、htmlでは、記事の題名が下記の形式になっています。
<a data-testid="Heading" href="***>記事題名</a>

a tag に続く data-testid="Heading" 利用したいが方法が解りません。
正規表現 <a data-testid="Heading".*?</a>
editor検索では、aタグ部分となるのでsoupでためしてみたけど、
エラーにならないが、結果は ゼロ。
soup.find_all(re.compile('<a data-testid="Heading".*?</a>'))

質問者からの補足コメント

  • うーん・・・

    titles=soup.find_all("a") とすると、全ての a tagが抽出され、
    for title in titles: #story-titleリストの要素
    print(title.text.strip())
    で、記事ヘッディングとそれ以外のもののテキストがあるものだけプリントできるが、
    記事無関係が記事同数以上。

      補足日時:2023/11/25 08:41
  • titles=soup.find_all("a",data-testid="Heading")
    だと、エラー dの部分でメッセージ下記
    expression cannot contain assignment, perhaps you meant "=="?

    類似ケースで同じ構文は機能するの、未定義でも属性として認識するようだ。
    で属性部分を1文字から一文字ずつ増やしてみたら
    - が入るとエラーになった。禁止文字なのだろうか?

      補足日時:2023/11/25 12:34
  • うれしい

    今回、いろいろやって気が付いたこと
    html で tag と attrs で指定する場合は、
    登録されている attrs の class(class_) や id などは クオーテーションで囲まず=で指定できる。
    しかし、未登録の attrs の場合は、クオーテーションで囲んで == を使う。
    attrs は辞書になっているので、辞書の指定方法の下記形式でも利用できる。
    soup.find_all(attrs={"属性(Key)" : "属性内容(value)"})

    また、 tag なしだと すべてのtagに適用される。
    soup.find_all(attrs={"key":"value"})

    No.1の回答に寄せられた補足コメントです。 補足日時:2023/11/26 09:12

A 回答 (1件)

soup.find_all(re.compile(~~~)) は、「タグ名」が指定した正規表現にマッチするかどうかです。

タグ名以外は無関係。

def f(tag):
  return tag.attrs.get("data-testid")=="Heading"
soup.find_all(f)

か、同じ事をlambdaで書いて、

soup.find_all(lambda tag: tag.attrs.get("data-testid")=="Heading")

か、

soup.select("a[data-testid='Heading']")

findやfind_allは、引数が独特で機能も少ないのに対して、select_one や selectは引数にCSSセレクターを書けるので、よく使われます。
まあ、find系も上記のように関数を引数にすれば細かく指定は出来ますが。
この回答への補足あり
    • good
    • 0
この回答へのお礼

ご教示に感謝。解決しました。
私のスキルでは、
def f(tag):
  return tag.attrs.get("data-testid")=="Heading"
soup.find_all(f)
が理解できず、いろいろ探したら 属性指定する方法があるようで、
soup.find_all(attrs={"data-testid":"Heading"})
として、貴兄推奨と同じ結果を得ることができました。
これなら、私にも理解できそう。

また、この属性は a tag だけでなく h tag などにも使われていて、
初めに 
soup.find_all("a", attrs={"data-testid":"Heading"})
だと、件数がごく少なかったので気が付いて、属性だけ指定の必要性に気が付きました。

HTMLのtagとその属性(attribute)や利用法を初めて意識するようになりました。
また、a tagを指定すると、下記でも機能することが解りました
soup.find_all("a", "data-testid"=="Heading")

この関係の解説では、例えば
https://ai-inter1.com/beautifulsoup_1/#st-toc-h-18
find_all: attrs引数
属性を辞書にして引数 attrs として値を渡しても、属性で検索することができます。辞書にはキーとして属性を、値として属性値を設定します。

例えば、以下のコードでは、辞書でid属性、属性値”link2”を渡しています。
soup.find_all(attrs={"id": "link2"})

お礼日時:2023/11/26 07:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A