Newspaper3kでニュースサイトの記事を簡単スクレイピング

スポンサーリンク
データ解析
スポンサーリンク

PythonのライブラリNewspaper3kを使ってニュースサイトの記事を巡回して収集する方法をまとめます。これを使えば、いろいろなサイトの記事を巡回して取得することができます。法律などのの範囲内で楽しくスクレイピングを使いましょう。

eye-catching image by Krzysztof Pluta in Pixabay

ニュースサイトのスクレイピングの注意点

最初にスクレイピングについての法律的な観点からの注意事項です。webスクレイピングは私的の限られた範囲内で行うだけなら問題ありませんが、二次利用等では著作権法やその他、法律に違反する可能性がありますので、法律を遵守して行いましょう。また、大量のデータのダウンロードはサーバーに過度な負荷をかけ、相手の業務に影響を与えた場合は損害賠償を請求をさせる恐れがありますので、スクレイピングは常識的な範囲内で行うようにしましょう。

以下、参考サイトです。
スクレイピングとは?違法性があるデータの活用方法とその対処を解説(ココナラ法律相談)
スクレイピングは違法?Webスクレイピングに関する10のよくある誤解!(Octoparseのwebサイト)
【Webスクレイピング】違法にならないサービスパターン5選(PigDataのWebサイト)
著作権法(e-gov法令検索)

newspaper3k

newspaper3k公式ドキュメント(pypi.org英語サイト)

インストール

newspaper3kのライブラリのインストールはコマンドラインからpipコマンド等で行います。

pip install newspaper3k

Successfully built tinysegmenter feedfinder2 jieba3k sgmllib3k
Installing collected packages: tinysegmenter, sgmllib3k, jieba3k, lxml, filelock, feedparser, 
cssselect, requests-file, feedfinder2, tldextract, newspaper3k
Successfully installed cssselect-1.1.0 feedfinder2-0.0.4 feedparser-6.0.10 filelock-3.7.1 
jieba3k-0.35.1 lxml-4.9.1 newspaper3k-0.2.8 requests-file-1.5.1 sgmllib3k-1.0.0 
tinysegmenter-0.3 tldextract-3.3.1

URLを指定して記事を取得する

記事の取得はnewspaperのArticleに記事のURLを引数と渡すことで準備できます。今回はCNNからスターバックスのトイレに関する記事を取ってきます。入力はjupyter labのインタラクティブ開発環境を使用します。

from newspaper import Article
URL = "https://edition.cnn.com/2022/07/21/business/nightcap-starbucks-bathroom-netflix/index.html"
article = Article(URL)

続いて記事のダウンロードをします。

article.download()

記事を解析します。

article.parse()

タイトルを取得します。

title = article.title
print(title)
Don't let Starbucks take away our public bathroom

CNNの記事内容を取得します。

text = article.text
print(text)
This story is part of CNN Business' Nightcap newsletter. (以下略/記事の本文全文が出力される)

トップイメージのURLを取得します。

image_url = article.top_image
print(image_url)
https://cdn.cnn.com/cnnnext/dam/assets/220721174156-starbucks-bathroom-file-restricted-super-tease.jpg

記事の掲載された日付を取得します。

date = article.publish_date
print(date)
2022-07-21 00:00:00

その他のメタ情報を一括して辞書型として取得します。

meta_data = article.meta_data
defaultdict(dict,
            {'viewport': 'width=device-width, initial-scale=1.0, minimum-scale=1.0',
             'section': 'business',
             'referrer': 'unsafe-url',
             'og': {'pubdate': '2022-07-22T01:00:01Z',
              'url': 'https://www.cnn.com/2022/07/21/business/nightcap-starbucks-bathroom-netflix/index.html',
              'title': "Analysis: Don't let Starbucks take away our public bathroom",
              'description': 'One of the ultimate examples of "corporate solutions for government problems" is the Starbucks bathroom.',
              'site_name': 'CNN',
              'type': 'article',
              'image': {'identifier': 'https://cdn.cnn.com/cnnnext/dam/assets/220721174156-starbucks-bathroom-file-restricted-super-tease.jpg',
               'width': 1100,
               'height': 619}},
             'pubdate': '2022-07-22T01:00:01Z',
             'lastmod': '2022-07-22T01:00:01Z',
             'author': 'Analysis by Allison Morrow, CNN Business',
             'twitter': {'title': "Analysis: Don't let Starbucks take away our public bathroom",
              'description': 'One of the ultimate examples of "corporate solutions for government problems" is the Starbucks bathroom.',
              'card': 'summary_large_image',
              'image': 'https://cdn.cnn.com/cnnnext/dam/assets/220721174156-starbucks-bathroom-file-restricted-super-tease.jpg'},
             'description': 'One of the ultimate examples of "corporate solutions for government problems" is the Starbucks bathroom.',
             'keywords': "business, Don't let Starbucks take away our public bathroom  - CNN",
             'thumbnail': 'https://cdn.cnn.com/cnnnext/dam/assets/220721174156-starbucks-bathroom-file-restricted-super-tease.jpg',
             'vr': {'canonical': 'https://edition.cnn.com/2022/07/21/business/nightcap-starbucks-bathroom-netflix/index.html'},
             'article': {'opinion': 'false', 'content-tier': 'free'},
             'fb': {'app_id': 80401312489, 'pages': '5550296508,18793419640'},
             'template-top': 'business,bra-nightcap,art-vid'})

ページから一括して記事取得

newspaper.buildで指定されたURLからHTMLデータを取得し、記事をダウンロードする準備をしてくれます。

import newspaper
URL = "https://edition.cnn.com/"
cnn_paper =newspaper.build(URL, memoize_articles=False)

確認してみます。

print(len(cnn_paper.articles))
525

525個のニュース記事の取得準備ができました。これを一気にダウンロードするとダウンロード先のhtmlサーバーに負荷をかけてしまい迷惑をかけてしまいます。また、こちらがロボットによる取得だと思われると、こちらのリクエストが遮断されてしまう可能性もありますので、ここでは、人がwebを閲覧すると同じくらいの速度で5~7秒に1回くらいのペースで、リクエストを送って記事をダウンロードするようにします。また、今回は、テストなので、最初の10記事のみを取得します。

待ち時間はランダムで取得して、およそ1分ほどかけてダウンロードするようにせってしています。
また、ダウンロードした結果はarticle_dataに保管して後から取り出せるようにします。

import time
import random

i = 0
article_data = []
print("Now downloading  ", end="")
while i < 10:
    wait_time = random.uniform(5,7)
    print("--",end="")
    article = cnn_paper.articles[i]
    article.download()
    article.parse()
    article_data.append(article)
    
    time.sleep(wait_time)
    
    i += 1

print("-->OK")
Now downloading  ---------------------->OK

では、記事の中身を見ていきます。今回は、ダウンロードした各記事のタイトルとURL、テキストの最初の150文字、総文字数を出力します。

for article in article_data:
    
    print(article.title)
    print(article.url)
    print(article.text[0:150]+"....")
    print("文字数:{}字".format(len(article.text)))
    print()

最初の方に記事ではないヘッドラインが3個ほど入っていますが、合計7個の記事を取得できています。ダウンロードした記事を自分用にスクラップしたり、解析するデータして用いたりできそうです。

コメント