【初心者向け】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で見出しにカーソルを動かします。

<img width="239" alt="コメント 2020-03-31 212354.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/057f44cd-139b-6bfa-1b56-185a556e13c3.jpeg">
<img width="395" alt="コメント 2020-03-31 212442.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/88c36486-6e7d-27d2-887a-d9d6bc6a4566.jpeg">
すると、classがcategoryという部分に、記事の連載名がある事が分かりました。
<img width="224" alt="コメント 2020-03-31 212502.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/a403935a-9baf-839b-4ea4-09186d9d9b5d.jpeg">
<img width="341" alt="コメント 2020-03-31 220521.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/3a2a8650-e9a9-d4c0-198d-6589581c7917.jpeg">

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

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/e7b20e2e-1852-c080-759a-9c6fa3a2c84b.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/6fc2a4ef-e07e-518a-e046-062f613c61f8.png)

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

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

![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267677/4e7fa7cd-2242-10a0-765d-910b2d5ef027.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/ 
```

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

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