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

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

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

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

Q&A

3回答

596閲覧

pythonで、yahooニュースの主要タイトルをスクレイピングしたい

hfjdsfh_48

総合スコア13

Python

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

0グッド

1クリップ

投稿2018/12/23 06:10

前提・実現したいこと

プログラミング初心者です。
yahooニュース(https://news.yahoo.co.jp)の主要タイトルを取り出したいのですが、うまくいきません。

書いたコード
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
import requests
from bs4 import BeautifulSoup
response=requests.get("https://news.yahoo.co.jp")
soup=BeautifulSoup(response.text,"html.parser")
topics=soup.find_all("div",class_="toptopics_cont")
for topics_title in topics:
print(topics_title.a.get_text())
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

結果
主要タイトルの一番最初のタイトルのみは取り出せました。
しかし、それ以外のしゅようは取り出せませんでした。
訂正、修正すべき点をご指摘いただければ幸いです。
よろしくお願いいたします。

該当のソースコード

ソースコード

試したこと

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

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

「class="toptopics_list" を持つ ul タグの子」で「href 属性が pickup を含む a タグ」でまず抜き出します。

href 属性が pickup を含むという条件がないと以下の記事でないリンクが入ってきてしまいます。

<a data-ylk="slk:more;" href="https://news.yahoo.co.jp/list/">もっと見る</a> <a data-ylk="slk:allpcs;" href="https://news.yahoo.co.jp/topics">全カテゴリのトピックス一覧</a>

これで抽出した a タグは以下のようになっており、<span class="icNew">NEW</span> や改行は不要なので、

<a data-ylk="slk:title;pos:1;" href="https://news.yahoo.co.jp/pickup/6307733"> 日韓協議 レーダー照射提起へ <span class="icNew">NEW</span> </a>

stripped_strings という子孫ノードのテキストを返すジェネレーターの1つ目の要素を参照することでタイトルを抜き出します。

print(list(topic.stripped_strings)) # ['日韓協議 レーダー照射提起へ', 'NEW'] print(list(topic.stripped_strings)[0]) # '日韓協議 レーダー照射提起へ'

サンプルコード

python

1import re 2from pprint import pprint 3 4topics = soup.select('ul[class="toptopics_list"] a[href*="pickup"]') 5 6titles = [] 7for topic in topics: 8 titles.append((list(topic.stripped_strings)[0], topic['href'])) 9pprint(titles)

output

1[('日韓協議 レーダー照射提起へ', 'https://news.yahoo.co.jp/pickup/6307733'), 2 ('インドネシア津波 死者60人超', 'https://news.yahoo.co.jp/pickup/6307732'), 3 ('消防隊がEV閉じ込め 3人搬送', 'https://news.yahoo.co.jp/pickup/6307727'), 4 ('通勤ライナー 裏に熾烈な競争', 'https://news.yahoo.co.jp/pickup/6307738'), 5 ('携帯への苦情 半数は店舗販売', 'https://news.yahoo.co.jp/pickup/6307729'), 6 ('競馬の「二刀流」有馬Vなるか', 'https://news.yahoo.co.jp/pickup/6307740'), 7 ('広島菊池 MLBでは打力不足?', 'https://news.yahoo.co.jp/pickup/6307731'), 8 ('宇垣アナ 闇キャラ武器に転身', 'https://news.yahoo.co.jp/pickup/6307736')]

投稿2018/12/23 06:43

tiitoi

総合スコア21956

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

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

hfjdsfh_48

2018/12/23 07:04

ご回答ありがとうございます。 頂いたコードで、うまくできました。 ただ、まだ初心者すぎて一つ一つのコードの意味を理解できていないので、勉強します。 ありがとうございました。
tiitoi

2018/12/23 07:10

スクレイピングはCSSセレクタを勉強されるとよいです。 http://www.htmq.com/csskihon/005.shtml 簡単な条件ならば find(), find_all() でもよいですが、条件が複雑の場合は CSSセレクタのほうが柔軟に指定できます。
guest

0

findで書くとこんな感じになります。
findを重ねていかないといけないのでsoupで書く方がシンプルでわかりやすいです。

python

1topics = soup.find('ul', class_='toptopics_list').find_all('a', href=re.compile('pickup')) 2 3titles = [] 4for topic in topics: 5 titles.append((topic.contents[0].strip(), topic.get('href'))) 6 7pprint(titles)

投稿2018/12/23 14:16

barobaro

総合スコア1286

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

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

0

Requests-HTMLを使った例です。

Python

1from requests_html import HTMLSession 2session = HTMLSession() 3r = session.get('https://news.yahoo.co.jp') 4topics = r.html.find('.toptopics_cont',first=False) 5for t in topics: 6 print(t.text)

投稿2018/12/23 06:31

can110

総合スコア38234

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問