클라이언트가 요청할 때에도 타입이라는 것이 존재.
- 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) // 서버에서 준 결과를 이용해서 나머지 코드를 작성
}
})
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/web/api/movie",
data: {},
success: function(response){
console.log(response['movies'])
}
})
메소드에서 명령을 내린다. response값들 중 '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)
}
}
})
$.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 매개변수를 좀 더 디테일하게 지정해 줄 수 있다.
let star_image = '⭐'.repeat(star) 이미지를 반복시킬 때 사용하는 매소드를 잘 기억해뒀다가 활용해보자.
$('#기존에있는내용(id값)').empty(''); 기존에 있던 내용을 지워주는 메소드.
파이썬 기본 문법
변수&기본연산
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,해당하는 이름이 없습니다. ** 질문 : for와 def의 차이는 무엇인가? ** 파이썬에서의 for과 js에서의 for문의 차이(문법적인 부분) for 변수 in 리스트(또는 튜플, 문자열): ** 파이썬에서의 if문 ** return의 역할. 어디서 정보를 결과값을 보이게 되는것인지. ** people['name']이라는 표기는 = for person in people: if person['name'] 이것과 같은가? ** 그런데 같은 정보를 이렇게 다양한 for와 if를 사용한 것은 반복문을 통한 결과값을 도출하기 위해서인가?
** 파이썬에서 사용하는 함수가 다른 이유:
각 언어마다 쓰이는 라이브러리가 다르다.
** 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
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의 자료형태가 딕셔너리이기 때문인가?
** 자료 형태가 중요한 이유 : 리스트형, 딕셔너리형
불러오는 방식이 달라지는가? 불러오는 자료가 달라지는가?
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. 함수에 아무값도 리턴하지 않고 끝낼때 사용되기도 한다
# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')
soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')
# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')
# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')
웹스크래핑 더 해보기 (순위, 제목, 별점)
내가 작성한 답안지
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:를 쓰는지 이해가 안된다. 해결 답안지를 한번 봐야할것 같다.