Pythonでウェブページを取得してみる
「ネットを触る」の、こわくない最初の一歩
Pythonの本や記事を読んでいると、どこかで必ず「Webページを取得する」という話が出てきます。そして、そこで手が止まる方が少なくありません。
ファイルの整理や家計簿の集計なら、失敗しても自分のパソコンの中の話です。でも「インターネットに向かって何かをする」となると、急に話が違って見えます。知らないうちに誰かに迷惑をかけていたら。怒られたら。よくないものを受け取ってしまったら。——そう感じるのは、おかしなことではありません。むしろ自然な感覚です。
この記事は、その一歩を踏み出すためだけの記事です。やることは1つだけ、書くコードは全部で10行以下。応用も自動化も出てきません。「なんだ、これだけか」と思ってもらえたら成功です。
この記事でやること
WikipediaのPythonのページを1回だけ開いて、そのタイトルを取り出す。これだけです。
「毎日自動でチェックする」も「値段の変化を見張る」も、この記事では扱いません。それらは、この最初の一歩が済んでからで十分間に合います。
Pythonのインストールとエディタ(VS Code)の準備がまだの方は、先に「Pythonを始める前に:インストールとエディタの準備」を済ませてから戻ってきてください。
何が怖いのか、先に分解します
不安なまま手を動かすと、うまくいっても「たまたま無事だっただけかも」という気持ちが残ります。先に、何が引っかかっているのかをはっきりさせてしまいましょう。
勝手にアクセスして、怒られない?
ページを1回開くだけなら、ブラウザでそのページを見るのとまったく同じです。あなたが今日ブラウザで開いたページの数を思い出してください。何十ページも開いているはずですが、誰にも怒られていません。
問題になるのは「1秒間に何百回もアクセスする」ような使い方です。それはサイト側の負担になります。この記事でやるのは1回だけなので、まったく心配ありません。
ただし、「どこから来たか」を名乗るのは礼儀です。ブラウザは自動で名乗っていますが、Pythonは何も指定しないと「Pythonの標準の名札」のままアクセスします。それを断るサイトもあります(実際、Wikipediaは断ります)。このあとのコードでは、最初から名乗るように書いてあります。
ウイルスとか、大丈夫?
今回受け取るのは、ページを組み立てている文字の情報だけです。文字を受け取って画面に表示するだけなので、何かのプログラムが勝手に動き出すことはありません。
ブラウザの場合はむしろ、受け取った内容を実際に動かして表示まで行っています。それに比べれば、今回やることのほうが単純で、触る範囲も狭いのです。
パソコンが壊れたりしない?
今回のコードは読むだけで、あなたのパソコンには何も保存しません。ファイルを消すことも、設定を書き換えることもしません。実行してもパソコンの中身は何ひとつ変わらない、と思って大丈夫です。
難しそう…
この記事で書くコードは、全部合わせて10行以下です。しかも、そのうち意味を理解しないといけないのは3行だけです。
実は、ブラウザと同じことをしています
Webページを取得するというのは、特別なことではありません。いつもブラウザにやってもらっていることを、Pythonに代わりにやってもらうだけです。
あなたがリンクをクリックすると、ブラウザがサイトに「このページをください」とお願いし、サイトがページの中身を返してきます。ブラウザはそれを受け取って、人が読める形に整えて画面に表示します。
Pythonでやる場合も、まったく同じ流れです。違うのは真ん中がブラウザではなくPythonになることと、受け取った中身を画面に整えずそのまま扱うこと。それだけです。
サイト側から見れば、ブラウザからのアクセスもPythonからのアクセスも「ページを見に来た人」として同じように届きます。特別な裏口を使うわけでも、こっそり忍び込むわけでもありません。
準備:ライブラリを1つ入れる
Webページを取得するために、requestsというライブラリを使います。ターミナル(コマンドプロンプト)で次のコマンドを実行してください。
pip install requests
最後にSuccessfully installedと表示されれば完了です。あとで文字を抜き出すときに使うものも、この時点で一緒に入れておきましょう。
pip install beautifulsoup4
ライブラリとは、誰かが作って公開してくれている「便利な部品セット」のことです。自分でゼロから作らなくても、この一行で使えるようになります。Pythonが広く使われている理由のひとつが、この部品の豊富さです。
まず1回、取ってみる
いよいよ実行します。エディタで新しいファイルを作り、次の4行を書いて保存してください。ファイル名はweb_test.pyなど、分かりやすいもので構いません。
import requests
headers = {"User-Agent": "MyFirstScript/1.0 (personal study)"}
response = requests.get("https://ja.wikipedia.org/wiki/Python", headers=headers)
print(response.status_code)
実行すると、次のように表示されます。
200
これで成功です。あっけないと思われたかもしれませんが、いま実際にインターネットに接続し、Wikipediaのページを受け取っています。
この4行が何をしているか
import requests— さきほど入れた部品を使う、という宣言headers = {...}— 「どのソフトから来たか」を名乗るための札。これを付けずにアクセスすると、断ってくるサイトがあります(後述)requests.get(...)— 指定したページを「ください」とお願いするprint(response.status_code)— 結果がどうだったかを表示する
表示された200は、「問題なく受け取れました」という意味の番号です。ページが見つからないときは404になります。この番号、実はブラウザでも同じものが使われていて、見覚えのある「404 Not Found」がまさにそれです。
練習台にWikipediaを選んだのは、誰でも自由に閲覧できる公開百科事典であり、内容も安定していて、何度開いても問題がないためです。いきなり通販サイトなどで試すより、まずはこうしたページで慣れるのが安全です。
何が返ってきたのか、見てみる
200だけでは実感がわかないので、実際に受け取った中身を覗いてみましょう。さきほどのコードの最後の行を、次のように書き換えます。
print(response.text[:300])
実行すると、記号が入り混じった文字がずらずらと表示されます。びっくりされたかもしれませんが、これが「ページの正体」です。
普段ブラウザで見ている見出しや文章や画像は、こうした<html>や<title>といった目印(タグと呼びます)で囲まれた文字を、ブラウザが読み取って組み立てた結果なのです。私たちは完成品だけを見ていて、その材料を初めて見た、という状態です。
末尾の[:300]は「最初の300文字だけ表示する」という指定です。これを付けないと、ページ全体の何万文字もが画面に流れてしまいます。
ここで「うわ、読めない」と感じても問題ありません。この記号の羅列を人間が読む必要はなく、次のセクションで使う道具が、必要な部分だけを取り出してくれます。
タイトルだけ、抜き出してみる
先ほどの文字の山から、ページの見出しだけを取り出してみましょう。ここでbeautifulsoup4の出番です。コード全体は次のようになります。
import requests
from bs4 import BeautifulSoup
headers = {"User-Agent": "MyFirstScript/1.0 (personal study)"}
response = requests.get("https://ja.wikipedia.org/wiki/Python", headers=headers)
soup = BeautifulSoup(response.text, "html.parser")
title = soup.find("h1").get_text(strip=True)
print(title)
実行すると、こう表示されます。
Python
できました。あの記号だらけの文字の中から、ページの見出しだけをきちんと取り出せています。
増えた部分の意味
BeautifulSoup(...)— 受け取った文字の山を、扱いやすい形に整理してもらうsoup.find("h1")— その中からh1(大見出し)の目印が付いた部分を探す.get_text(strip=True)— 見つけた部分から、タグを除いた文字だけを取り出す
やっていることは、「材料の山から、欲しい部品を1つ指名して取り出す」だけです。h1の部分を別の目印に変えれば、他の場所も同じやり方で取り出せます。
ここまでで、この記事の目標は達成です。書いたコードは全部で8行でした。「Webページを取得する」というのは、この8行のことだったわけです。
気をつけるのは、たった2つ
今後この方法を自分の目的に使っていくときに、守ってほしいことが2つあります。逆に言えば、この2つを守っていれば、まず問題は起きません。
1. 短い間隔で何度もアクセスしない
プログラムは、人間と違って一瞬で何百回でも繰り返せてしまいます。それをそのままやると、相手のサイトに負担をかけます。人が手でクリックするのと同じくらいの間隔——数秒に1回、あるいはもっとゆっくり——を守れば大丈夫です。
2. 取ったものを、そのまま公開しない
取得した文章や画像には、書いた人の権利があります。自分で見て使う分には問題ありませんが、自分のサイトやSNSにそのまま転載するのはやめてください。これはPythonに限った話ではなく、ふだんのコピー&ペーストと同じ考え方です。
もう少し踏み込んだ使い方(特定のサイトを繰り返し見張るなど)をするときは、そのサイトの利用規約で自動取得が禁止されていないかを確認してください。大手の通販サイトやSNSは禁止していることが多く、その場合は行ってはいけません。この記事の範囲(自分で1回開く)では、まだ気にしなくて大丈夫です。
うまくいかないとき
ModuleNotFoundError: No module named ...と出ます▼pip install requestsとpip install beautifulsoup4をもう一度実行してください。それでも直らない場合は、python -m pip install requestsのようにpython -mを付けて実行すると、いま使っているPythonに確実に入ります。なお、インストール時の名前はbeautifulsoup4ですが、コードの中で読み込むときはbs4になります。ここは名前が違う珍しい例です。200ではなく別の番号が出ました▼404はページが見つからない、403はアクセスを断られた、という意味です。403が出た場合は、まずheadersの行を書き忘れていないか確認してください。Wikipediaは、名乗らずに来たアクセスを断ります。URLが正しくても、headersが無いと403になります。404が出た場合は、URLの打ち間違いを確認してください。この記事のURLをそのままコピーして貼り付けるのが確実です。print()の行を書き忘れていないか確認してください。Pythonは、表示するよう指示しない限り、結果を画面に出しません。処理は成功しているのに何も出ない、というのはよくあることです。まとめ:次にできるようになること
この記事でやったことを振り返ります。
- Webページの取得は、ブラウザがやっていることをPythonに代わってもらうだけ
- 受け取るのは文字だけ。パソコンには何も書き込まれない
- 実際に書いたコードは8行
- 気をつけるのは「連続でアクセスしない」「取ったものを転載しない」の2つだけ
ここまでできれば、あとは「どの部分を取り出すか」と「取り出した後どうするか」を変えていくだけです。たとえば、次のようなことができるようになります。
- 気になる商品のページから、価格の部分だけを取り出す
- 前回取り出した価格と比べて、変わっていたら教えてもらう
- それを1時間ごとに、自分は何もせずに繰り返す
やっていることは、今日の8行の延長線上にあります。続きは次の記事で、ひとつずつ作っていきましょう。


コメント