BeautifulSoup4を使ってみる
BeautifulSoupとは
めっちゃ簡潔に、Pythonでスクレイピングをすることができる外部ライブラリ
事前準備
Python3がインストールされている環境であることを前提としている。
ターミナルで以下を⼊⼒
code:powershell
pip install beautifulsoup4
開発環境としてjupyter-labを使ったので、同じ環境を使ってみたい⽅を以下も(⾼専の時に書いた資料を移植したのでチョット
キョウミアル⼈はこちらも ← scrapbox移行で削除)
code:powershell
pip install jupyter-lab
まずはrequestを使ってみよう
beautifulsoupを使う前に、標準ライブラリのrequestを使⽤して、読売新聞のページHTMLを受け取ってみる
以下のコードを打ち込もう
code:python
# 先に必要なものをすべてインポートしておく
import request
import re
from bs4 import BeautifuSoup
# urlは⾃分が⾒てみたいサイトに適宜変更してみよう
res = requests.get(url)
結果
https://scrapbox.io/files/62b57102aba368001df1d3e9.png
bs4でHTML解析
HTML解析とは
HTML⽂書を解析して、プログラム内で扱いやすい形にすること。
今回の場合はHTMLパーサーをつかって条件に合う属性のテキストを抽出する。
条件を⾒つけるためにCSSセレクタを使う。
CSSセレクタ
CSS セレクターは、⼀連の CSS のルールが適⽤される要素を定義するもの。
ブラウザのデベロッパーツールからニュースタイトルのセレクタをコピーしてみる
1. F12キーをおしてDevツールを押して、左上の⽮印を押す
https://scrapbox.io/files/62b5714d35f6ce001dbdeb0f.png
2. 記事のタイトルをクリックする
https://scrapbox.io/files/62b571940b2365001d2a1d84.png
3. 該当箇所のHTMLが表⽰されるので、右クリック
https://scrapbox.io/files/62b5721275932900200c565d.png
4. copy->copy selectorを選択
https://scrapbox.io/files/62b571f9dd7c65002372cbf6.png
5. 試しに貼り付けてみるとこのようなものが出てくる
code:css selector
body > div.layout-contents > div.layout-contents__main > div.uni-scrap > article > div.article-header > h1
タイトルの抽出
Devツールで抽出したCSSセレクタを使ってHTML解析をしていく。
今回は例としてタイトルを抽出してみる
code:python
# HTMLパーサーの定義
soup = BeautifulSoup(res.text, "html.parser")
element = soup.select('body > div.layout-contents > div.layout-contents__main > div.uni-scrap > article > div.article-header >
print(element0.contents0) """
出⼒:
'\n アップル、iPod販売終了へ…2001年に初代発売、⾳楽業界に⾰命
"""
find, find_allメソッド
find
引数に⼀致する最初の⼀つの要素を取得する
find_all
引数に⼀致するすべての要素を取得する
Yahooのニュースの記事のURLを習得してみる
code:python
res = requests.get(url)
# htmlパーサーの定義
soup = BeautifulSoup(res.text, "html.parser")
print(soup.find("a"))
# 正規表現で記事URLが⼊っている要素だけ取得
elems = soup.find_all(href=re.compile("news.yahoo.co.jp/pickup"))
for i in elems:
結果
https://scrapbox.io/files/62b572d680ab420023e3e8fc.png
https://scrapbox.io/files/62b572e79aa276001dcaf71b.png
クローリング
先ほど取得したニュース記事から更にニュース記事の内容を取得してみる
code:python
pickup_links = [elem.attrs'href' for elem in elems] for pickup_link in pickup_links:
pickup_res = requests.get(pickup_link)
# 標準より早いlxmlパーサーを使ってみている
# 開発者ツールを使うと、特定の名前のクラス名に記事の内容が⼊っている
pickup_elem = pickup_soup.find("p", class_="sc-fsGQkc gnQXTK")
news_link = pickup_elem.contents0.attrs'href' news_res = requests.get(news_link)
print(news_soup.title.text)
print(news_link)
detail_text = news_soup.find(class_=re.compile("sc-ipXKqB LKGIH yjSlinkDirectlink highLightSearchTarget"))
print(detail_text.text if hasattr(detail_text, "text") else '', end='\n\n\n')
結果
https://scrapbox.io/files/62b5731b0b2365001d2a3f8a.png