「つくってマスターPython」で勉強日記#3

【出典】[つくってマスターPython](https://www.amazon.co.jp/%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BCPython-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%BBWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%BB%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%83%BB%E6%96%87%E6%9B%B8%E5%87%A6%E7%90%86%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4297110342)
[前回の続きです](https://qiita.com/kato_squalldeka/items/9bf491cbb13114df0734)

# chapter5 webから情報を取得する
# 5-1request/requestsによるスクレイピング
最初はrequestとrequestsでスクレイピングを学習しました。
正直これは話半分でもいいかなと思うのですが、正規表現を使っているようなので、確認程度にやっています。

requestによるデータの取得

```python:リスト5-1　

from urllib import request
import chardet

with request.urlopen('https://www.tuyano.com/index2?id=505001') as response:
    body = response.read()
    cs = chardet.detect(body)
    data = body.decode(cs['encoding'])
    print(data)
```
requestsによるデータの取得

```python:リスト5-2
import requests

result = requests.get('https://www.tuyano.com/index2?id=505001')
print(result.text)
```

クエリ―パラメーターを含んだアクセス(取得)

```python:リスト5-3
import requests

address = 'https://www.tuyano.com/index3'
prm = {'id':511001, 'page':1}
result = requests.get(address ,params=prm)

print(result.text)
```

正規表現とスクレイピングを組み合わせる

```python:リスト5-4
import requests
import re #正規表現をタグの抜き出しに利用

result = requests.get('https://www.tuyano.com/')
deta = result.text

#記述はhrefがタグの属性として一番最初に来ることを想定し簡略化
fdata = re.findall(r'<a href="([\w \?/:%#&~\$\.=+\-@]*)"', data)
print(fdata)
print('*** link adress ***')
for item in fdata:
    print(item)
```

画像のダウンロード

```python:リスト5-5
import requests
import re

domain = 'https://www.tuyano.com'
resp = requests.get(domain + '/index3?id=511001')
data = resp.text


#記述はsrcがタグ属性として一番最初にくることを想定し簡略化
fdata = re.findall(r'<img src\s*=\s*"([^"]+)"', data)
'''
r：raw文字列
'
<img src：文字列
\s：任意の空白文字
*：ゼロ以上続く
=：文字列
\s：任意の空白文字
*：ゼロ以上続く
"([^"]+)"：^と"の集合が1回以上続くグループ
'
'''

print('*** image address ***')
n = 1


for item in fdata:
    result = requests.get(domain + item)
    fname = "saved_" + str(n)
    ctype = result.headers['Content-Type'] #ファイルの種類
    if (ctype == "image/jpeg"):
        fname += ".jpg"
    if (ctype == "image/png"):
        fname += ".png"
    if (ctype == "image/gif"):
        fname += ".gif"
    with open(fname, 'wb') as file:
        file.write(result.content)
        print("save file" + fname)
    n += 1
```

**パターンの書き方を覚える**
正規表現を利用するとき、最大のポイントとなるのが、｢パターン｣です。適切なパターンを用意できれば想像以上に複雑な文字列処理が行えるようになります。正規表現を使うには、特殊文字の働きと使い方を覚える必要があります。

|機能|特殊文字|説明|
|-|-|-|
|任意の文字| . |任意の文字を表す。｢ ... ｣なら3文字の文字列|
|先頭| ^ |行の先頭を示す。｢^abc｣とした場合abcで始まる文字列|
|末尾|$|行の末尾を示す。｢abc$｣ならばabcで終わる行を表す|
|文字の繰り返し|*, +, ?|*はゼロ以上、+1回以上、？は0または1以上|
|指定した回数の繰り返し|{}|｢a{3}｣は3回繰り返す|
|文字の集合|[]|[abc]はa,b,cの3つの文字の集合。[abc]+とするとabcのいずれかの文字が1つ以上つながった文字列をすべて指定|
|グループ|()|正規表現のグループを示す|
|複数の候補| ｜ |(abc｜xyz)とすれば'abc','xyz'のいずれの文字も指定できる|
|文字の範囲|-|[]内で使われるもので、文字の範囲を指定する|
|それ以外の文字|^|[]内で使われるものでその後の文字以外のものを示す|

|特殊シーケンス|説明|
|-|-|
|\A|文字列の先頭|
|\d|数字を示す|
|\D|数字以外の文字を示す|
|\s|空白文字|
|\S|空白文字以外|
|\w|単語文字|
|\W|単語文字以外|
|\z|文字列の末尾|
|\n|改行を示す|
|\t|タブ文字を示す|

（スクレイピングに関しては実際に完成形作ってから見直したほうが理解が進みやすい気がする。）

本日は以上です。ありがとうございました。