일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- 프로젝트
- 티스토리챌린지
- 텍스트 분석
- 내일배움카드
- 파이썬
- 오블완
- 내일배움
- harkerrank
- hackerrank
- TiL
- 파이썬 머신러닝 완벽가이드
- 스파르타
- wil
- 프로그래머스
- 어쩌다 마케팅
- 파이썬 철저입문
- 웹 스크랩핑
- R
- 미세먼지
- 회귀분석
- 중회귀모형
- 스파르타코딩
- MySQL
- SQL
- 파이썬 철저 입문
- Cluster
- 스파르타 코딩
- 실전 데이터 분석 프로젝트
- 파이썬 머신러닝 완벽 가이드
- 내일배움캠프
- Today
- Total
OkBublewrap
웹 스크랩핑(2) 본문
2023-03-16
예제4
%%writefile C:/myPyCode/br_example_constitution.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>줄 바꿈 테스트 예제</title>
</head>
<body>
<p id="title"><b>대한민국헌법</b></p>
<p id="content">제1조 <br/>①대한민국은 민주공화국이다.<br/>②대한민국의 주권은 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
<p id="content">제2조 <br/>①대한민국의 국민이 되는 요건은 법률로 정한다.<br/>②국가는 법률이 정하는 바에 의하여 재외국민을 보호할 의무를 진다.</p>
</body>
</html>
# utf-8으로 인코딩(한글)
f = open('C:/myPyCode/br_example_constitution.html', encoding='utf-8')
html_source = f.read()
f.close()
soup = BeautifulSoup(html_source, "lxml")
# title 제목
title = soup.find('p', {"id":"title"})
# p 태그 콘텐츠 가져오기
contents = soup.find_all('p', {"id":"content"})
print(title.get_text())
for content in contents:
print(content.get_text())
이렇게 보기 싫게 글이 나온다. 이를 정렬 하는 방법이 있다. 작성할 때 보면 글 사이에 <br/>으로 문장이 나눠진 것을 볼 수가 있다. 이부분을 띄어쓰기 '\n'으로 대체해서 사용해 정렬을 한다.
html1 = '<p id="content">제1조 <br/>①대한민국은 민주공화국이다.<br/>②대한민국의 주권은 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>'
soup1 = BeautifulSoup(html1, "lxml")
print("==> 태그 p로 찾은 요소")
content1 = soup1.find('p', {"id":"content"})
print(content1)
br_content = content1.find("br")
print("==> 결과에서 태그 br로 찾은 요소:", br_content)
br_content.replace_with("\n")
print("==> 태그 br을 개행문자로 바꾼 결과")
print(content1)
==> 태그 p로 찾은 요소
<p id="content">제1조 <br/>①대한민국은 민주공화국이다.<br/>②대한민국의 주권은 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
==> 결과에서 태그 br로 찾은 요소: <br/>
==> 태그 br을 개행문자로 바꾼 결과
<p id="content">제1조
①대한민국은 민주공화국이다.<br/>②대한민국의 주권은 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
soup2 = BeautifulSoup(html1, "lxml")
content2 = soup2.find('p', {"id":"content"})
br_contents = content2.find_all("br")
for br_content in br_contents:
br_content.replace_with("\n")
print(content2)
replace_with이 함수도 하나만 변할수 있게 할 수 있는 것 같다. 책에서는 이것을 그냥 함수로 만들어서 진행을 했다
# 줄맞춤 함수
def replace_newline(soup_html):
br_to_newlines = soup_html.find_all("br")
for br_to_newline in br_to_newlines:
br_to_newline.replace_with("\n")
return soup_html
웹 스크랩핑 시 주의 사항
1. 소스코드에서 데이터를 얻기 위한 규칙을 발견할 수 있어야 한다.
2. 사이트 접근 주기를 짧게 설정하지 않는 것이 예의! (서버의 부담)
3. 웹 사이트는 변경될 수 있기 때문에 코드를 주기적으로 변경, 관리를 해야 한다.
4. 저작권이 있는 경우가 있기 때문에 저작권 침해 여부를 미리 확인을 해야 한다.
웹 스크랩핑 vs 웹 크롤링
웹 스크랩핑 : 웹 사이트 내용을 가져와서 특정 데이터를 추출하는 것
웹 크롤링 : 가능한 웹 사이트 전체의 내용을 긁어와서 복제하는 것
순위 데이터 가져오기
아마존 알렉사의 사이트를 가지고 스크랩을 하는데 사이트 자체가 구동이 되지 않았다.
네이버 노래를 이용하기로 했다.
https://vibe.naver.com/chart/total
오늘 종합 Top 100
[VIBE] 좋아하는 음악, 좋아할 음악이 모두 여기에
vibe.naver.com
2023-03-16에 순위가 3위까지 인 곡들을 가져왔다.
1위 Ditto인 것을 보면
요쪽으로 나온 것을 볼 수가 있다.
전체적인 차트는
<tr class>...</tr> 하나하나가 저 메뉴바가 되는 것이다. 하지만 request 했을 때 해당부분이 안 들어간 것을 확인을 했다.
추후에 방법을 찾아서 진행을 해봐야 겠다.
2023-03-17
GoogleDriver을 이용해서 정보를 가져오기로 했다.
# Packages
import requests
from bs4 import BeautifulSoup
import time
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# URL, GoogleDriver
url = "https://vibe.naver.com/chart/total"
path = 'C:\\Temp1\\chromedriver_win32\\chromedriver.exe'
driver = webdriver.Chrome(path)
driver.get(url)
# 팝업창 지우기
driver.find_element_by_xpath('//*[@id="app"]/div[2]/div/div/a[2]').click()
# 현재 페이지 html 가져오기
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
# song name
soup.select_one('#content > div.track_section > div:nth-child(2) > div > table > tbody > tr:nth-child(1) > td.song > div.title_badge_wrap > span > a').get_text()
# singer name
soup.select_one('#content > div.track_section > div:nth-child(2) > div > table > tbody > tr:nth-child(1) > td.artist > span > span > span > a > span').get_text()
song name : 'Ditto'
siger name : 'NewJeans'
로 잘 나온 것을 확인 할 수 있다.
Song name
# song
song = []
for i in range(100):
a = soup.select('.inner_cell')[i].text
song.append(a)
song[:3]
['Ditto', 'Hype boy', '사건의 지평선']
song 부분이 잘 추출이 된 것을 볼 수 가 있다.
Singer name
똑같은 코드로 진행을 했을 때 228개가 나온 것을 볼 수 가 있다. 앞부분만 봤을 때는 두개 씩 아티스트 이름이 나온 것을 볼 수 가 있었다.
soup.select('a.link_artist')[:6]
[<a class="link_artist" href="/artist/5615371"><span class="text">NewJeans</span></a>,
<a class="link_artist" href="/artist/5615371"><span class="text">NewJeans</span></a>,
<a class="link_artist" href="/artist/5615371"><span class="text">NewJeans</span></a>,
<a class="link_artist" href="/artist/5615371"><span class="text">NewJeans</span></a>,
<a class="link_artist" href="/artist/15649"><span class="text">윤하</span></a>,
<a class="link_artist" href="/artist/15649"><span class="text">윤하</span></a>]
1위 뉴진스, 2위 뉴진스 3위, 윤하 이렇게 나와야하는데 중복되서 나온 것을 볼 수 가 있다.
길이 수는 228개로 나는데 연결된 부분이 더 많은 것 같다.
singer = []
for i in range(2,102):
a = soup.select('.link_artist')[i].text
song.append(a)
데이터 프레임 만들기
import numpy as np
import pandas as pd
data = {
'num' : list(range(1, 101)),
'song' : song,
'singer' : singer
}
song_list = pd.DataFrame(data)
song_list
song_list[['singer', 'num']].groupby('singer').count().sort_values('num', ascending = False)[:10]
뉴진스와, 찰리푸스, 아이브가 순위 100위권에 제일 많은 노래를 차지 하고 있는 것을 알 수 있다.
'Python > 학습용' 카테고리의 다른 글
웹 스크랩핑(4) (0) | 2023.03.17 |
---|---|
웹 스크랩핑(3) (0) | 2023.03.17 |
웹 스크래핑(1) (0) | 2023.03.16 |
군집화(cluster)(3) (0) | 2022.12.12 |
군집화(cluster)(2) (0) | 2022.12.11 |