Pythonで指定したページのリンクと指定したエリアの子要素のリンクhrefを取得する方法!Webスクレイピングの勉強

2022-01-02

Pythonで指定したページのリンクの一覧を取得できるようになりたいと思います。

Pythonで指定したページのリンクを取得する方法

URLを指定して表示されるページのリンク一覧を取得したいと思います。

環境

Python IDLEを使用

ライブラリ BeautifulSoup

BeautifulSoup4のインストール方法

BeautifulSoup4はpipのコマンドでインストール可能です。

Win

pip install beautifulsoup4

Mac

pip3 install beautifulsoup4

リンクを全て取得する

サンプルコードを見ながら取得する手順を追います。

サンプルコード

# BeautifulSoupをインポート
import requests
from bs4 import BeautifulSoup

#「手っ取り早くPython3.xをダウンロードして使ってみる(Mac)!はじめてのPython」のURLを指定
url = "https://programmer-life.work/python/use-python3-mac"

# ページのHTML(ソース)を取得
html = requests.get(url)

# BeautifulSoupで解析(=parser)
soup = BeautifulSoup(html.content, "html.parser")

# aタグを解析データから全て見つけてhref属性の中身を表示
for element in soup.find_all("a"):
    url = element.get("href")
    print(url)

※ for文でprintの前に見やすくなるようにスペースを設けていますが、コピペの場合はPython側のエディタでスペースを付け直してください。コピペのままだとエラーになります。

Run 実行結果

大量のリンクが結果として表示されるので省略

指定したエリアのリンクを取得

少し取得したリンク量が多すぎたので開発者ツールでソースを確認し「関連記事」=「id="related"」のdivタグの中にあるリンクだけ取得したいと思います。これがidで取ればすぐ取れるかと思いきやなかなか面倒くさい。

(はじめは関連のリンクを取得しようとしたがwordpressの仕様なのか、解析データに含まれておらず断念)

面倒だった理由はid指定したdiv内に同じリンクが2回使われていたので2個重複して出力されてしまうのが嫌だったからです。id指定したdiv内にリンクが重複していなければ以下サンプルコードで取得可能だと思います。

サンプルコード

# BeautifulSoupをインポート
import requests
from bs4 import BeautifulSoup

#「手っ取り早くPython3.xをダウンロードして使ってみる(Mac)!はじめてのPython」のURLを指定
url = "https://programmer-life.work/python/use-python3-mac"

# ページのHTML(ソース)を取得
html = requests.get(url)

# BeautifulSoupで解析(=parser)
soup = BeautifulSoup(html.content, "html.parser")

# aタグを解析データから特定のID内から全て見つけてhref属性の中身を表示
related = soup.find(id="related")

# 指定したIDの中からaタグを探してhrefをプリント
for element in related.find_all("a"):
    url = element.get("href")
    print(url)

Run 実行結果

https://programmer-life.work/python/requests-pyhon
https://programmer-life.work/python/requests-pyhon
https://programmer-life.work/python/requests-get-encoding-python
https://programmer-life.work/python/requests-get-encoding-python
https://programmer-life.work/python/python-get-h1-text
https://programmer-life.work/python/python-get-h1-text
https://programmer-life.work/python/python-no-module-named-selenium
https://programmer-life.work/python/python-no-module-named-selenium
https://programmer-life.work/python/with-open-python
https://programmer-life.work/python/with-open-python

エクセルで重複を消してもいいのかもしれないですね。

指定したエリアの内の特定のクラス内のリンクを取得

やっぱり重複を消したいとclassでリンクの片側の要素のエリアを指定してfind_allで試みるも、find_allで取得するとオブジェクト化されるようでうまく中身を取得できない。
いろいろ調べるもこれといった方法はなく、ループをネストして増やしたところうまくいきました。

# BeautifulSoupをインポート
import requests
from bs4 import BeautifulSoup

#「手っ取り早くPython3.xをダウンロードして使ってみる(Mac)!はじめてのPython」のURLを指定
url = "https://programmer-life.work/python/use-python3-mac"

# ページのHTML(ソース)を取得
html = requests.get(url)

# BeautifulSoupで解析(=parser)
soup = BeautifulSoup(html.content, "html.parser")

# 解析データから特定のID内の特定のクラス配下のaタグから全てのhref属性の中身を表示
related = soup.find(id="related")

# 指定したIDの中からexcerptクラスを探す
for elements in related.find_all(class_="excerpt"):
# 指定したIDの中のexcerptクラスからaタグを探しhrefをプリント
    for element in elements.find_all("a"):
        url = element.get("href")
        print(url)

Run 実行結果

https://programmer-life.work/python/python-get-h1-text
https://programmer-life.work/python/with-open-python
https://programmer-life.work/python/requests-pyhon
https://programmer-life.work/python/python-comment
https://programmer-life.work/python/python-no-module-named-selenium

ID内のクラス内のaタグのhrefが取得できました。

おわり

急がば回れですね、初めから自分で考えれば重複を取り除くのも早かったのかもしれない。4時間くらいだらだら調べてしまった気がします。

Python

Posted by Nakamoto