2
2

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 5 years have passed since last update.

【python】簡単クローリング&スクレイピングvol.2

Posted at

前回(vol.1)よりも少しだけ複雑なものを書いてみたいと思います。前回と同じく日経電子版を対象に行います。

目標

前回は指定したカテゴリーページのはじめの1ページ分の全記事タイトルを返すだけのものでした。

今回はカテゴリー名ページ数を指定し、指定したカテゴリーの指定したページ数分の記事ジャンルがそれぞれ何件あるのかをキーが記事ジャンル、バリューが記事数の辞書型を返す関数をつくっていきます。

クローリング_2.png

上記の範囲だと、AI: 1, フィンテック: 1, コラム(テクノロジー): 1, IoT: 1, モバイル・5G: 1, 日経経済新聞: 1, 科学&新技術: 1となります 。

コード

from typing import Dict
import requests
from bs4 import BeautifulSoup
from time import sleep


def count_genre_nikkei(category: str, page: int) -> Dict[str, int]:
    """
    指定カテゴリーの指定ページ数のジャンルとその記事数を辞書型で返す関数

    :param category:記事カテゴリー
    :param page: ページ数
    :return: キー:記事カテゴリー、バリュー:記事数の辞書型
    """
    news = dict()
    base_url = 'https://www.nikkei.com/'
    base_url_2 = '/archive/'
    base_url_3 = '?bn='
    for i in range(page):
        sleep(1)
        try:
            response = requests.get('{}{}{}{}{}1'.format(base_url, category, base_url_2,
                                                         base_url_3, i))
            response.raise_for_status()

            response.encoding = response.apparent_encoding
            soup = BeautifulSoup(response.text, 'html.parser')

            # スクレイピング
            genre_list = soup.find_all('div', class_='m-miM09_keyword', reversed=False)

            for genre_1 in genre_list:
                genre_2 = genre_1.find_all('a')
                for genre_3 in genre_2:
                    genre = genre_3.text

                    if genre in news:
                        news[genre] += 1
                    else:
                        news[genre] = 1

        except requests.exceptions.HTTPError:
            print("{}カテゴリーページへのアクセス失敗".format(category))

        except Exception as e:
            print(e)

    return news

d = count_genre_nikkei("technology", 2)
for key, value in d.items():
    print('{}: {}'.format(key, value))

実行結果

コラム(テクノロジー): 3
科学&新技術: 11
IoT: 2
モバイル・5G: 4
BP速報: 6
AI: 2
シェアエコノミー: 1
フィンテック: 1

コード解説

  • try~except構文:発生した例外に応じたエラー処理ができる。try節の中でエラーが発生すると、そのエラーに対応したexcept節の処理へと移行する。
  • requests.get('url'):指定したURLに対してHTTPリクエストを送信し、サーバから返却されるHTTPレスポンスを戻り値として返す。
  • response.raise_for_status():ステータスコードが200番台以外だった場合エラーを起こす
HTTPステータスコード 意味
100番台 処理中
200番台 成功
300番台 リダイレクト
400番台 クライアントエラー
500番台 サーバーエラー
  • response.encoding = response.apparent_encoding:極力文字化けが起こらないようにコンテンツを取得できる

  • BeautifulSoup(response.text, "html.parser"):第一引数にHTML、第二引数にHTMLパーサーを指定できる。最初から使える html.parser を指定している。HTMLの字句解析をして、タグなどを判断してデータ構造として取得するプログラムをHTMLパーサーという。

  • soup.find_all():タグの子孫要素を調べてフィルタにマッチする全ての子孫要素をリスト型で返す

  • except requests.exceptions.HTTPError::ステータスコードが200番台以外だった場合のエラー時の処理

  • except Exception as e::例外の内容を知る

if genre in news:
	news[genre] += 1
else:
    news[genre] = 1

genreがすでに辞書newsに存在する場合そのバリューに1を足し、ない場合はそのgenreをキーに1をバリューとして追加

2
2
3

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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?