先週 Let’s start Python #2 に参加してきました!今回の講座内容はスクレイピングなのでとても楽しみでした。
スクレイピングは興味ある人多いと思うんですけど、勉強する機会ってなかなかないんですよねー。ProgateにもPaizaラーニングにも見当たらないし、業務で使う訳でなく趣味で使ってみたいだけなので、書籍購入してまでの学習コストは掛けたくないし。。
クローリング、スクレイピング基礎
クローリングとは、リンクを辿ってWebページを収集すること
スクレイピングとは、収集したWebページ(HTML)から必要な情報を抜き出すこと
クローリングとスクレイピング実施時の注意事項
これが知りたかったです!勝手にスクレイピング(クローリング)しちゃダメなんだろうなーとは思いつつ、どういうルールで許可/拒否されているんだろうと疑問に思ってました。
- Webサイトによっては、クローリングが禁止されている
- robots.txtやrobots metaタグで拒否されているページをクロールしないこと
- Webサーバへの負担をかけないよう配慮して作成する(最低1秒は間隔をあける)
Googleを例にした場合、下記のようにrobots.txtにアクセスすると、どのページが許可されていて、どのページが拒否されているのかを確認できます。
https://www.google.co.jp/robots.txt
# robots.txt User-agent: * Disallow: /search # /search以下は基本的にクロール禁止 Allow: /search/about # /search/aboutのみクロール許可 Allow: /search/static # /search/staticのみクロール許可
詳細は、 robots.txt の概要に記載されています。
仮想環境構築
今回ライブラリのインストール等を行うので、今回の作業用の仮想環境を構築します。Windows用とMac用の説明がありました。WSLでUbuntu(Linux)使っている人は少ないんですね(使用コマンドは適宜置き換えました)。Macはいいとして、WindowsでコマンドプロンプトからPython使うとか、お疲れ様です!としか言えない(20年以上前のターミナルをまだ使うってことは、メインフレームをまだ使っているに等しい)。。
$ mkdir elv_python # 作業ディレクトリ作成 $ cd elv_python $ python3 -m venv myvenv # 仮想環境をvenvライブラリで作成 $ source myvenv/bin/activate # 環境設定ファイルを読み込む $ pip install requests # ライブラリのインストール $ pip freeze # 確認 certifi==2019.6.16 chardet==3.0.4 idna==2.8 pkg-resources==0.0.0 requests==2.22.0 # インストールされている urllib3==1.25.3
Webページの情報をクローリング
$ vi sc_1.py
import requests
url = "http://sandream.main.jp/elv_python/first" # サンプルURL
response = requests.get(url) # HTMLを取得
response.encoding = response.apparent_encoding # エンコーディング
print(response.text)
$ python3 sc_1.py # クローリング実行
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>初めてのスクレイピング</title>
</head>
<body>
<h1>初めてのスクレイピング</h1>
<p>スクレイピングテスト</p>
</body>
</html>
Web情報を解析する(スクレイピング)
$ pip install beautifulsoup4 # ライブラリのインストール
$ pip freeze # 確認
$ vi sc_4.py # スクレイピングのソースファイル作成
import requests
from bs4 import BeautifulSoup # スクレイピングに特化したモジュール
url = "http://sandream.main.jp/elv_python/second" # サンプルURL
response = requests.get(url) # HTML取得
response.encoding = response.apparent_encoding # エンコーディング
# BeautifulSoupにファイルとhtml parserを渡してインスタンスを作成
# html.parser:htmlのタグ情報から情報を解析するプログラム
bs = BeautifulSoup(response.text, 'html.parser')
ul_tag = bs.find('ul') # ulタグで囲まれた部分を抽出
for a_tag in ul_tag.find_all('a'): # ulタグの中のaタグを抽出
text = a_tag.text # aタグのテキストを取得
link_url = a_tag['href'] # aタグのhref属性を取得
print('%s: %s'%(text, link_url))
$ python3 sc_4.py # 実行結果
どこにも行かない1: http://sandream.main.jp/elv_python/1
どこにも行かない2: http://sandream.main.jp/elv_python/2
どこにも行かない3: http://sandream.main.jp/elv_python/3
どこにも行かない4: http://sandream.main.jp/elv_python/4
どこにも行かない5: http://sandream.main.jp/elv_python/5
練習問題
■問題
http://sandream.main.jp/elv_python/exercises
の中のリンク先に記載されているpタグ内のテキストだけを表示しましょう
■私の回答
全てのhref属性を取得して、その後でpタグを取得したので、for文を2回も回してしまいました。
$ vi sc_5.py
import requests
import time
from bs4 import BeautifulSoup
url = "http://sandream.main.jp/elv_python/exercises"
response = requests.get(url) # HTMLを取得
response.encoding = response.apparent_encoding # エンコーディング
# BeautifulSoupにファイルとhtml parserを渡してインスタンスを作成
bs = BeautifulSoup(response.text, 'html.parser')
link_url = []
ul_tag = bs.find('ul') # ulタグで囲まれた部分を抽出
for a_tag in ul_tag.find_all('a'): # ulタグの中のaタグを抽出
link_url.append(a_tag['href']) # aタグのhref属性を取得
for url in link_url:
response = requests.get(url)
response.encoding = response.apparent_encoding
bs = BeautifulSoup(response.text, 'html.parser')
p_tag = bs.find('p') # pタグを取得
print(p_tag.text)
time.sleep(1) # 1秒間隔をおく
$ python3 sc_5.py # 実行結果
すばらしい仕事をするには、自分のやっていることを好きにならなくてはいけない。
まだそれを見つけていないのなら、探すのをやめてはいけない。
安住してはいけない。
心の問題のすべてがそうであるように、
答えを見つけたときには、自然とわかるはずだ。
※ 「by スティーブジョブス」だそうです。いい言葉ですね!
私はインフラエンジニアに安住せず探して、Webエンジニアという答えを見つけました~!
■模範解答
href属性を取得してそのままpタグも取得すれば、for文は1度で済みますね汗
動くコードは書けるけど、よいコード(技術的負債のない)を書くにはまだ精進が必要のようです!
$ vi sc_5.py
import requests
import time
from bs4 import BeautifulSoup
url = "http://sandream.main.jp/elv_python/exercises"
response = requests.get(url) # HTMLを取得
response.encoding = response.apparent_encoding # エンコーディング
# BeautifulSoupにファイルとhtml parserを渡してインスタンスを作成
bs = BeautifulSoup(response.text, 'html.parser')
ul_tag = bs.find('ul') # ulタグで囲まれた部分を抽出
for a_tag in ul_tag.find_all('a'): # ulタグの中のaタグを抽出
link_url = a_tag['href'] # aタグのhref属性を取得
detail_response = requests.get(link_url)
detail_response.encoding = detail_response.apparent_encoding
detail_bs = BeautifulSoup(detail_response.text, 'html.parser')
detail_p_tag = detail_bs.find('p') # pタグを取得
print(detail_p_tag.text)
time.sleep(1) # 1秒間隔をおく
主催者の方の資料:python_elv_2
※ 上下左右ボタンでページが切り替わります。
Kindleのデータを収集したい
・Prime Reading
Amazonプライム会員になっていると、Prime Readingという読み放題サービス(949冊)があるので、ここから自分が興味ありそうな本を抽出したい。
・Kindleオーナーライブラリー
Amazonプライム会員でかつKindle Fireを持っていると、Kindleオーナーライブラリという月1冊が無料で読めるサービス(641冊)があるので、ここから自分が興味ありそうな本を抽出したい。
robots.txtの内容を確認してみたところ、自分のwishlistだけスクレイピングが許可されてました笑 まあ当然というか、スクレイピングはダメということですね。
AmazonならAPIが用意されていると思ったので、下記の記事に目を通す。Product Advertising APIを使用するには、Amazonアソシエイトへの登録が必要とのこと。Amazonアソシエイトは、登録後に1年間放置してたら(売り上げないから)アカウント閉鎖されてしまってました。。おとなしく、ブラウザの画面から地道に探すことにします。。



