경기도미래기술학교 AI개발자 부트캠프 11일차 TIL - 크롤링

2023. 5. 22. 23:39python

반응형

 

 

크롤링은 예전에 한 번 해봤는데 진짜 금방 까먹는다. 참. 뭔가 기억이 날 듯 말 듯. 처음 보는 것처럼도 보이고 ㅎㅎ

파이참이 자꾸 안돼서 정신이 없어서 집중을 잘 못했다. 한스럽다.

 

하기 전에, JsonView 같이 Json을 편하게 보여주는 크롬 확장 프로그램이 있으니 마음에 드는 것을 찾아서 설치하자.

 

우선 크롤링을 하기 위해서 사이트가 잘 되는지 확인하기 위해 requests 라는 라이브러리를 사용한다.

 

requesets는 HTTP 통신의 요청과 응답를 하는데 도움을 주는 라이브러리이다.

 

import requests

response = requests.get("http://example.com")

print(response)
print(response.text)

이렇게 해서 response를 호출하면 정상 호출 response(200)이 나오고 .text를 하면 해당 주소 안에 어떤 html 소스가 있는지 보여준다.

 

 

그다음 bs4를 깔아야 한다. beautifulSoup이라는 것인데 우선 파이참에서 깔고 진행했다.

 

soup = BeautifulSoup(response.text, 'html.parser')

이렇게 하면 BeautifulSoup()으로 감싸는데  text를 가져오는데 html 파싱을 하겠다는 의미이다.

 

# head 찾아가기
# soup.select('tag이름')
soup.select('p')   # 해당 tag 모두 리턴, 리스트로 

soup.select_one('p')   # string 타입으로 리턴

# 특정 id 조회  #
# soup.select('#아이디명')
soup.select('#book_title')


# soup.select('tag명#아이디명')
soup.select('p#book_title')

# 특정 class를 조회  .
# soup.select('tag명.클래스명')
plist =soup.select('.portal')
print(plist[0])

# 속성은 dictionary 구조
print(plist[0]['class'])
print(plist[0]['href'])

# for문으로 text 출력 -> 출력포멧 : text, href
plist =soup.select('.portal')
#print(plist)
for portal in plist :
    # print(portal)
    # print(portal.text)
    # print(portal['href'])
    print(portal.text , portal['href'])
    
    # 상위 tag 하위 tag 지정
# '상위tag 하위tag'  : 띄어쓰기 
soup.select('body p')

# 상위tag 바로 아래 하위 tag 조회 
soup.select('body > p')

족보이면서 bs4의 핵심이 되는 애들이니 참고하자.

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/?_C_=42121&NaPm=ct%3Dlhym2psg%7Cci%3D0zu0003-_kHyt7tsd0Xi%7Ctr%3Dbrnd%7Chk%3D6ced1ef4a6ea435ef21967d6afc0e9e2a720ee4c',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

# 코딩 시작

title = soup.select_one('#body-content > div.main-wrap.clearfix > div.chart > div > div > table > tbody > tr:nth-child(1) > td.info > a.title.ellipsis')
title_list = soup.select('#body-content > div.main-wrap.clearfix > div.chart > div > div > table > tbody > tr')

#body-content > div.main-wrap.clearfix > div.chart > div > div > table > tbody > tr:nth-child(1) > td.info > a.title.ellipsis
#body-content > div.main-wrap.clearfix > div.chart > div > div > table > tbody > tr:nth-child(5) > td.info > a.title.ellipsis


# print(title.text)
# print(title['href'])

# print(title_list)

for song in title_list:
    a = song.select_one('td.info > a.title')
    print(a.text)

이번에는 지니뮤직 사이트의 음악 제목을 추출했다. select_one 메서드로 먼저 잘 나오는지 확인한 후 soup.select를 통해 list로 받았다.

 

for idx, ( title, price, volume ) in enumerate(zip(tltles, pricelist, volumelist) ):
    print(f"{idx+1}. {title} / {price} / {volume}")

이것은 코스피 주식을 이용해 zip 파일로 묶은 다음 제목, 가격, 거래량을 각각 뽑은 것이다.

 

 

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.gmarket.co.kr/n/best?&viewType=G&groupCode=G06',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

onetitle = soup.select_one('#gBestWrap > div.best-list > ul > li:nth-child(1) > a')

oneprice = soup.select_one('#gBestWrap > div.best-list > ul > li:nth-child(1) > div.item_price > div.s-price > strong > span')

# print(onetitle.text)
# print(oneprice.text)

# title : #gBestWrap > div.best-list > ul > li:nth-child(1) > a

# price : #gBestWrap > div.best-list > ul > li:nth-child(1) > div.item_price > div.s-price > strong > span

# price : #gBestWrap > div.best-list > ul > li:nth-child(4) > div.item_price > div.s-price > strong > span

title_price_list = soup.select('#gBestWrap > div.best-list > ul > li')
# price_list = soup.select('#gBestWrap > div.best-list > ul > li')

idx=0
for title in title_price_list:
    titles = title.select_one('a.itemname')
    prices = title.select_one('div.item_price > div.s-price > strong > span')
    idx+=1
    print(idx,'상품명 :', titles.text ,'가격 :', prices.text)

 

그리고 지마켓 1위~ 100위를 뽑았다. 이게 좀 당황스럽게 했는데 title에 보면 뒤에 a태그 딱 하나밖에 없다. 실제로 a 태그 하위의 느낌은 없어서 좀 당황스러웠는데 크롤링을 해보니 역시나 제목이 뽑히지가 않았다. 그래서 클래스명이 마침 있길래 a.itemname이라고 붙여보니 다행히 정상작동 했다. 왜 안됐는지는 아직 잘 모르겠다. 이유가 뭘까. 아무튼 해결이 돼서 다행이다.

 

내일은 좀 일찍 가서 판다스 같은거 엑셀로 좀 뽑는 연습 하고싶은데 내가 과연 일찍 갈까?

728x90