【コード公開】【初心者のPython入門】Webスクレイピングとクローリング





今回は、特定のURL内にある各リンクにもアクセスし、そのリンク内の内容を抽出する基本的なクローリングプログラムを作成していきます。
当然、特定のWebサイトによってHTML構造等が異なる場合があるのと、取得したい情報も異なるかと思いますが、クローリングはこのように行うことができるということがお伝えできればなと思います。
 
 

汎用性の広いPythonを0から習得するためのフロー及び実際にPythonで開発を行い開発案件を獲得するまでの筋道について解説しているチュートリアル資料と

コーディングの参考となる実際にPythonを使って作ったツールのソースコードを無料で配布していますので、こちらも併せてご覧ください。

初心者・入門者でも30日間で学習できるおすすめPython学習方法

 

おすすめのPython学習サービスをまとめてみました。挫折することなく一直線にエンジニアを短期集中で目指している人はこちらから確認してください。 

【おすすめ】Python学習サイトPyQが初心者に選ばれる理由

プログラミングを学ぶ上で作りたいものがない人へ提案させてください

 

プログラム概要

 
 
本プログラムは、簡単に作成できるクローリングプログラムになります。
クローリングとは、特定のWebサイト内を巡回する技術の総称になります。そのため、実際にクローリングした先の情報を収集する技術としては、Webスクレイピングという技術となります。
 
 
クローリングといっても、様々な種類があります。
そしてその種類としては、利用用途によって変化します。例えば、今回の本プログラムのようにWebサイト内のテキストを抽出するプログラムや、特定の動画だけを抽出(ダウンロード)を行うプログラムなどです。
 
 
そして一番のメリットは、なんといっても情報収集の自動化です。
本プログラムは、そのきっかけなどに利用していただければ幸いです。
 



各SNSにおけるAPIの利用

最近では、SNSからのデータ抽出も頻繁に利用されているため、サイト内を巡回するクローリングプログラムの他に、APIを利用したプログラムも人気があります。

これは一長一短ではありますが、SNSからのデータ抽出を考えている場合、クローリングシステムによる制限とAPIによる制限が異なるため、どちらを利用することが最適なのか理解しておく必要があります。

ただ、単純に多くの情報を抜き取りたい場合やAPIの使用制限内で必要な情報を取得できる場合は、APIによるプログラムを構築した方が比較的簡単にプログラム自体も時間的コストも抑えられます。

あなたがどのようなプログラム設計を行うかによって、選択するものを変換すると良いでしょう。

本記事では、簡単なクローリングプログラムを記載していますが、興味があれば別記事でAPIを利用したプログラムも記載していますのでよければ一読してみてください。

必要なモジュールのインストール

 
 
# モジュールのインポート
import urllib.request as req
from bs4 import BeautifulSoup
import time
 
 
ここでは利用するモジュールとして、request、BeautifulSoup、timeを利用します。
 
 
requestモジュールは、HTTP通信を行うためのライブラリに特化した機能を備えています。
WebサーとのダウンロードやRESTAPI等の利用が比較的簡単に行うことができます。
このモジュールを利用して特定URLに対してリクエストを行い、結果を取得します。
 
 
BeautifulSoupモジュールは、pythonのライブラリの一つでスクレイピングに特化した機能を備えています。
スクレイピングは、端的に言うと取得したHTMLから任意の情報を抽出する技術を指します。
 
 
timeモジュールついては、pythonの標準モジュールとして備えられているので、特にインストールする必要はありません。
 
 



特定のURLからデータを取得

 
 
# 任意のURLからデータを取得
url = "https://su-gi-rx.com/"
res = req.urlopen(url)
 
 
ここでは、まず任意の特定URLを変数urlに代入して利用します。
req.urlopen()を利用して、特定URLから結果を取得し、変数resに格納しています。
 
 
本プログラムでは、特定のWebサイトを指定していますが、特定のサイトを指定する際にどのようなHTML構造かを考慮して設計しなければならないことを前提としてください。
つまり、特定のWebサイトによっては取得したいデータの格納先が異なることがあるため、HTML構造をよく理解してコーディングしていきましょう。
 
 



特定URL内にあるリンク抽出

 
 
"""
特定URL内にあるリンクを抽出
抽出データのHTML解析を行い、リンクをリスト化
"""
soup = BeautifulSoup(res, 'html.parser')
links = soup.select("a[href]")
result = []
for a in links:
	href = a.attrs["href"]
	title = a.string
	result.append((title, href))
 
 
ここでは、先ほど取得したデータを格納した変数resを利用します。
BeautifulSoupモジュールを利用して、取得データをHTML情報を解析し、そのデータを変数soupに格納しています。
 
 
次に解析したデータを格納している変数soupから任意のタグをselectメソッドを利用して選択・抽出し、その取り出したデータを変数linksに格納しています。
 
 
for文では、変数links内のデータを回して、タイトルとサイト内のリンク先の各URLをリスト化していきます。
 
 



テキストデータ抽出 -> 各ファイル保存

 
 
"""
リンク先の<p>タグ内のテキストを抽出
抽出データを記事タイトルごとにtxtファイルに書き込み作成
"""
for title, url in result:
	print("link = " + url)
	time.sleep(1)
	res_1 = req.urlopen(url)
	soup_1 = BeautifulSoup(res_1, 'html.parser')
	p_list = soup_1.find_all("p")
	for p in p_list:
		print(p.get_text())
		with open("{}.txt".format(title), mode="a") as f:
			f.write(p.get_text())
 
 
ここでは、リスト化したデータを格納している変数resultに対して、titleとurlとしてfor文で回していきます。
 
 
また、本プログラムでクロール先はこのサイトを指定しているので、気にすることはありませんが、本来はクローリングを行う際の注意点があります。
 
 
・Webサイトの利用規約に則って行うこと
・アクセス制限内容を守ること
・サーバに負荷をかけないこと
 
 
基本的に上記の内容になりますが、当然サイトによっての規約内容で異なるので、よく理解してクローリングを行いましょう。
 
 
次にサーバに負荷をかけないためにtime.sleepを利用して1秒間隔アクセスするようコードを追加しています。
 
 
次に、リスト化したデータ内にある各URLからデータを取得した内容を変数res_1に格納し、変数res_1のデータを解析したデータを変数soup_1に格納していきます。
その後、解析したデータ内の<p>タグのテキストデータを抽出し、変数p_listに格納していきます。
 
 
最後に、抽出したテキストデータごとにwith openを利用してファイルを作成し、このファイル内にテキストデータを書き込んでいきます。
 
 
全体のコードを下記に記載しておきます。
コピーして利用してみてください。
 
 
# crawl.py

# モジュールのインポート
import urllib.request as req
from bs4 import BeautifulSoup
import time

# 任意のURLからデータを取得
url = "xxxx"
res = req.urlopen(url)

"""
特定URL内にあるリンクを抽出
抽出データのHTML解析を行い、リンクをリスト化
"""
soup = BeautifulSoup(res, 'html.parser')
links = soup.select("a[href]")
result = []
for a in links:
	href = a.attrs["href"]
	title = a.string
	result.append((title, href))

"""
リンク先の<p>タグ内のテキストを抽出
抽出データを記事タイトルごとにtxtファイルに書き込み作成
"""
for title, url in result:
	print("link = " + url)
	time.sleep(1)
	res_1 = req.urlopen(url)
	soup_1 = BeautifulSoup(res_1, 'html.parser')
	p_list = soup_1.find_all("p")
	for p in p_list:
		print(p.get_text())
		with open("{}.txt".format(title), mode="a") as f:
			f.write(p.get_text())
 
 
今回の記事を読んでいただき、ありがとうございました。
 
 

実務に活かす際に学習として利用していたPython本が以下のものになります。

・PythonによるWebスクレイピング(オライリー出版)

・増補改訂Pythonによるスクレイピング&機械学習 開発テクニック(クジラ飛行机)

・Pythonクローリング&スクレイピング – データ収集・解析のための実践開発ガイド



ABOUTこの記事をかいた人

sugi

大学卒業後、IT企業に就職を果たす。システム開発・人工知能に触れながら大手企業と業務をこなす。2年半後脱サラし、フリーランス活動経験を経て 2019年2月から起業し、今に至る。 自社サービス及び製品を開発、ブログ収入、クラウドソーシングなど、多方面で売り上げを立てている。