Python で Web スクレイピング

Web スクレイピングとは

スクレイピングとは、web ページから情報を抽出することを言います。取得した情報は、エクセルなどにまとめて利用することができます。…(中略)…
Python を使えば、web ページをスクレイピングし、データを自動で取ってくることができます。一度 Python で自動化してしまえば、後はプログラムが勝手に情報を取ってきてくれるようになり、大幅に作業が効率化できます。このように自動的に web ページの情報を取ってくることをスクレイピングと言います。

出典:Tech Teacher

実行例

Yahoo ニュースのタイトルとリンクを取得する例です。
赤枠の部分が取得対象です。

次のコードを実行します。

import time
import requests
from bs4 import BeautifulSoup

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
result = requests.get('https://news.yahoo.co.jp/', headers=headers)
try:
    result.raise_for_status()
except Exception as exc:
    print('URLの取得に失敗しました。:{}'.format(exc))

soup = BeautifulSoup(result.text, 'lxml') 
elems = soup.select('.sc-hCbubC li a') 

for elem in elems: 
    time.sleep(1) 
    title = elem.getText()
    link = elem.get('href')
    print(title, '({})'.format(link)) 

出力結果は次のとおりです。

東京 新たに430人の感染確認 (https://news.yahoo.co.jp/pickup/6388981)
空き教室 わいせつ行為が多発 (https://news.yahoo.co.jp/pickup/6388982)
ミャンマー クーデター正当化 (https://news.yahoo.co.jp/pickup/6388975)
18歳刺殺 車に注意し口論か (https://news.yahoo.co.jp/pickup/6388974)
聖火リレー初の週末 密集警戒 (https://news.yahoo.co.jp/pickup/6388969)
半世紀 多摩ニュータウンは今 (https://news.yahoo.co.jp/pickup/6388976)
速報 常総学院vs.中京大中京 (https://news.yahoo.co.jp/pickup/6388979)
東海大菅生がサヨナラ 初8強 (https://news.yahoo.co.jp/pickup/6388978)

解説

User-Agent の設定
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}

User-Agent は主にブラウザの情報で、User-Agent を設定しない場合、「Python-urllib」といった値になります。この場合、サイトによっては、スクリプトからのアクセスを禁止するために別の HTML を返すことがあります。

Web ページのダウンロード

Web ページをダウンロードし、result に格納します。

result = requests.get('https://news.yahoo.co.jp/', headers=headers)
Web ページを HTML テキスト化

ダウンロードした Web ページを lxml で読み取り、HTML テキストを抽出します。

soup = BeautifulSoup(result.text, 'lxml') 
HTML テキストから要素を検索

セレクタを使って、HTML の要素を取り出します。ターゲットは、以下のとおりです。

  • class 属性に.sc-hCbubC含む要素
  • 全ての li 要素
  • 全ての a 要素
elems = soup.select('.sc-hCbubC li a') 
タイトルと URL を取り出して表示

取り出した要素を for 文で 1 ずつ取り出し、elem に代入し、タイトルとリンクを表示します。

for elem in elems: 
    time.sleep(1) 
    title = elem.getText()
    link = elem.get('href')
    print(title, '({})'.format(link)) 

以上