買ってきました!
1章2章がクローリングとスクレイピング。これは何とかなりそう。
3章からチャレンジしました。
#テキストデータとバイナリデータ
###テキストデータ
人間が読みやすい形
###バイナリデータ
機械が使うのに合理的な形
どう違うか見てみます。バイナリで出力するプログラムを作ります。
filename=“binary.bin”
data=100
with open(filename, ”wb”) as f:
f.write(bytearray[data])
ありゃ、うごかない!
python test.py
File "test.py", line 1
filename=“binary.bin”
^
SyntaxError: invalid character in identifier
このエラーはというと、
invalid character in identifier のエラー
全角?半角?Pythonにわからない文字が入っているようです。
仕方ない、一行まるまる書き換えて・・・
$ python test.py
File "test.py", line 3
with open(filename, ”wb”) as f:
^
SyntaxError: invalid character in identifier
また書き換えて
またエラー
$ python test.py
Traceback (most recent call last):
File "test.py", line 4, in <module>
f.write(bytearray[data])
TypeError: 'type' object is not subscriptable
リストのタイプが違う???
うーん、わからん。
ともかくもう一回書き換えて実行。
filename='binary.bin'
data=100
with open(filename, ) as f:
f.write(bytearray[data])
ようやくちゃんと実行できました。
$ ls
binary.bin
$ cat binary.bin
d
$ hexdump binary.bin
0000000 64
0000001
おおー
なるほど!
ただし、1bitを削る時代ではないので、今時はテキストでよいそうです。
#文字コード
Shift_JIS(改行CR+LF)、UTF-8(改行 LF)→よく見る。
HTMLでは<meta charaset=“文字セット名”>
で指定する。
HTML5はUTF-8が推奨。Excelで開くとこんがらかるやつだ!
#XML
タグで囲んでデータをタグ付けする仕様。
<要素名 属性=“属性値”>
内容</要素名>
##練習)横浜市の防災データを読む。
###URLが変わっていた。横浜市、オープンデータ推進ページにまとまってて使いやすい。
https://www.city.yokohama.lg.jp/kurashi/bousai-kyukyu-bohan/bousai-saigai/bosai/data/data.html
###ダウンロードがZipファイルだったので解凍する
with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
existing_zip.extractall('data/temp/ext')
まずはお手本を見ながらざくざく書いてみる。
from bs4 import Beautifulsoup
import urllib.request as req
import os.path
#XMLをダウンロード
url="https://www.city.yokohama.lg.jp/kurashi/bousai-kyukyu-bohan/bousai-saigai/bosai/data/data.files/0001_20180911.zip"
#Zipがなければダウンロード、あればパス
zipname="0001_20180911.zip"
savename="shelter.xml"
if not os.path.exists(zipname):
req.urlretrieve(url, zipname)
#Zipを解凍
with zipfile.ZipFile('0001_20180911.zip') as existing_zip:
existing_zip.extractall()
#Beautifulsoupで解析
xml = open(savename, "r", encording="utf-8").read()
soup = Beautifulsoup(xml, 'html.parser')
#データを各区ごとに確認
##辞書infoを初期化
info={}
#shelterタグをiに入れて1つづつ見ていく
for i in soup.find_all("shelter"):
name = i.find('name').string #建物名
ward = i.find('ward').string #区
addr = i.find('address').string #住所
note = i.find('notes').string #メモ
#辞書infoに収録されていないward(区)だったら区を追加する。
if not (ward in info):
info[ward] =[]
#区ごとに項目を追加する
info[ward].append(name)
#区ごとに防災拠点を表示
for ward in info.keys():
print("+", ward)
for name in info[ward]:
print("| - ", name)
さて実行!
###1回目
大文字小文字が違ってた!
Beautifulsoup→BeautifulS
oup
$ python xml-bousai-r.py
Traceback (most recent call last):
File "xml-bousai-r.py", line 1, in <module>
from bs4 import Beautifulsoup
ImportError: cannot import name 'Beautifulsoup' from 'bs4' (/anaconda3/lib/python3.7/site-packages/bs4/__init__.py)
###2回目
zipfileをimportしてなかった!
$ python xml-bousai-r.py
Traceback (most recent call last):
File "xml-bousai-r.py", line 14, in <module>
with zipfile.ZipFile('0001_20180911.zip') as existing_zip:
NameError: name 'zipfile' is not defined
###3回目
encording
???
encoding
でした!
$ python xml-bousai-r.py
Traceback (most recent call last):
File "xml-bousai-r.py", line 19, in <module>
xml = open(savename, "r", encording="utf-8").read()
TypeError: 'encording' is an invalid keyword argument for open()
###4回目
ファイルがない?
$ python xml-bousai-r.py
Traceback (most recent call last):
File "xml-bousai-r.py", line 19, in <module>
xml = open(savename, "r", encoding="utf-8").read()
FileNotFoundError: [Errno 2] No such file or directory: 'shelter.xml'
どうやってもpythonでunzipできない、ギブアップ。
$ unzip 0001_20180911.zip
Archive: 0001_20180911.zip
inflating: shelter.xml
###5回目
またしてもBeautifuls
oup
$ python xml-bousai-r.py
Traceback (most recent call last):
File "xml-bousai-r.py", line 20, in <module>
soup = Beautifulsoup(xml, 'html.parser')
NameError: name 'Beautifulsoup' is not defined
###6回目
$ python xml-bousai-r.py
+ 鶴見区
| - 生麦小学校
| - 豊岡小学校
| - 鶴見小学校
| - 潮田小学校
| - 下野谷小学校
(以下略)
できました!
解析した結果は辞書{}に入れる、これは良い収穫でした。
###機械学習の道のりが遠い・・・
さて、気を取り直して。
###JSONとは
Javascript Objecct Notationの略。Javascriptのオブジェクトの表記法をベースにしている。単純で使いやすい。Pythonの標準モジュールで使える。
表記法の例)
数値 そのまま。30
文字列 “”でくくる。”str”
真偽型 true/false
配列 [n1,n2,n3,,,]
オブジェクト {“key”:value, “Key”:value, …}
Null null
###PythonでJSONの解析
import urllib.request as req
import os.path, random
import json
#JSONデータをダウンロード
#urlを指定
url = "http://api.aoikujira.com/hyakunin/get.php?fmt=json"
#ファイル名
savename ="hyakunin.json"
#もしダウンロード済みだったら実行しない
if not os.path.exists(url):
#ファイルがなければ実行する。
req.urlretrieve(url, savename)
#ファイルを読み込む
data=json.load(open(savename, "r", encoding="utf-8"))
#ランダムに一首表示
r=random.choice(data)
print(r['kami'], r['simo'])
おおっ一発でできた!
###JSON形式を書き出す
import json
price = {
"date": "2019/08/24",
"price": {
"Apple": 80,
"Orange": 55,
"Banana": 40
}
}
s=json.dumps(price)
print(s)
簡単だからできると思ったらエラー。
どこをどうみても間違っていないはず・・・???
$ python json.py
Traceback (most recent call last):
File "json.py", line 1, in <module>
import json
File “…../json.py", line 12, in <module>
s=json.dumps(price)
AttributeError: module 'json' has no attribute 'dumps'
AttributeError
で調べたら、importしたいモジュールと同じファイル名だと、ファイルの方を読みに行ってこけるらしい。何ということでしょう。。。
ファイル名を変えるだけでいいの?
$ mv json.py test.py
$ python test.py
{"date": "2019/08/24", "price": {"Apple": 80, "Orange": 55, "Banana": 40}}
できました!
YAML、CSV、Excel SQLite、MySQLはやった事があるので省略。
Docerはどっかでやってみたい。TinyDB、MongoDBは便利そう。
1、2、3章ざっくり完了です。
(所要時間 4時間)