pythonからwebにアクセスして情報を取得するために_requests

はじめに

WEBから降水確率を取得して毎朝デスクトップ上に通知させたいと思ってます
YahooAPIを取得してGithubリポジトリを登録するまで気合いMAXで行いましたが、 YahooAPIでは60分後までの降水確率しか取得できないと判明...

天気予報は洗濯物のために使ってる私は1日分欲しいので色々調べた結果、
気象庁が公開している気象情報をXMLにしてくれている方がいました。
これなら6時間毎の降水確率がわかりそう

気象庁の天気予報情報を XML で配信 - drk7jp

ということでこちらのページにアクセスして情報を取得したいと思います。
まずpython web xml 取得で検索して色々調べた結果urllibとかrequestsとかいうモジュールを使えば良さそう
これらのモジュールは何ができるのか、何を得られるのかを調べてみます

WEBへのアクセスについての知識

インターネットへのアクセスは、
1. 私たちが使ってるWEBブラウザからWEBページが存在するWEBサーバにリクエストを送る
2. WEBサーバはリクエストに対してレスポンスを返す
3. そのレスポンスを元にWEBブラウザはページを開くことができる
という流れで行われているらしい

WEBでリクエストとレスポンスを行う為に、HTTPという通信プロトコル(約束事)が決められてる。そのためHTTPリクエスト、HTTPレスポンスとも呼ぶ

HTTPリクエス

HTTPリクエストは「リクエストライン」「リクエストヘッダ」「リクエストメッセージボディ」から構成される

  • ライン
    HTTPリクエストの1行目に書かれている
    [メソッド] [URL] [HTTPバージョン]で構成される
    メソッドにはPOST(値がボディにつく)やGET(値がURLにつく)があるらしい
    requestモジュールかなにかのリファレンスでPOSTかGETか指定できるメソッドがあったので実際使う場面が出てきたら覚えたい

  • ヘッダ
    HTTPリクエストの際のお願い事とかが書いてある

  • メッセージボディ
    HTTPリクエストの際のメモ書

HTTPレスポンス

HTTPレスポンスは「ステータスライン」「レスポンスヘッダ」「レスポンスボディ」から構成される

  • ライン
    HTTPレスポンスの1行目に書かれている [HTTPバージョン] [ステータスコード=結果] [ステータスコードの詳細]で構成される
    ステータコードはwikipediaに乗っている → wiki
    とりあえず200なら成功してるってことみたい

  • ヘッダ
    ファイルの情報を示す情報()とかが書いてあるところ

  • ボディ
    HTMLの中身が入ってる



    さて、webにアクセスする際の知識を得たところで、pythonに戻る
    webにアクセスできるurllibrequestはHTTP通信を行うためのモジュール
    HTTPレスポンスを得ることができるのかな?

urllibはpythonに最初から入っているがurllibの公式リファレンスによるとrequestのほうが使い勝手がいいみたい
requestを使ってみることにした

requestsモジュールの概要

Requests: 人間のためのHTTP — requests-docs-ja 1.0.4 documentation

ここからは公式リファレンスのクイックスタートガイドに沿ってrequestsを試してみる

requestsはurllibよりも人間にわかりやすいらしい
まずはインストールしてから呼び出す

$ pip install requests
import requests

URLを指定してURLレスポンスを取得

r = requests.get('https://www.drk7.jp/weather/xml/08.xml')
print(r)

取得したレスポンスをそのまま出力したらステータスコードがでた↓

<Response [200]>

取得したHTTPレスポンスで何ができるのか

  • レスポンスの内容 requestsはサーバから得た内容を勝手に復元(デコード)してくれる。 HTTPリクエストを作成したら、requestsはリクエストヘッダに入ってる情報に基づいて円コーディングする。エンコディングしたデータは変数.textで得ることができる
r.text

結果↓

<?xml version="1.0" encoding="UTF-8"?>
<weatherforecast>
<title>weather forecast xml</title>
<link>http://www.drk7.jp/weather/xml/08.xml</link>
<description>æ°è±¡åºã®å¤©æ°äºå ±æå ±ã XML ã§éä¿¡ã1æ¥1å AM 6:00 ããæ´æ°ã</description>
<pubDate>Thu, 21 Jun 2018 18:00:02 +0900</pubDate> 
<author>æ°è±¡åº</author>
<managingEditor>drk7.jp</managingEditor>
<pref id="è¨åç">

    <area id="åé¨">
    <geo>
        <long>140.4021</long>
.........

文字化けしてる!
ググって以下記事を拝見

kanji.hatenablog.jp

以下のとおり記入することで解決(詳しい原因は調べてない)

r.encoding = r.apparent_encoding
print(r.text)

↓↓

<?xml version="1.0" encoding="UTF-8"?>
<weatherforecast>
<title>weather forecast xml</title>
<link>http://www.drk7.jp/weather/xml/08.xml</link>
<description>気象庁の天気予報情報を XML で配信。11回 AM 6:00 ごろ更新。</description>
<pubDate>Thu, 21 Jun 2018 18:00:02 +0900</pubDate> 
<author>気象庁</author>
<managingEditor>drk7.jp</managingEditor>
<pref id="茨城県">

    <area id="北部">
    <geo>
        <long>140.4021</long>
        <lat>36.3980</lat>

OK~!


エンコーディング変数.eoncodingで調べることができる

r.encoding

↓↓

ISO-8859-1  #encodingにapparent_encodingを指定する前
utf-8 #指定した後


レスポンスのステータスコードを知ることもできる
ステータスコードの意味は先程書いたようにWikipediaにある

r.status_code

↓↓

200


レスポンスヘッダーをみる

r.headers

↓↓

{'Content-Type': 'text/xml', 'Accept-Ranges': 'bytes', 'ETag': '"3863184871"', 'Last-Modified': 'Thu, 21 Jun 2018 09:00:11 GMT', 'Content-Length': '8839', 'Date': 'Thu, 21 Jun 2018 10:03:43 GMT', 'Server': 'lighttpd/1.4.33'}

辞書で取得できるためキーを指定して値を取得できるようだが、大文字でも小文字でもOKみたい
特に今は使わなそうなのでハショリます

URLにパラメータを渡す

APIを使うときにパラメータを指定させることで特定の条件の商品などを取得できるみたい
今回は余裕がないのでまたあとで...
参考:http://bty.sakura.ne.jp/wp/archives/1157


とりあえず今回はxmlをテキスト化することができたので以上。
次はxmlの中の値を取得します