Ajax 기초와 Python

쭈오기단·2023년 1월 31일

항해

목록 보기
5/9

Ajax 문법과 적용

클라이언트가 요청할 때에도 타입이라는 것이 존재.

  • GET 타입 : 데이터 조회를 요청할 때
  • POST 타입 : 데이터를 생성할 때
GET 타입 문법

$.ajax({
  type: "GET",
  url: "여기에URL을입력",
  data: {},
  success: function(response){
    console.log(response)
  }
})

api에 내용을 요청할 때 get으로 요청할때는 이렇게 사용하여 정보를 요청한다. 왜 이렇게 적는지보다는 이렇게 생긴 구조로 정보를 요청한다는 것에 집중해서 보도록 하자.

해석해보기
$.ajax({
  type: "GET", // GET 방식으로 요청한다.
  url: "http://spartacodingclub.shop/sparta_api/seoulair",
  data: {}, // 요청하면서 함께 줄 데이터 (GET 요청시엔 비워두세요)
  success: function(response){ // 서버에서 준 결과를 response라는 변수에 담음
    console.log(response) // 서버에서 준 결과를 이용해서 나머지 코드를 작성
  }
})
  1. 반드시 response라는 변수에 담을 필요는 없다. 변수 이름에 의미를 두지 말자. 여기서 중요한 포인트는 success: 에서 function을 통해 요청한 값을 이름을 정해 받아올 수 있다는 것이다.
  2. 정보의 흐름에 더 포인트를 줘서 이해하려고 노력할 것. 문법 자체는 외울필요가 없다. 이렇게 생긴 문법이 있고 결과는 여기서 나타낸다.

영화 데이터 콘솔에 찍어보기

$.ajax({
  type: "GET",
  url: "http://spartacodingclub.shop/web/api/movie",
  data: {},
  success: function(response){
        console.log(response['movies'])
  }
})

메소드에서 명령을 내린다. response값들 중 'movies'를 콘솔로 보여라.

movies를 돌면서 하나씩 출력시키기

for라는 메소드가 쓰인다.

for : 초기식, 조건식, 증감식을 모두 포함하고 있는 반복문이다.
while보다 좀 더 간결하게 표현할 수 있다. 
for(초기식;조건식;증감식){
조건식 결과가 참인 동안 반복적으로 실행하고자 하는 명령문
	}
$.ajax({
  type: "GET",
  url: "http://spartacodingclub.shop/web/api/movie",
  data: {},
  success: function(response){
        let movies = response['movies']
        for (let i = 0 ; i < movies.length; i++) {
            let movie = movies[i]
            console.log(movie)
        }
  }
})
  1. for문을 설명하자면 i는 0부터 시작한다(초기식).
  2. i는 movies의 길이보다 작다(조건식).
  3. i는 0부터 시작해서 하나씩 증가한다.(증감식)
  4. {movie를 로그에 표현해라. movie는 movies에 i에 해당하는 것이다.(조건결과가 참인동안 반복적으로 실행하고자하는 명령문}

movie 내용을 image, comment,title,desc,star 등 여러가지를 표현할 수 있다.

$.ajax({
    type: "GET",
    url: "http://spartacodingclub.shop/web/api/movie",
    data: {},
    success: function(response){
          let movies = response['movies']
          for (let i = 0 ; i < movies.length; i++) {
              let movie = movies[i]
              let title = movie['title']
              let desc = movie['desc']
              let image = movie['image']
              let comment = movie['comment']
              let star = movie['star']

              let star_image = '⭐'.repeat(star)

              let temp_html = `<div class="col">
                                  <div class="card h-100">
                                      <img src="${image}"
                                           class="card-img-top">
                                      <div class="card-body">
                                          <h5 class="card-title">${title}</h5>
                                          <p class="card-text">${desc}</p>
                                          <p>${star_image}</p>
                                          <p class="mycomment">${comment}</p>
                                      </div>
                                  </div>
                              </div>`
              $('#cards-box').append(temp_html)
          }
    }
  })

i 매개변수를 좀 더 디테일하게 지정해 줄 수 있다.

  • 여기서 사용하는 for,let,append(),movies[i]가 각각 어떤식으로 정보를 보내는지 살펴보면서 이해하면 쉽게 접근할 수 있을것이다.
    let star_image = '⭐'.repeat(star)
    이미지를 반복시킬 때 사용하는 매소드를 잘 기억해뒀다가 활용해보자.
$('#기존에있는내용(id값)').empty('');
기존에 있던 내용을 지워주는 메소드.

Python

파이썬 기본 문법

  • 변수&기본연산

    a = 3      # 3을 a에 넣는다
    b = a      # a를 b에 넣는다
    a = a + 1  # a+1을 다시 a에 넣는다
    num1 = a*b # a*b의 값을 num1이라는 변수에 넣는다
    num2 = 99 # 99의 값을 num2이라는 변수에 넣는다
  • 자료형

숫자,문자형
name = 'bob' # 변수에는 문자열이 들어갈 수도 있고,
num = 12 # 숫자가 들어갈 수도 있고,
is_number = True # True 또는 False -> "Boolean"형이 들어갈 수도 있습니다.
리스트형
a_list = []
a_list.append(1)     # 리스트에 값을 넣는다
a_list.append([2,3]) # 리스트에 [2,3]이라는 리스트를 다시 넣는다
Dictionary 형 
a_dict = {}
a_dict = {'name':'bob','age':21}
a_dict['height'] = 178
Dictionary 형과 List형의 조합
people = [{'name':'bob','age':20},{'name':'carry','age':38}]
person = {'name':'john','age':7}
people.append(person)
  • 함수
함수의 정의 : 이름은 마음대로 정할 수 있다. 수학적 함수와 헷갈리지말자
#수학문제에서
f(x) = 2*x+3
y = f(2)
y의 값은? 7
#참고: 자바스크립트에서는
function f(x) {
	return 2*x+3
}
#파이썬에서
def f(x):
	return 2*x+3
y = f(2)
print(y)
y의 값은? 7
함수의 응용
def sum_all(a,b,c):
	return a+b+c
def mul(a,b):
	return a*b
result = sum_all(1,2,3) + mul(10,10)
print(result)
#result라는 변수의 값은? 106
  • 조건문
함수의 응용1
def oddeven(num):  # oddeven이라는 이름의 함수를 정의한다. num을 변수로 받는다.
	if num % 2 == 0: # num을 2로 나눈 나머지가 0이면
		 return True   # True (참)을 반환한다.
	else:            # 아니면,
		 return False  # False (거짓)을 반환한다.
result = oddeven(20)
print(result)
#result의 값은 무엇일까요? true
함수의 응용2
def is_adult(age):
	if age > 20:
		print('성인입니다')    # 조건이 참이면 성인입니다를 출력
	else:
		print('청소년이에요')  # 조건이 거짓이면 청소년이에요를 출력
is_adult(30)
print(is_adult)
#무엇이 출력될까요? 성인입니다.
  • 반복문 :파이썬에서의 반복문은 리스트의 요소들을 하나씩 꺼내쓰는 형태이다. 무조건 리스트와 함께 쓰인다.
fruits = ['사과','배','감','귤']
for fruit in fruits:
	print(fruit)
#사과, 배, 감, 귤 하나씩 꺼내어 찍힙니다.
응용 : 과일갯수세기
fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
count = 0
for fruit in fruits:
	if fruit == '사과':
		count += 1
print(count)
#사과의 갯수를 세어 보여줍니다. 2

스터디 공부자료

def count_fruits(target):
	count = 0
	for fruit in fruits:
		if fruit == target:
			count += 1
	return count
subak_count = count_fruits('수박')
print(subak_count) #수박의 갯수
gam_count = count_fruits('감')
print(gam_count) #감의 갯수
**질문 : 여기서 target이라는 변수를 따로 지정한 이유.
위에 '사과'와는 무엇이 다른가.
딕셔너리 예제
people = [{'name': 'bob', 'age': 20}, 
          {'name': 'carry', 'age': 38},
          {'name': 'john', 'age': 7},
          {'name': 'smith', 'age': 17},
          {'name': 'ben', 'age': 27}]
#모든 사람의 이름과 나이를 출력해봅시다.
for person in people:
    print(person['name'], person['age'])
#이번엔, 반복문과 조건문을 응용한 함수를 만들어봅시다.
#이름을 받으면, age를 리턴해주는 함수
def get_age(myname):
    for person in people:
        if person['name'] == myname:
            return person['age']
    return '해당하는 이름이 없습니다'
print(get_age('bob'))
print(get_age('kay'))
결과 : 20,해당하는 이름이 없습니다.
** 질문 : fordef의 차이는 무엇인가?
** 파이썬에서의 for과 js에서의 for문의 차이(문법적인 부분)
  for 변수 in 리스트(또는 튜플, 문자열):
** 파이썬에서의 if** return의 역할. 어디서 정보를 결과값을 보이게 되는것인지.
** people['name']이라는 표기는 
   = for person in people:
   		if person['name'] 이것과 같은가?
** 그런데 같은 정보를 이렇게 다양한 forif를 사용한 것은
   반복문을 통한 결과값을 도출하기 위해서인가?

파이썬 자주쓰이는 함수

** 파이썬에서 사용하는 함수가 다른 이유:
   각 언어마다 쓰이는 라이브러리가 다르다.
** Requests패키지를 설치했는데 이건 라이브러리인가?

# 내가 보낸 request 객체에 접근 가능
response.request

# 응답 코드
response.status_code

# 200 (OK 코드)이 아닌 경우 에러 raise
response.raise_for_status()

# json response일 경우 딕셔너리 타입으로 바로 변환
response.json()

# content 속성을 통해 바이너리 타입으로 데이터를 받을 수 있다.
response.content

# text 속성을 통해 UTF-8로 인코딩된 문자열을 받을 수 있다.
response.text

# encoding 정보 확인
response.encoding

파이썬 예제 모든 구의 IDEX_MVL 값을 찍어주자!

import requests # requests 라이브러리 설치 필요

r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()

gus = rjson['RealtimeCityAir']['row']

for gu in gus:
	print(gu['MSRSTE_NM'], gu['IDEX_MVL'])
** gu는 어떻게 'MSRSTE_NM'],['IDEX_MVL']두개의 정보를 불러올 수 있는가?
** gus의 자료형태가 딕셔너리이기 때문인가?
** 자료 형태가 중요한 이유 : 리스트형, 딕셔너리형 
   불러오는 방식이 달라지는가? 불러오는 자료가 달라지는가?

파이썬 예제 IDEX_MVL 값이 60 미만인 구만 찍어주자!

import requests # requests 라이브러리 설치 필요

r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()

gus = rjson['RealtimeCityAir']['row']

for gu in gus:
	if gu['IDEX_MVL'] < 60:
		print (gu['MSRSTE_NM'], gu['IDEX_MVL'])

파이썬 크롤링 기본세팅

import requests
from bs4 import BeautifulSoup

# 타겟 URL을 읽어서 HTML를 받아오고,
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(data.text, 'html.parser')

#############################
# (입맛에 맞게 코딩)
#############################

영화제목 가져와보기

import requests
from bs4 import BeautifulSoup

# URL을 읽어서 HTML를 받아오고,
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
soup = BeautifulSoup(data.text, 'html.parser')

# select를 이용해서, tr들을 불러오기
movies = soup.select('#old_content > table > tbody > tr')

# movies (tr들) 의 반복문을 돌리기
for movie in movies:
    # movie 안에 a 가 있으면,
    a_tag = movie.select_one('td.title > div > a')
    if a_tag is not None:
        # a의 text를 찍어본다.
        print (a_tag.text)
        
** 왜 바로 if문을 빼고 print (a_tag.text)을 사용하지 않는가?
** 왜 반드시 if문으로 None이라는 깡통 변수를 사용하는가?
** 로그인 해야하는 

참고
None 깡통변수
1. 값이 존재하지 않는 변수에 None에 대입하여 이 변수에 아무런 값이 없다는 것을 나타내기 위해 사용될 수 있음.
2. None이 대입된 변수는 아무런 값도 없는 빈 깡동 변수라고 판단할 수 있음.
3. 깡통 = None 으로 선언한 경우 변수 '깡통' 은 아무런 값도 가지지 않음으로 이 변수로는 할 수 있는 것이 없으나,
None으로 지정된 변수에 값이 있는 임의의 자료형을 대입하여 활용할 수 있다
4. 함수에 아무값도 리턴하지 않고 끝낼때 사용되기도 한다

beautifulsoup 내 select에 미리 정의된 다른 방법

# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')

soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')

# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')

# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')

Quiz_웹스크래핑(크롤링) 연습

웹스크래핑 더 해보기 (순위, 제목, 별점)

내가 작성한 답안지

from bs4 import BeautifulSoup
#URL을 읽어서 HTML를 받아오고,
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
#HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
soup = BeautifulSoup(data.text, 'html.parser')
#select를 이용해서, tr들을 불러오기
movies = soup.select('#old_content > table > tbody > tr')
point = soup.select('# old_content > table > tbody')
rank = soup.select('# old_content > table > tbody')
#movies (tr들) 의 반복문을 돌리기
for movie in movies:
    # movie 안에 a 가 있으면,
    a_tag = movie.select_one('td.title > div > a')
    a_point = movie.select_one('td.point')
    a_rank= movie.select_one('img')
    if a_tag is not None:
        # a의 text를 찍어본다.
        print (a_tag.text)
		if a_point is not None:
			# a의 text를 찍어본다.
			print(a_point)
		if a_rank is not None:
			# a의 text를 찍어본다.
			print(a_rank)

당연히 에러가 났다. 정말 머리가 아프다.

import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
#old_content > table > tbody > tr:nth-child(3) > td.title > div > a
#old_content > table > tbody > tr:nth-child(4) > td.title > div > a
movies = soup.select('#old_content > table > tbody > tr')
for movie in movies:
    a = movie.select_one('td.title > div > a')
    if a is not None:
        title = a.text
        rank = movie.select_one('td:nth-child(1) > img')['alt']
        star = movie.select_one('td.point').text
        print(rank, title, star)

오답노트
1. select와 select_one을 잘못 사용했다. 여러번 사용하는 것이 아니라 한번씩 사용해서 원하는 정보를 불러와야 했다.
2. title,rank,star 변수를 잡는 것은 좋았으나 if a is not None:을 여러번 쓰는것도 문제였다. 어차피 같은 내용을 적용시킬 것인데 여러번 사용할 필요가 없었다.
3. 하나씩 만들어 보면서 적용을 했더라면 더 좋았을 것이다.

다시 한번 만들어보며 느낀점 : 파이썬에 완전히 익숙해지진 못한것 같다. 그리고 여전히 if a is not None:를 쓰는지 이해가 안된다. 해결 답안지를 한번 봐야할것 같다.

profile
나는야 해적이 될거야

0개의 댓글