【Python基礎】urllibでWebページの取得と保存:urllib.request.urlopen、.getcode()、.read()、.decode()、urllib.request.urlretrieve

  • URLをコピーしました!
目次

urllib

今回はPythonのurllibライブラリを使って、Webページの取得と保存を試していきます。

その理由としては、最近少しWebページの解析をやり、その解析の前段階としてWebページの取得を行なったので備忘録的に復習しようというのが今回の背景です。

ちなみに今回用いるurllibは標準ライブラリのため、インストールの必要はありません。

それでは始めていきましょう。

Webページの取得:urllib.request.urlopen

まずは何がともあれWebページの取得からです。

今回は3PySciのトップページを使ってみます。

サーバーに負荷をかけない程度(1回/5秒程度でしょうか)であれば3PySciを使っていただいて構いませんが、毎秒何十回もアクセスするようなやり方はやめてください。

使うのは「urllib.request.urlopen(’取得するWebページのURL’)」です。

import urllib

url = 'https://3pysci.com'

with urllib.request.urlopen(url) as response:
    print(response)

実行結果
<http.client.HTTPResponse object at 0x7fece6f5cd00>

ちなみに今回は「with構文」を使って書いていますが、使わずに書くとこうなります。

import urllib

url = 'https://3pysci.com'

response = urllib.request.urlopen(url)

print(response)

response.close()

このように「with構文」を使わずに書いた場合は、最後に開いたファイルを「close」する必要があるのに注意しましょう。

これでWebページの情報の取得が完了しているのですが、このままではどういうデータが取得できたのか分かりません。

ということで取得できたデータを紐解いていきましょう。

HTTPステータスコードの取得:.getcode()

取得したデータの中でまず重要なのが、データを正しく取得できたのかということです。

その情報をHTTPステータスコードというらしいのですが、urllibモジュールでは「.getcode()」で取得することができます。

import urllib

url = 'https://3pysci.com'

with urllib.request.urlopen(url) as response:
    print(response.getcode())

実行結果
200

今回は「200」というステータスコードが返ってきました。

「200」は正常に処理されたことを示すステータスコードです。

他のものとしてはこんなステータスコードがあります。

102処理中
200正常に処理
302一時的にページを転送
400リクエストが不正
401認証が必要
403アクセス禁止
404ページが見つからない
500サーバーエラー
503一時的に利用不可

ここに挙げたのは一部のものなので、もし他にどのようなものがあるか知りたい方は調べてみてください。

html情報の取得:.read()

次は本命、html情報の取得です。

html情報を取得するには、「.read()」を使います。

import urllib

url = 'https://3pysci.com'

with urllib.request.urlopen(url) as response:
    content = response.read()
    print(content)

実行結果
b'<!DOCTYPE html>\n<html lang="ja" data-loaded="false" data-scrolled="false" data-spmenu="closed">
\n<head>\n<meta charset="utf-8">\n<meta name="format-detection" content="telephone=no">\n
<meta http-equiv="X-UA-Compatible" content="IE=edge">\n<meta name="viewport" 
content="width=device-width, viewport-fit=cover">\n<link rel=\'dns-prefetch\' 
href=\'//codoc.jp\' />\n<link rel="alternate" type="application/rss+xml" title="3PySci » 
\xe3\x83\x95\xe3\x82\xa3\xe3\x83\xbc\xe3\x83\x89" href="https://3pysci.com/feed/" />\n
<link rel="alternate" type="application/rss+xml" title="3PySci » 
\xe3\x82\xb3\xe3\x83\xa1\xe3\x83\xb3\xe3\x83\x88\xe3\x83\x95\xe3\x82\xa3\xe3\x83\xbc\
(以下略)

実行してみると確かにhtml情報は取得できているのですが、「\xe3\x82\xb3\xe3\x83」といった感じで、ちゃんと読み取れていません。

これはデコードがうまくいっていない、つまり使われている文字と読んでいる文字が違っているというわけです。

例えでいうと英語の文章を英語で読み取るのではなく、カタカナで読み取っているため、何を言っているのか分からないといった状態といった感じでしょうか。

ということで次はデコードをしていきましょう。

デコード:.decode()

取得したhtmlファイルをデコードするには、「.decode()」を用います。

import urllib

url = 'https://3pysci.com'

with urllib.request.urlopen(url) as response:
    content = response.read()
    html = content.decode()
    print(html)

実行結果
<!DOCTYPE html>
<html lang="ja" data-loaded="false" data-scrolled="false" data-spmenu="closed">
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, viewport-fit=cover">
<link rel='dns-prefetch' href='//codoc.jp' />
<link rel="alternate" type="application/rss+xml" title="3PySci » フィード" href="https://3pysci.com/feed/" />
<link rel="alternate" type="application/rss+xml" title="3PySci » コメントフィード" href="https://3pysci.com/comments/feed/" />

正常にデコードできたおかげで、中身が読めるようになりました。

ただ気をつける点はこの「.decode()」は、文字のタイプを自動で読み取ってデコードしてくれるわけではありません。

デフォルトは「utf-8」という文字コードで、今回は「utf-8」で書かれたhtmlだったため、何も指定せずともちゃんとデコードされただけです。

もし他の文字コードの場合(例えば日本語だとshift_jisとか)は、文字コードの指定が必要です。

指定する場合は「.decode(‘文字コード’)」とします。

htmlの保存 その1:ファイル書き出し

取得したhtmlファイルの保存方法ですが2つあります。

まず一つ目はopen関数を使って、通常のファイル書き出しを行う方法です。

と言うことでこんな感じ。

import urllib

url = 'https://3pysci.com'
html_out = './3pysci.html'

with urllib.request.urlopen(url) as response:
    content = response.read()
    html = content.decode()
    with open(html_out, 'w') as f_out:
        f_out.write(html)

取得し、デコードしたhtmlの情報をそのまま「.write」に渡してやることで書き出すことができます。

htmlの保存 その2:urllib.request.urlretrieve

もう一つの方法は「urllib.request.urlopen」でファイルを開くのではなく、直接htmlファイルをダウンロードする方法です。

その場合には「urllib.request.urlretrieve(’保存先のファイル名’, ‘保存するURL’)」を使います。

import urllib

url = 'https://3pysci.com'
html_out = './3pysci_retrieve.html'

urllib.request.urlretrieve(url, html_out)

もしhtmlファイルを保存するのが主目的ならこちらの方が楽かもしれません。

さてこれでWebページの情報が取得できるようになりました。

次にWebページの解析を色々と試していきますが、今回、単にWebページの情報の取得ではなく、「保存」としたのは理由があります。

保存をせずに解析のために何度もWebページにアクセスすると、相手のサーバーに無用な負荷をかけてしまうことになります。

あまり負荷をかけすぎてしまうと、サーバーがダウンし、最悪の場合、損害賠償なんて話にもなりかねません。

そのため一度Webページの情報を自分のローカル(PC上)に保存し、それを解析することで負荷をかけないようにするわけです。

もし他のサイトで試すのが怖い方がいらしたら、3PySciを使っていただいても構いませんが、先ほども毎秒何十回もアクセスするようなやり方をしないようにご注意ください。

ということで次回からはWebページを解析する方法を色々と試していきましょう。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次