<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()을 사용해서 싹 다 지워주었다.
와 정리가 너무 잘돼있어서 읽으니까 저절로 공부가 되네요 ㅎㅎ