스파르타 웹개발종합반 3주차-1

thermal·2022년 9월 12일
0

requests 라이브러리 사용

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

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

웹 크롤링

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')
  • header : 코드에서 보내는 콜을 브라우저(사람)이 보내는 것처럼 해줌

  • 웹 크롤링 순서

  1. 페이지에 요청해 html 가져오기(requests 이용)
  2. beautifulsoup(BS4)라이브러리로 html에서 원하는 내용 찾기

beautifulsoup 사용법

title = soup.select_one('#old_content > table > tbody > tr:nth-child(2) > td.title > div > a') // ''은 copy selector로 복사한 내용
print(title)
print(title.text)
print(title['href'])

결과 : 
<a href="/movie/bi/mi/basic.naver?code=186114" title="밥정">밥정</a>
밥정
/movie/bi/mi/basic.naver?code=186114
  • soup.select_one으로 하나 선택해 서치
  • 서치된 내용 중 text나 href만 출력 가능

영화 랭킹 리스트의 각 영화명의 selector(선택자) 경로는

#old_content > table > tbody > tr:nth-child(3) > td.title > div > a
#old_content > table > tbody > tr:nth-child(4) > td.title > div > a

이렇게 생겼다. tr까지는 모두 같으므로 이들을 골라내려면

movies = soup.select('#old_content > table > tbody > tr')

로 가능하다.

movies = soup.select('#old_content > table > tbody > tr')

for i in movies :
    a = i.select_one('td.title > div > a')
    if a is not None : // 구분줄은 None으로 뜨므로 제외하고 출력
        print(a.text)

select로 골라낸 결과에서 select_one으로 영화 제목만 다시 골라낼 수 있다.

selector(선택자) : div 안의 table 안의 tr 안의 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')

title = soup.select_one('#old_content > table > tbody > tr:nth-child(2) > td.title > div > a')

movies = soup.select('#old_content > table > tbody > tr')
print(movies)

for i in movies:
	a = i.select_one('td.title > div > a')
    if a is not None:
        title = i.select_one('td.title > div > a')
        rank = i.select_one('td.ac > img')  
        score = i.select_one('td.point')
        print(rank['alt'], title.text, score.text)        
  • 속성 값은 ['속성명']으로 가져온다
  • 그냥 score = i.select_one('td.point').text 이렇게 뒤에 바로 .text나 ['alt'] 붙여도 상관없음

퀴즈

지니차트에서 순위, 곡 제목, 가수 스크래핑

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 :
    music_grade = music.select_one('td.number').text[0:2].strip()
    music_title = music.select_one('td.info > a.title.ellipsis')
    music_artist = music.select_one('td.info > a.artist.ellipsis').text

    if music_title.find('span') is not None :
        music_title.find('span').decompose()

    print(music_grade, music_title.text.strip(), music_artist)
  • music_grade는 순위 숫자 뒤에 공백이 있어 숫자(문자열 형식임)만 나오게 [0:2]로 앞의 두 글자만 가져옴
  • 데이터 앞뒤의 쓸데없는 공백은 .strip() 함수 이용해 제거
  • 곡명 앞에 span 태그(19금)가 붙어있는 곡은 find()로 span 태그 여부 확인, deconpose()로 제거

데이터.find(찾을 내용) : 찾을 내용 찾으면 그것 반환. 없으면 None 반환

데이터.decompose() : 지정한 것 지움 (태그를 트리에서 제거 후 그 태그와 태그 내용물 파괴)

데이터.strip() : 데이터 앞뒤 공백 제거
.split()랑 헷갈리지 않기..

0개의 댓글