0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonプログラミング:BeautifulSoup4を使ってlivedoor NEWSから今日のニュースを取得(スクレイピング)してみた

Last updated at Posted at 2021-10-07

はじめに

前回記事に続き、データ収集に関する投稿です。

  1. ニュースアクセスランキング編
  2. 今日のニュース編 ★本稿
  3. 話題のニュース編
  4. キーワード検索結果のニュース編

今回は、今日のニュースが対象です。
というわけで、Pythonプログラムで取得(スクレイピング)する処理を実現してみようと思います。

※本稿執筆時点(2021/10/07)の情報に基づき、Code紹介と実行例を示します。

本稿で紹介すること

  • 今日のニュース(livedoor NEWS)の取得

尚、筆者は以下のVersionで動作確認をしています。

  • Python: 3.6.10
  • BeautifulSoup4: 4.9.3

本稿で紹介しないこと

  • Pythonライブラリのインストール方法および使い方
    • urllib.request
    • BeautifulSoup4
    • re
    • pandas
    • csv
    • traceback
    • os

サンプルコード

Code量も多くないので、全体のCodeを紹介。
ポイントは3つ。

1. User-Agentの設定

HTTPリクエストヘッダーにUserAgentを設定するのがベター。
自宅PC(個人環境)なので不要ですが、会社PC(企業環境)であればProxyの設定も同じようにヘッダーに設定するのがベター。

2. 名前付きグループの正規表現

後々、ニュースIDをKeyに記事全文を取得することも視野に、ニュースIDも抽出しておくのがベター。

3. タグ要素の指定

各ページSourceを眺めて、タグ構成を鑑みて要素を指定し、BeautifulSoup4で情報を取得する必要あり。
多くの場合、タグに付与されたclass属性を指定し、目的のタグ(およびその内部のText)を取得する処理を実装することになります。
WebブラウザでページのSourceを眺めて、HTMLタグの構造を把握するのは簡単です。

Codeを紹介

以下、全体のCodeです。

from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
import re
import pandas as pd
import csv
import traceback
import os

# 保管先フォルダの名称
OUTPUT_DIR = 'livedoor_news'
# 今日のニュース(ライブドアニュース)のURL
URL = 'https://news.livedoor.com/straight_news/'
# ニュースID抽出用の正規表現(名前付きグループ)
REG_URL = r'(?P<L1>(https?://[^/]+/))(?P<L2>([^/]+))/(?P<L3>([^/]+))/(?P<L4>([^/]+))/'
# UserAgent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36'

def create_folder():
    if not os.path.exists(OUTPUT_DIR):
        # フォルダが存在しなければ、フォルダを作成
        os.makedirs(OUTPUT_DIR)

def get_links():
    try:
        # HTTPリクエストヘッダーにUser Agentを設定
        req = Request(URL, data=None, headers={'User-Agent': USER_AGENT})
        with urlopen(req) as res:
            # HTMLドキュメントからBeautifulSoupを初期化
            soup = BeautifulSoup(res.read().decode('euc_jp', 'ignore'), 'html.parser')
            # 今日のニュース部分を検索し、全てを取得
            soupNewsStraight = soup.find('ul', class_='straightList').find_all('li')

            articles = []
            for idx, soupNews in enumerate(soupNewsStraight):
                # 詳細ページURLをHTMLタグの属性から抽出
                url = soupNews.a.get('href')
                # NewsBodyを検索し取得
                soupNewsBody = soupNews.find('div', class_='straightBody')
                # NewsBodyから各種データを抽出
                article = {
                    'url': url,
                    # ニュースIDを詳細ページURLから抽出
                    'id': re.search(REG_URL, url).groupdict()['L4'],
                    # タイトル/サマリ/提供元/公開日時をHTMLタグの本文から抽出
                    'title': soupNewsBody.find('h3', class_='straightTtl').text,
                    'summary': soupNewsBody.find('p', class_='straightSummary').text,
                    'vender': soupNewsBody.find('p', class_='straightVender').text,
                    'datetime': soupNews.a.time.get('datetime')
                }
                articles.append(article)
                print('%2d: %s' %(idx + 1, soupNewsBody.find('h3', class_='straightTtl').text))

            df = pd.DataFrame(articles)
            # DataFrameからCSVファイルを生成
            # encoding='sjis'だとJupyterLab(CSVTable)上で表示不可なことに注意
            df.to_csv('%s/livedoor_news_straight.csv' %OUTPUT_DIR, encoding='utf-8', index=False, quotechar='"', quoting=csv.QUOTE_ALL)
    except Exception as e:
        # エラー概要
        print('Exception: ', e)
        print('=====')
        # エラー詳細(スタックトレース)
        print(traceback.format_exc().rstrip())
        print('=====')

正常に実行できると、以下のようになります。
実行例.png

まとめ

BeautifulSoup4を使って今日のニュースを取得(スクレイピング)する方法を紹介。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?