77
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【初心者向け】PythonでWebスクレイピングをやってみる

読者の想定

初心者向けとありますが、私も初心者です。
webスクレイピングの簡単なサンプルコードの理解をした後、ちょっと自身のオリジナリティを出したいなと思って、調べながらやってみたという内容です。
webスクレイピングの参考コード通りに実行したら、タイトルとかを抜きだす事ができた!がレベル1なら、今回はレベル2くらいの内容だと思います。
なので、勘違いの部分もあったりすると思うので、ご指摘あればコメントいただければと思います。

はじめに

環境

python 3.7.3
私は、visual studio codeで開発しました。

ライブラリのインポート

Pythonには"urlib2"というHTTPのライブラリがあるのですが、使い勝手がよくないので、"Requests"と"BeautifulSoup"のライブラリを使ってwebスクレイピングを行います。
RequestsでWebページを取得して、Beautiful SoupでそのHTMLを抽出します。

やっていこう!

スクレイピング内容

日経ビジネス電子版
https://business.nikkei.com/
から、新着記事の見出しとURLを取得してみようと思います。

Google Chromeでアクセスし、F12キーで、デベロッパーツール(検証モード)にアクセスします。

新着記事の部分が、HTMLのどの部分なのか知りたいので、Ctrl + Shift + Cで見出しにカーソルを動かします。

コメント 2020-03-31 212354.jpg
コメント 2020-03-31 212442.jpg
すると、classがcategoryという部分に、記事の連載名がある事が分かりました。
コメント 2020-03-31 212502.jpg
コメント 2020-03-31 220521.jpg

記事の見出しは、h3タグに入っています。
また、URLは、少し上のaタグの部分にある事が分かります。
この関係を図に示すと、以下のような構図になります。
あとで、プログラムと一緒に解説したいと思います。

図1.png

コードの解説

code.py
import requests
from bs4 import BeautifulSoup
import re

urlName = "https://business.nikkei.com"
url = requests.get(urlName)
soup = BeautifulSoup(url.content, "html.parser")

requestsのライブラリでhttp接続をして、BeautifulSoupでhtmlの解析をします。

code.py
elems = soup.find_all("span")

まず、span要素を全てelemsに格納します。

code.py
for elem in elems: 
  try:
    string = elem.get("class").pop(0)
    if string in "category":
      print(elem.string)
      title = elem.find_next_sibling("h3")
      print(title.text.replace('\n',''))
      r = elem.find_previous('a')
      print(urlName + r.get('href'), '\n')
  except:
    pass

次に、span要素の中から、class名を取り出して、categoryかどうかを判別します。
もし、classがcategoryであった場合には、連載名のテキストを、.stringを用いて抜き出します。

そして、次は見出しの内容を取得します。
見出しは、h3タグにありました。
h3タグは、同じ深さで、すぐ下の部分にありました。
なので、find_next_sibling()を使って、要素以降の同じ深さにあるh3を検索します。

図2.png

抜き出した文章には、画像もついている場合があり、改行が含まれている場合と含まれていない場合があったので、含まれている場合は削除しました。

最後に、URLを抜き出しにいきたいと思います。先ほどは、同じ深さでしたが、aタグは、ひとつ上の深さにいます。
したがって、find_previous()を使って、aタグを探しに行き、要素の指定の属性値を取得するgetメソッドを用いて、hrefのアドレスを取り出しました。

図3.png

以下、実行結果の一部です。

池松由香のニューヨーク発直行便
米海軍の巨大病院船がNY入り それでも足らない病床
https://business.nikkei.com/atcl/gen/19/00119/033100011/

市嶋洋平のシリコンバレーインサイ…
「需要2割経済」を生きる ポストコロナ考え動く米外食業界
https://business.nikkei.com/atcl/gen/19/00137/033100002/

橋本宗明が医薬・医療の先を読む
中国平安保険と提携した塩野義・手代木社長の深謀遠慮
https://business.nikkei.com/atcl/gen/19/00110/033100012/ 

このように、取得する事ができました。

さいごに

まだまだ勉強中なので、勘違いしている部分があったり、もっと良い方法があるかとは思います。
少しずつ理解を深めながら実践していきたいと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
77
Help us understand the problem. What are the problem?