<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
class
를 선택자로 사용id
를 선택자로 사용!!! (항상 헷갈려하던 것)<sytle>
태그에 .mypost
에 대한 css(display: none;
)를 적용해 처음 페이지에 들어가게 되면 박스가 닫혀 있도록 함영화 기록하기
버튼을 통해 열고 닫기
버튼을 통해 닫을 수 있음<head>
<script>
function openbox() {
$('#post-box').show()
}
function closebox() {
$('#post-box').hide()
}
</script>
</head>
<body>
<div class="mytitle">
<h1>내 생애 최고의 영화들</h1>
<button onclick="openbox()">영화 기록하기</button>
</div>
<div class="mypost" id="post-box">
<div class="form-floating mb-3">
<input type="url" class="form-control" id="floatingInput" placeholder="영화 URL">
<label for="floatingInput">영화 URL</label>
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">별점</label>
<select class="form-select" id="inputGroupSelect01">
<option selected>--선택하기--</option>
<option value="1">⭐</option>
<option value="2">⭐⭐</option>
<option value="3">⭐⭐⭐</option>
<option value="3">⭐⭐⭐⭐</option>
<option value="3">⭐⭐⭐⭐⭐</option>
</select>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="코멘트" id="floatingTextarea2"
style="height: 100px"></textarea>
<label for="floatingTextarea2">코멘트</label>
</div>
<div class="mybtn">
<button type="button" class="btn btn-dark">기록하기</button>
<button type="button" class="btn btn-outline-dark" onclick="closebox()">닫기</button>
</div>
</div>
</body>
val()
을 통해 받아와 내용이 있다면 alert
를 통해 내용을 보여주고, 내용이 없다면 입력하세요!
메세지를 띄워줌@
의 여부를 통해 이메일인지 아닌지 파악해 사용자에게 도메인을 반환하는 기능@
가 포함되는지 알 수 있으며, split()을 사용해 지정한 부분을 기준으로 입력값을 두 개로 나눌 수 있다는 아이디어를 통해 작성<body>
태그 안에 있는 리스트에 값을 입력해줌empty()
함수를 통해 입력되어 있는 모든 값을 삭제<head>
<script>
function q1() {
let input = $('#input-q1').val()
if (input == '') {
alert('입력하세요!')
} else {
alert(input)
}
}
function q2() {
let input = $('#input-q2').val()
if (input.includes('@')) {
alert(input.split('@')[1].split('.')[0])
} else {
alert('이메일이 아닙니다.')
}
}
function q3() {
let input = $('#input-q3').val()
let temp_html = `<li>${input}</li>`
$('#names-q3').append(temp_html)
}
function q3_remove() {
$('#names-q3').empty()
}
</script>
</head>
Key : Value
의 구조로 이루어져 있으며, 자료형 Dictionary
와 유사!데이터 조회(Read)
요청데이터 생성(Create), 변경(Update), 삭제(Delete)
요청https://www.musinsa.com/brands/attentionrow?category3DepthCodes=&category2DepthCodes=&category1DepthCode=&colorCodes=&startPrice=&endPrice=&exclusiveYn=&includeSoldOut=&saleGoods=&timeSale=&includeKeywords=%EB%B8%94%EB%A1%9D%EB%B2%84%EC%8A%A4%ED%84%B0%EC%84%B8%EC%9D%BC&sortCode=discount_rate&tags=&page=1&size=90&listViewType=small&campaignCode=&groupSale=&outletGoods=false&boutiqueGoods=
?
을 기준으로 서버 주소
와 정보
로 나뉘어짐?
부터 전달할 데이터가 작성되며, &
은 생긴 그대로 뭔가 할말이 더있다, 즉 전달할 데이터가 더 있다는 뜻!<head>
<script>
$.ajax({
type: "GET", // 요청 타입 작성 (GET or POST)
url: "요청할 url 주소",
data: {}, // 요청하면서 함께 줄 데이터 (GET 요청시엔 비우기)
success: function(response){ // 서버에서 준 결과를 response라는 변수에 담음
코드작성
}
})
</script>
</head>
console.log()
를 사용해 개발자 도구의 콘솔에 내용이 잘 나오는지, 어떻게 받아져 보여지는지 파악하는 것!$('#id 입력').empty
를 통해 새로고침할 때마다 페이지의 내용을 다 지워 요청한 정보들이 이전에 요청된 정보들과 겹치지 않게 해줌rows
로 받아오고, for
문을 사용해 rows
안에 들어 있는 각 열들을 하나씩 사용if
문을 사용해 조건을 걸어주고, 조건에 맞는 것들의 글씨 색을 다르게 설정$('#id 입력').append
를 통해 불러온 내용을 unordered list의 각 요소로 설정한 후, 사용자가 볼 수 있도록 제시<head>
<script>
function q1() {
$('#names-q1').empty()
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/seoulair",
data: {},
success: function (response) {
let rows = response['RealtimeCityAir']['row']
for (let i = 1; i < rows.length; i++) {
let name = rows[i]['MSRSTE_NM']
let mise = rows[i]['IDEX_MVL']
let temp_html = ``
if (mise > 40) {
temp_html = `<li class="red">${name} : ${mise}</li>`
} else {
temp_html = `<li>${name} : ${mise}</li>`
}
$('#names-q1').append(temp_html)
}
}
})
}
</script>
</head>
data
는 입력할 필요 없음for
문을 많이 활용했는데, 같은 아이디어로 list인 rows
의 데이터를 활용하여 어렵진 않지만 가끔 파이썬 문법으로 작성하는 경우가 있어 주의 필요temp_html
에 들어가는 값이 현 실습 이상으로 길어지는 경우도 있으므로 값 입력에 주의<head>
<script>
function q1() {
$('#names-q1').empty()
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/seoulbike",
data: {},
success: function (response) {
let rows = response['getStationList']['row']
for (let i = 1; i < rows.length; i++) {
let name = rows[i]['stationName']
let rack = rows[i]['rackTotCnt']
let parking = rows[i]['parkingBikeTotCnt']
let temp_html = ``
if (parking < 5) {
temp_html = `<tr class="not_enough">
<td>${name}</td>
<td>${rack}</td>
<td>${parking}</td>
</tr>`
} else {
temp_html = `<tr>
<td>${name}</td>
<td>${rack}</td>
<td>${parking}</td>
</tr>`
}
$('#names-q1').append(temp_html)
}
}
})
}
</script>
</head>
msg
와 url
을 받아와 르탄이나와
버튼을 누를 때마다 이미지를 변경해 주는 실습$('#id 이름').attr('src', url)
을 사용하며, url의 경우 위에서 언급하였기 때문에 url만 입력msg
의 경우 텍스트 값을 반환해야 하기 때문에 $('#id 이름').text()
를 사용<head>
<script>
function q1() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/rtan",
data: {},
success: function (response) {
let msg = response['msg']
let url = response['url']
$('#img-rtan').attr('src', url)
$('#text-rtan').text(msg)
}
})
}
</script>
</head>
날씨를 알려주는 기능
을 추가 <script>
$(document).ready(function(){
alert('보여?')
});
</script>
보여?
라는 단어가 출력됨temp
에 대한 데이터를 불러와 텍스트로 넣어주도록 작성00.0
에 span
태그를 사용하여 숫자가 로딩을 할 때마다 현재의 기온을 보여줄 수 있도록 변경<head>
<script>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/weather/seoul",
data: {},
success: function (response) {
let t = response['temp']
$('#temp').text(t)
}
})
});
</script>
</head>
<body>
<div class="mytitle">
<h1>팬명록</h1>
<p>현재기온 : <span id="temp">00.0</span>도</p>
</div>
</body>
import requests # requests 라이브러리 설치 필요
r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()
gu_info
를 설정for
문을 활용해 각 구별 정보를 불러온 후, if
문의 조건에 맞는 각 구들의 이름과 미세먼지 레벨을 불러옴import requests
r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()
gu_info = rjson['RealtimeCityAir']['row']
for gu in gu_info:
if gu['IDEX_MVL'] < 60:
print(gu['MSRSTE_NM'], gu['IDEX_MVL'])
soup
변수를 사용해 필요한 부분을 추출할 수 있음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')
movies
변수는 select
기능을 활용해 #old_content > table > tbody > tr
에 해당하는 모든 정보를 list
의 형태로 저장함#old_content > table > tbody > tr
는 추출하고자 하는 데이터가 위치하는 곳을 오른쪽 클릭->DevTools->음영처리된 곳 오른쪽 클릭>-Copy->Copy Selector
의 경로로 찾아낼 수 있으며, 현재 하나의 정보를 불러오는 것이 아닌 모든 정보를 불러오는 것이기 때문에 모든 정보를 포괄할 수 있는 단위만을 남겨놓아야 함for
문 안의 title
변수의 경우는 하나의 정보를 추출하는 것이고, 영화 제목 부분의 Copy Selector
를 복사하게 되면 #old_content > table > tbody > tr:nth-child(2) > td.title > div > a
이고, 앞서 movies
에서 변수의 내용으로 설정된 앞부분을 제외한 td.title > div > a
를 적용한 것!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')
movies = soup.select('#old_content > table > tbody > tr')
for movie in movies:
title = movie.select_one('td.title > div > a')
if title is not None:
num = movie.select_one('td:nth-child(1) > img')['alt']
title = title.text
star = movie.select_one('td.point').text
print(f'{num} {title} {star}')
# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')
soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')
# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')
# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')
원격 DB
가 생김 from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta
from pymongo import MongoClient
client = MongoClient('URL')
db = client.dbsparta
# URL -> 아래의 방법으로 찾아서 입력
-> mongodb+srv://<username>:<password>@cluster0.a2woz.mongodb.net/myFirstDatabase?retryWrites=true&w=majority
-> <username>과 <password>에 앞서 설정한 test, sparta 입력
-> myFirstDatabase?를 현재 데이터베이스 이름인 Cluster0?으로 변경
-> 결과 : mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority
# 저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)
# 한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})
# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
all_users = list(db.users.find({},{'_id':False}))
# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
# 지우기 - 예시
db.users.delete_one({'name':'bobby'})
db.users.insert_one(doc)
에서 users는 collection을 뜻하고, insert_one을 통해 하나의 정보를 데이터베이스에 저장from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
doc = {
'name' : 'Bob',
'age': 27
}
db.users.insert_one(doc)
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
db.users.insert_one({'name' : 'Bobby','age': 27})
db.users.insert_one({'name' : 'park','age': 29})
db.users.insert_one({'name' : 'messi','age': 20})
list
의 형태로 가져왔으며, find({})
의 {}
부분에는 조건이 들어가나 현재는 조건이 필요없어 기입하지 않음for
문을 활용해 모든 값을 출력하였고, 아래와 같은 결과가 나옴{'_id': ObjectId('625e892b169e843115f599a0')
값은 몽고디비가 데이터를 넣을 때 스스로 생성하는 번호이므로 확인할 필요가 없음 from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
all_users = list(db.users.find({}))
for user in all_users:
print(user)
위의 '_id'
확인이 불필요하므로 코드를 다음과 같이 수정
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
all_users = list(db.users.find({}, {'_id' : False}))
for user in all_users:
print(user)
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
user = db.users.find_one({'name' : 'Bobby'})
print(user['age'])
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
db.users.update_one({'name':'Bobby'},{'$set':{'age':19}})
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
db.users.delete_one({'name':'Bobby'})
inster_one
기능을 통해 새로 만든 movies
db에 저장import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
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')
movies = soup.select('#old_content > table > tbody > tr')
for movie in movies:
title = movie.select_one('td.title > div > a')
if title is not None:
num = movie.select_one('td:nth-child(1) > img')['alt']
title = title.text
star = movie.select_one('td.point').text
doc = {
'rank': num,
'title': title,
'star': star
}
db.movies.insert_one(doc)
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
movie_name = db.movies.find_one({'title': '가버나움'})
print(movie_name['star'])
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
star = db.movies.find_one({'title': '가버나움'})['star']
target_movie = list(db.movies.find({'star': star}, {'_id': False}))
for target in target_movie:
print(target['title'])
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.a2woz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
db.movies.update_one({'title':'가버나움'},{'$set':{'star':"0"}})
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://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
musics = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
for music in musics:
rank = music.select_one('td.number').text[0:2].strip()
title = music.select_one('td.info > a.title.ellipsis').text.strip()
singer = music.select_one('td.info > a.artist.ellipsis').text.strip()
print(f'({rank}) {title} ==> {singer}')
위와 같이 풀었고 아주 잘 풀렸다. 하지만 결과를 내리는 순간,,,
짜증나게 지니에서 쓸데없이 19금을 걸어 놓은 것이다...
그래서 양쪽 공백만 없애주는 strip() 말고 다른 친구를 찾아야 겠다 생각했다.
그래서 나는 문자를 바꾸고 싶은 것과 바꿔주는 replace()
를 기용해보기로 했다.
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://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
musics = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
for music in musics:
rank = music.select_one('td.number').text[0:2].strip()
title = music.select_one('td.info > a.title.ellipsis').text.replace('19금', '').strip()
singer = music.select_one('td.info > a.artist.ellipsis').text.strip()
print(f'({rank}) {title} ==> {singer}')
결과는,,,,
성공 ㅋㅋ
title = music.select_one('td.info > a.title.ellipsis').text.replace('19금', '').strip()
나는 먼저 title
을 html에서 파싱해와서 그 결과에 있는 text
값만 취했다. 그리고 숨어있던 19금
을 없애주기 위해 replace()
를 사용해서 해당 글자들을 공백으로 바꾸어 주었다. 그리고 다른 곳에 남아있는 공백들을 strip()
을 사용해서 싹 다 지워주었다.
와 정리가 너무 잘돼있어서 읽으니까 저절로 공부가 되네요 ㅎㅎ