Pythonを一から勉強してデータ分析できるようになる

~ Pythonとデータ分析のお勉強の記録 ~

リスト、タプル、ディクショナリ:メソッド

 

[Take1] リスト末尾に値を追加 append

 

【書式】

リスト.append(値)

 

【コード】

# リストを作る
list1=[100,"20",30,40,50]
 
# 「天才」と言う文字列を末尾に追加
list1.append("天才")
 
# 結果を表示
print(list1)

 

【結果】

[100, '20', 30, 40, 50, '天才']

 

 

[Take2] リストの指定位置に値を追加 insert

 

【書式】

リスト.insert(位置, 値)

 

【コード】

# リストを作る
list1=[100,"20",30,40,50]
 
# 「天才」と言う文字列を3番目に追加
list1.insert(2,"天才")
 
# 結果を表示
print(list1)

 

【結果】

[100, '20', '天才', 30, 40, 50]

 

 

[Take3] リストの指定要素を削除

 

【書式】

リスト.pop(位置)
「位置」デフォルトはリスト末尾

 

【コード】

# リストを作る
list1=[100,"20",30,40,50]
 
# 2番目を削除
list1.pop(1)
 
# 結果を表示
print(list1)

 

【結果】

[100, 30, 40, 50]

 

 

[Take4] 指定した要素のインデックスを調べる index

 

【書式】

リスト.index(値)

 

【コード】

# リストを作る
list1=[100,"20",30,40,50,30]
 
# 50 のインデックスを調べる
print(list1.index(50))
 
# 30(複数存在) のインデックスを調べる
print(list1.index(30))
 
 
# 100 のインデックスを調べる
print(list1.index(1000))

 

【結果】

4
2
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in ()
10
11 # 100 のインデックスを調べる
---> 12 print(list1.index(1000))
 
ValueError: 1000 is not in list

 

値が複数存在する場合は、最初のインデックスが返ってくる。

値が存在しない場合はエラーが返ってくる

 

[Take5] リストの並び替え sort

 

【書式】

リスト.sort()
デフォルトで昇順、「reverse=True」オプションを設定すると降順になる。

 

【コード】

# リストを作る
list1=[100,20,30,40,50,30]
 
# 昇順に並び替える
list1.sort()
print(list1)
 
# 降順順に並び替える
list1.sort(reverse=True)
print(list1)

 

【結果】

[20, 30, 30, 40, 50, 100]
[100, 50, 40, 30, 30, 20]

 

要素に文字列が混在するとエラーになることに注意する。

 

[Take6] リストを逆順に並び替える reverse

 

【書式】

リスト.reverse()
単純に並び順をかえるため、文字列の混在も可能。

 

【コード】

# リストを作る
list1=[100,"20",30,40,50,30]
 
# 逆順に並び替える
list1.reverse()
print(list1)

 

【結果】

[30, 50, 40, 30, '20', 100]

 

 

[Take7] リストをコピーする copy

 

【書式】

リスト.copy()
結局、dfのところでもやった通り、他変数への代入はオリジナルを参照しているだけということに注意しておけばよさそう。

 

【コード】

# リストを作る
list1=[100,"20",30,40,50,30]
list2=list1
 
# list2 の2番目の要素を「天才」に変更する
list2[1]="天才"
 
# 結果を表示
print(list1)
print(list2)
 
# copyメソッドを使って、list1の複製をlist2として作成する
list3=[100,"20",30,40,50,30]
list4=list1.copy()
 
# list2 の2番目の要素を「天才」に変更する
list4[1]="天才"
 
# 結果を表示
print(list3)
print(list4)
 
# 各リストのオブジェクトIDを表示する
print("list1:",id(list1))
print("list2:",id(list2))
print("list3:",id(list3))
print("list4:",id(list4))

 

【結果】

[100, '天才', 30, 40, 50, 30]
[100, '天才', 30, 40, 50, 30]
[100, '20', 30, 40, 50, 30]
[100, '天才', 30, 40, 50, 30]
list1: 134216732946240
list2: 134216732946240
list3: 134216732849728
list4: 134216732845952

 

リスト、タプル、ディクショナリ:関数と演算子

[Take1] データ構造の要素の数を返す len() 関数

 

【書式】

len(オブジェクト)

 

【コード】

# リストを作る
list1=[10,20,30,40,50]
 
# リストの要素の合計を表示する
print(sum(list1))
 
# リストの要素数を表示する
print(len(list1))
 
# リスト内要素の平均を表示する
print(sum(list1)/len(list1))

 

【結果】

150
5
30

 

 

[TAke2] データ構造の要素を並び替える sorted()関数

 

【書式】

sorted(オブジェクト, reverse="True")
reverse:降順の時「True」を指定する

 

【コード】

# リストを作る
list1=[100,20,30,40,50]
 
# リストの要素を昇順に並び替える
print(sorted(list1))
 
# リストの要素を降順に並び替える
print(sorted(list1,reverse=True))
 
# リストを表示する
print(list1)

 

【結果】

[20, 30, 40, 50, 100]
[100, 50, 40, 30, 20]
[100, 20, 30, 40, 50]

 

list1自体の並びは変わっていないことに注意。このあたりは、dfの処理でやってきたことと同じ。

 

[Take3] データ構造に所定文字列があるか否かを調べる in 演算子

 

【書式】

検索文字列 in データ構造(リストなど)
戻り値:True/False
※反対(文字列が無いことを調べる)
検索文字列 not in データ構造(リストなど)

 

【コード】

# リストを作る
list1=[100,"20",30,40,50]
 
# 「天才」と言う文字列がリストにあるか調べる
print("天才" in list1)
 
# 「20」と言う文字列がリストにあるか調べる
print("20" in list1)
 
# 「30」という文字列が無いことを調べる
print("20" not in list1)

 

【結果】

FALSE
TRUE
FALSE

 

 

[Take4] タプルやディクショナリで試してみる

 

【書式】

 

【コード】

# タプルを作る
tuple1=(10,"20",30,40,50)
 
# 「20」と言う文字列がタプルにあるか調べる
print("20" in tuple1)
 
# ディクショナリを定義
dict1={
    "国語":100,
    "数学":80,
    "理科":70,
    "社会":90,
    "英語":90
}
 
# 「国語」と言う文字列がタプルにあるか調べる
print("国語" in dict1)

 

【結果】

TRUE
TRUE

 

リスト、タプル、ディクショナリ

よく見かけるので、定義のようなものを整理しておく。

 

【書式】

リスト:値の集合、編集可能

 

【コード】

# リストを作る
list1=[10,20,30,40,50]
 
# リストを表示する
print(list1)
print(type(list1))
 
# リストの2番目の要素を表示する
print(list1[1])
 
# リストの2番目の要素を変更する
list1[1]=100
print(list1)

 

【結果】

[10, 20, 30, 40, 50]
<class 'list'>
20
[10, 100, 30, 40, 50]

 

 

[Take2] タプルの操作

 

【書式】

タプル:値の集合、変更不可

 

【コード】

# タプルを作る
tuple1=(10,20,30,40,50)
 
# タプルを表示する
print(tuple1)
print(type(tuple1))
 
# タプルの2番目の要素を表示する
print(tuple1[1])
 
# タプルの2番目の要素を変更する
tuple1[1]=100
print(tuple1)

 

【結果】

(10, 20, 30, 40, 50)
<class 'tuple'>
20
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
10
11 # タプルの2番目の要素を変更する
---> 12 tuple1[1]=100
13 print(tuple1)
 
TypeError: 'tuple' object does not support item assignment

 

タプルの内容は変更できないということ

 

[Take3] タプルの入れ子構造

 

【書式】

タプルの要素を数値ではなく、タプルにすることが可能

 

【コード】

# タプルを作る
tuple1=*1
 
# タプルを表示する
print(tuple1)
print(type(tuple1))
 
# タプルの2番目の要素を表示する
print(tuple1[1])
 
# タプルの3番目の要素の、1番目を表示する
print(tuple1[2][0])

 

【結果】

<class 'tuple'>
(60, 70, 80, 90, 100)
110

 

 

[TAKE4 ]リストの入れ子構造~要素としてタプルを置いてみる

 

【書式】

リストの要素を数値ではなく、タプルにすることも可能。異なる形式の混在も可能。

 

【コード】

# リストを作る
list1=[(10,20,30,40,50),(60,70,80,90,100),(110,120,130,140,150)]
 
# リストを表示する
print(list1)
print(type(list1))
 
# リストの2番目の要素を表示する
print(list1[1])
 
# リストの3番目の要素の、1番目を表示する
print(list1[2][0])
 
# リストの2番目の要素を変更する
list1[1]=100
print(list1)

 

【結果】

[(10, 20, 30, 40, 50), (60, 70, 80, 90, 100), (110, 120, 130, 140, 150)]
<class 'list'>
(60, 70, 80, 90, 100)
110
[(10, 20, 30, 40, 50), 100, (110, 120, 130, 140, 150)]

 

 

[Take5] リストの要素としてのタプルの値を変更してみる

 

【書式】

 

【コード】

# リストを作る
list1=[(10,20,30,40,50),(60,70,80,90,100),(110,120,130,140,150)]
 
# リストを表示する
print(list1)
print(type(list1))
 
# リストの2番目の要素を表示する
print(list1[1])
 
# リストの3番目の要素の、1番目を表示する
print(list1[2][0])
 
# タプルの3番目の要素の、1番目を変更する
list1[2][0]=1
print(list1)

 

【結果】

[(10, 20, 30, 40, 50), (60, 70, 80, 90, 100), (110, 120, 130, 140, 150)]
<class 'list'>
(60, 70, 80, 90, 100)
110
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
13
14 # タプルの3番目の要素の、1番目を変更する
---> 15 list1[2][0]=1
16 print(list1)
 
TypeError: 'tuple' object does not support item assignment

 

結局、タプルの中身は変更できないということが確認できた。

 

[take6] ディクショナリ形式

 

【書式】

ディクショナリ:項目名と値のセット。要素の更新が可能。

 

【コード】

# ディクショナリを定義
dict1={
    "国語":100,
    "数学":80,
    "理科":70,
    "社会":90,
    "英語":90
}
 
#ディクショナリを表示
print(dict1)
print(type(dict1))
 
# ディクショナリの要素を変更
dict1['数学']=40
print(dict1)

 

【結果】

{'国語': 100, '数学': 80, '理科': 70, '社会': 90, '英語': 90}
<class 'dict'>
{'国語': 100, '数学': 40, '理科': 70, '社会': 90, '英語': 90}

 

*1:10,20,30,40,50),(60,70,80,90,100),(110,120,130,140,150

*2:10, 20, 30, 40, 50), (60, 70, 80, 90, 100), (110, 120, 130, 140, 150

スクレイピング:画像ファイルを読み込んで保存する

ファイル保存の基本的な考え方は次の通りだと思う。

1.保存先ファイルをフルパスで定義する

2.そのファイルに保存するデータを指定する

3.ファイル作成(保存)

 

[Take1] まずは、普通に画像を読み込んで保存する。

 

【書式】

imgdata=requests.get(画像URL)
with open(ファイル名,mode="wb") as f:
f.write(imgdata.content)

 

【コード】

import requests
 
# 画像ファイルを取得する
imgdata=requests.get(image_url)
 
# URLから最後のファイル名を取り出す
filename=image_url.split("/")[-1]
 
# 画像データをファイルに書き出す
with open(filename,mode="wb") as f:
  f.write(imgdata.content)

 

【結果】

 

 

[Tak2] 保存先のフォルダを作成して、保存する。上のプログラムの保存先を、Google Driveにしてみる。

 

【書式】

 

【コード】

import requests
 
# 画像ファイルを取得する
imgdata=requests.get(image_url)
 
# URLから最後のファイル名を取り出す
filename=image_url.split("/")[-1]
filepath="/content/drive/MyDrive/Python_2024/001/" +filename
 
# 画像データをファイルに書き出す
with open(filepath,mode="wb") as f:
  f.write(imgdata.content)

 

【結果】

 

 

[Tak3] ダウンロード用のフォルダを作って保存する方法

 

【書式】

フォルダ作成
フォルダ=Path("フォルダ名")
フォルダ.mkdir(exist_ok=True)

 

【コード】

import requests
from pathlib  import Path
 
# 保存用フォルダを作る
out_folder=Path("download")
out_folder.mkdir(exist_ok=True)
 
# 画像ファイルを取得する
imgdata=requests.get(image_url)
 
# URLから最後のファイル名を取り出す
filename=image_url.split("/")[-1]
# 保存ファイルのフルパスを作成する
out_path=out_folder.joinpath(filename)
 
# 画像データをファイルに書き出す
with open(out_path, mode="wb") as f:
  f.write(imgdata.content)

 

【結果】

 

 

[Take4] 全てのimgタグの画像ファイルURLを表示する

 

【書式】

 

【コード】

import requests
from bs4 import BeautifulSoup
import urllib
 
# webページを取得して解析する
response=requests.get(load_url)
soup=BeautifulSoup(response.content,"html.parser").find(class_="entry-content hatenablog-entry")
 
# 全てのimgタグを検索し、リンクを取得する
for element in soup.find_all("img"):
  src=element.get("src")
 
  # 絶対URLと、ファイルを表示する
  print("タグ:",element)
  print("タグのテキスト:",element.text)
  image_url=urllib.parse.urljoin(load_url,src)
  filename=image_url.split("/")[-1]
  print("URL:",image_url)
  print("ファイル名:",filename)
  print("\n")

 

【結果】

タグのテキスト:
ファイル名: 20200614142330.jpg
 
 
タグのテキスト:
ファイル名: 20200614142318.jpg
 
 
タグのテキスト:
ファイル名: 20200614142307.jpg

 

 

[Take5] ページ内の画像を一括ダウンロードする

 

【書式】

1秒待つ
import time
time.sleep(1)

 

【コード】

import requests
from bs4 import BeautifulSoup
from pathlib import Path
import urllib
import time
 
# webページを取得して解析する
response=requests.get(load_url)
soup=BeautifulSoup(response.content,"html.parser").find(class_="entry-content hatenablog-entry")
 
# 保存用フォルダを作成する
out_folder=Path("/content/drive/MyDrive/Python_2024/001/download")
out_folder.mkdir(exist_ok=True)
 
# 全てのimgタグを検索し、リンクを取得する
for element in soup.find_all("img"):
  src=element.get("src")
 
  # 絶対URLを作って、画像データを取得する。
  image_url=urllib.parse.urljoin(load_url,src)
  imgdata=requests.get(image_url)
 
  # URLからファイル名を取り出して、保存フォルダ名とつなげる
  filename=image_url.split("/")[-1]
  out_path=out_folder.joinpath(filename)
 
  # 画像データを、ファイルに書き出す。
  with open(out_path,mode="wb") as f:
    f.write(imgdata.content)
 
  # 1回アクセスしたので1秒待つ
  time.sleep(1)

 

スクレイピング:オーディオヴィジュアル製品のパッケージ画像URLを取得する

商品コードを検索キーにして、商品紹介ページにあるパッケージ画像のURLを取得したい。

amazonとかの著名ecサイトでは弾かれてしまうが、一応、動作したのでメモしておく。

(実際URLは伏せておく)

 

[TAKE1] まずは、コード番号から検索用のURLを生成し、そのリンク先のURLを取得する。

 

【考え方】

1.検索URLにおける次のタグを捕まえるのが目的。
 
<h2 class="entry-title"><a href="https://site1.com/374040/PNO-684">[PNO-684] ないすですね~</a></h2>
 
2.「soup.find(class_="entry-title")」で、定う術タグ全体を捕まえたのち、
 
3.「.select("a")」で、その中にあるaタグを取得。
 
4.次に、aタグの中の[href]の属性値を取得する感じ。

 

【コード】

import requests,bs4,time
 
result  = requests.get("https://site1.com/?s=PNO-684")
soup    = bs4.BeautifulSoup(result.content, "html.parser")
 
# elems   = soup.select("[class='entry-title']")
elems=soup.find(class_="entry-title").select("a")
 
for elem in elems:
    # print(type(elem))
    print(elem)
    # url=elem.select("a")
    # print(type(url))
    url     = elem.get("href")
    print(url)
    #1秒待機する(DoS攻撃になってしまうため)
    time.sleep(1)

 

【結果】

<a href="https://site1.com/374040/PNO-684">[PNO-684] ないすですね~</a> https://site1.com/374040/PNO-684

 

 

[take2] コード番号から、検索用URLを生成する過程を関数化する

 

【書式】

 

【コード】

import requests,bs4,time
 
def search_url(code_no):
  url="https://site1.com/?s=" + code_no
  return url
 
url=search_url("PNO-684")
print(url)

 

【結果】

 

 

[TAKE3] コード番号から、目的サイトのURL生成を関数化する

 

【書式】

 

【コード】

import requests,bs4,time
 
 
def tgt_url(code_no):
  url1  ="https://site1.com/?s=" + code_no
  result  = requests.get(url1)
  soup    = bs4.BeautifulSoup(result.content, "html.parser")
  # class_ はサイトの更新によって変更になる可能性有。
  elems=soup.find(class_="entry-title").select("a")
  for elem in elems:
    url2     = elem.get("href")
 
  return url2
 
 
url=tgt_url("PNO-684")
print(url)

 

【結果】

 

 

[TAKE4] 動画情報サイトのHTMLから目的のカバー画像URLを取得する。

 

【書式】

 

【コード】

import requests,bs4,time
 
result  = requests.get("https://site1.com/374040/PNO-684")
soup    = bs4.BeautifulSoup(result.content, "html.parser")
 
elems=soup.find(class_="entry-content").select("img")
# elems はリスト型なので、最初の要素の「src属性値」を取り出す
elem=elems[0].get("src")
 
print(elem)

 

【結果】

 

各変数の戻り値とデータ型は次の通り

 

[TAKE5] まとめ→ 各々を関数化し、コード番号からカバー画像URLを持ってくる。

 

【書式】

 

【コード】

import requests,bs4,time
 
def tgt_url(code_no):
  # コード番号に該当する動画の説明ページのURLを返す関数
  # 引数:動画コード番号
  # 戻値:動画説明ページURL
  url1  ="https://site1.com/?s=" + code_no
  result  = requests.get(url1)
  soup    = bs4.BeautifulSoup(result.content, "html.parser")
  # class_ はサイトの更新によって変更になる可能性有。
  # sou.findはリストを返すので、末尾に[0]をつけて一番目の要素を指定する
  elem=soup.find(class_="entry-title").select("a")[0]
  url2 = elem.get("href")
 
  return url2
 
def img_url(tgt_url):
  # 動画のカバー画像のURLを返す関数
  # 引数:動画説明URL
  # 戻値:カバー画像URL
  result  = requests.get(tgt_url)
  soup    = bs4.BeautifulSoup(result.content, "html.parser")
  elem=soup.find(class_="entry-content").select("img")[0]
  url3=elem.get("src")
 
  return url3
 
url=img_url(tgt_url("PNO-684"))
print(url)

 

【結果】

 

スクレイピング:リンクの抽出と加工

[Take0] とりあえず、リンクタグ(href)を抜き出す。

 

【書式】

値=要素.get("属性名")
 
例)
 
 
 
属性名:a
 
 
値=要素.get("属性名")
例)
属性名:a
 

 

【コード】

import requests
from bs4 import BeautifulSoup
 
# webページを取得して解析する
response=requests.get(load_url)
soup=BeautifulSoup(response.content,"html.parser").find(class_="entry-content hatenablog-entry")
 
 
# classで検索して、その中の全てのaタグを検索して表示する。
for element in soup.find_all("a"):
  print("タグ:",element)
  print("タグのデータ型:",type(element))
  print("タグのテキスト:",element.text)
  url=element.get("href")
  print("リンク:",url)
  print("\n")
 

 

【結果】

タグのデータ型: <class 'bs4.element.Tag'>
タグのテキスト: リンク1
 
 
タグ: <a href="../../../2021/02/07/000000">リンク2</a>
タグのデータ型: <class 'bs4.element.Tag'>
タグのテキスト: リンク2
リンク: ../../../2021/02/07/000000
 

 

# 元HTML

 

<div class="entry-content hatenablog-entry">

  <p> </p>

  <div id="chap1">

    <h2 id="第1章-小旅行の行先検討">第1章 小旅行の行先検討</h2>

    <ol>

      <li>近場が良いか?</li>

      <li>温泉が良いか?</li>

      <li>電車か車か?</li>

    </ol>

  </div>

  <div id="chap2">

    <h2 id="第2章-到着したら科飯にしよう">第2章 到着したら科飯にしよう</h2>

    <ol>

      <li>早速のお食事</li>

      <li>まずは、眺めて楽しもう</li>

      <li>お上品に食べ進めよう</li>

      <li>お酒はほどほどに!</li>

    </ol>

  </div>

  <p>

    <a href="https://20200105.hatenadiary.jp/entry/2021/05/02/000000">リンク1</a>

    <a href="../../../2021/02/07/000000">リンク2</a>

    <br/><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hwk159/20200614/20200614142330.jpg"/>

    <img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hwk159/20200614/20200614142318.jpg"/>

    <img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hwk159/20200614/20200614142307.jpg"/>

  </p>

</div>

 

 

[Take1] 相対URLがまざっているので、を絶対URLに変換する

 

【書式】

urllibライブラリを使用する。
書式)
parse.urljoin(ベースURL,調べるURL)
 

 

【コード】

import requests
from bs4 import BeautifulSoup
import urllib
 
# webページを取得して解析する
response=requests.get(load_url)
soup=BeautifulSoup(response.content,"html.parser").find(class_="entry-content hatenablog-entry")
 
 
# 全てのaタグを検索して、リンクを絶対URLで表示する。
for element in soup2.find_all("a"):
  print("タグ:",element)
  print("タグのデータ型:",type(element))
  print("タグのテキスト:",element.text)
  url=element.get("href")
  print("リンク:",url)
  # 相対URLを書き換え
  link_url=urllib.parse.urljoin(load_url,url)
  print("補正後URL:",link_url)
  print("\n")
 

 

【結果】

タグのデータ型: <class 'bs4.element.Tag'>
タグのテキスト: リンク1
 
 
タグ: <a href="../../../2021/02/07/000000">リンク2</a>
タグのデータ型: <class 'bs4.element.Tag'>
タグのテキスト: リンク2
リンク: ../../../2021/02/07/000000
 

 

戻り値を整理しておく。

 

[Take2] このリンクのリストをテキストファイルに書き出してみる。

 

【書式】

f=open(filename,mode="w")
f.write(書き込む値)
f.close()
 

 

【コード】

import requests
from bs4 import BeautifulSoup
import urllib
 
# webページを取得して解析する
response=requests.get(load_url)
soup=BeautifulSoup(response.content,"html.parser").find(class_="entry-content hatenablog-entry")
 
 
# ファイルを書き込みモードで開く
filename="/content/drive/MyDrive/Python_2024/001/linklist.txt"
 
with open(filename,"w") as f:
  # 全てのaタグを検索し、リンクを絶対URLで書き出す
  for element in soup.find_all("a"):
    url=element.get("href")
    link_url=urllib.parse.urljoin(load_url,url)
    f.write(element.text+"\n")
    f.write(link_url+"\n")
    f.write("\n")
 

 

【結果】

 

 

スクレイピング:実際のニュースサイトのトピックリスト取得

yahooニュースのトピックリスト情報の取得

 

【書式】

問題あると困るのでアドレスは架空のもので記述する。

 

【コード】

import requests
from bs4 import BeautifulSoup
 
# webページを取得して解析する
html=requests.get(load_url)
soup=BeautifulSoup(html.content,"html.parser")
 
# classで検索範囲を絞って、その中の全てのaタグを検索して表示する。
topic=soup.find(class_="**************")
for element in topic.find_all("a"):
  print(element.text)

 

【結果】

デジタル制限 不登校克服した小6
正恩氏プロパガンダSNSで流行
詐欺広告 誘われてみて見えた手口
生成AIが病気「診断」 ばらつきも
AI偽情報へ対処求める OECD声明
首相 生成AIの国際的枠組みを表明
円安が逆風 iPadの値上げは
プーさん舞台 改善策でまた物議
もっと見る

 

トピックスリストのclass名の取得が割と面倒。chromeデベロッパモードで、該当箇所を選択。コード表示領域で色付けされた箇所が該当する。その中の、class タグの名称を取得する感じ。もう、全然関係ない名前になってる。