비트교육센터/파이썬

[비트교육센터] 자바 기반 풀스택 개발자 양성 과정(Bigdata) 6일차

달의요정루나 2023. 6. 8. 20:24

1. Closure

- 간단히 말해 함수 안에 내부 함수(inner function)를 구현하고 그 내부 함수를 반환하는 함수를 말한다.

- 이때 외부 함수는 자신이 가진 변숫값 등을 내부 함수에 전달하여 실행되도록 한다.

- First class citizen: 일급객체로 객체지향프로그래밍에서 이용된다.

1) 변수 혹은 데이터구조(자료구조) 안에 담을 수 있어야 한다.

2) 매개변수로 전달할 수 있어야 한다.

3) 리턴값으로 사용될 수 있어야 한다.

 

- First class function: 퍼스트클래스 함수, 프로그래밍 언어가 함수르를 일급객체로 취급하는 것을 뜻한다. 

1) 함수 자체를 인자로써 다른 함수에 전달하거나 다른 함수의 결과값으로 리턴할 수 있다.

2) 함수를 변수에 할당하거나 데이터 구조안에 저장할 수 있는 함수를 뜻한다.

 

1) 코딩문

[1]

def double_func(x):
    return x*2
print(double_func(3))

- 기본 함수를 만든다. 값이 입력되면 그 값에 2배를 하는 함수이다.

--> 결과

6

[2]

a=double_func
print(double_func,a)

- 함수값을 찍어 레퍼런스 값을 출력한다.

--> 결과

<function double_func at 0x0000021AC3A190D0> <function double_func at 0x0000021AC3A190D0>

[3]

print(a(4))

--> 결과

8

[4]

def make_double_list(func,args):
    result=[]
    for i in args:
        result.append(func(i))
        
    return result

- 함수 func과 리스트 args를 기져와 함수에 의해 계산된 리스트 값을 출력하는 함수이다.

input_list=[1,2,3,4,5]
doubles = make_double_list(double_func,input_list)
print(doubles)

-  input_list 배열 값들을 double_func함수에 의해 계산되어져서 출력된다.

--> 결과

[2, 4, 6, 8, 10]

 

2) 코딩문

[1]

import time
def log_formatter(msg):
    def log_message():
        time_str=time.strftime('%c',time.localtime(time.time()))
        print(time_str,end='')
        print('--->',end='')
        print(msg)
        
    return log_message

- time을 import한다.

- log_formatter함수를 먼저 선언하고 그 안에 log_message함수를 선언한다.

- strftime함수를 이용해 원하는 서식을 지정해 날짜 형식을 변경할 수 있습니다.(아래 사이트에 더 자세한 설명을 볼 수 있다.)

https://docs.python.org/3/library/time.html?highlight=strftime#time.strftime 

 

time — Time access and conversions

This module provides various time-related functions. For related functionality, see also the datetime and calendar modules. Although this module is always available, not all functions are available...

docs.python.org

---

log_msg=log_formatter('test log')
print(log_msg)

--> 결과

<function log_formatter.<locals>.log_message at 0x0000021AC3A19430>

---

log_msg()

--> 결과

Thu Jun  8 09:27:57 2023--->test log

- log_formatter 함수의 로컬변수 msg는 함수실행이 종료된 후 사라지는 변수

- 종료된 이후에도 참조가 가능? log_message 를 클로저(closure) 라 함

- 클로저는 다른 함수의 지역변수값을 그 함수가 종료된 후에도 기억

- first class function을 지원하는 언어의 네임 바인딩 기술

- 어떤 함수를 함수 자신이 가지고 있는 환경과 함께 저장한 레코드

- 함수가 가진 프리변수(free variable)를 클로저가 만들어지는 당시의 값과 레퍼런스에 매핑하는 역할

- 자신의 영역 밖에서 호출된 함수의 변수값과 레퍼런스를 복사하고 저장

- free variable: 코드블럭 안에서 사용은 되지만 그 코드블럭안에서 정의되지 않은 변수

 

3) 코딩문

[1]

def outer_func():
    msg='Good Morning!'
    
    def inner_func():
        print(msg)
        
    inner_func()
outer_func()

- outer_func함수에 있는 msg 지역변수를 이용해 inner_func함수에서 해당 메시지를 출력한다.

--> 결과

Good Morning!

[2]

func=outer_func()
func()

- 다른 방식으로 출력할 수 있다.

- func는 outer_func()함수의 결과를 받는다.

--> 결과

Good Morning!

[3]

print(dir(func))

- func에 대한 디렉토리를 출력한다.

- dir(): 어떤 객체를 인자로 넣어주면 해당 객체가 어떤 변수와 메소드를 가지고 있는지 나열한다.

--> 결과

['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

---

print(type(func.__closure__))

- func의 __closure__성분의 타입을 출력한다.

--> 결과

<class 'tuple'>

- 튜플타입이라는 것을 알수 있다.

 

---

print(func.__closure__) #하나밖에 없음

- 튜플 값을 출력한다.

--> 결과

(<cell at 0x000001BC9E68B8B0: str object at 0x000001BC9E5329F0>,)

- <cell ~~~>이 괄호로 둘러쌓여있고, 쉼표 뒤에 아무것도 없어서 하나밖에 없다.

---

print(func.__closure__[0])

- 값이 하나밖이 없어서 [0]를 붙여도 같은 값이 출력된다.

--> 결과

<cell at 0x000001BC9E68B8B0: str object at 0x000001BC9E5329F0>

---

print(dir(func.__closure__[0]))#성분

- cell object의 특성을 알기 위해서  dir()를 찍어본다.

--> 결과

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']

- 마지막에 cell_contents를 가지고 있다.

---

print(func.__closure__[0].cell_contents)

- cell_contents를 붙여서 출력해본다.

--> 결과

Good Morning!

- Good Morning!이 출력된다.

 

4) 코딩문

[1]

import time
def log_formatter(msg):
    def log_message():
        time_str=time.strftime('%c',time.localtime(time.time()))
        print(time_str,end='')
        print('--->',end='')
        print(msg)#자기 바깥쪽에 있는 함수의 지역변수에 접근시 클로저 성립
        
    return log_message
test_log_msg=log_formatter('test log')
runtime_log_msg=log_formatter('runtime log')

--> 결과

test_log_msg()
Thu Jun  8 15:41:30 2023--->test log

---

runtime_log_msg()
Thu Jun  8 15:41:31 2023--->runtime log

[2]

@log_decorator #log_decorator함수를 이용해 로그 메시지를 꾸며준다.
def test_log_msg():
    print('This is test log message')

@log_decorator
def runtime_log_msg():
    print('This is runtime log message')

- @log_decorator함수를 이용해 해당 함수안의 문장을 꾸며준다.

--> 결과

test_log_msg()
Thu Jun  8 15:41:39 2023--->This is test log message
runtime_log_msg()
Thu Jun  8 15:41:39 2023--->This is runtime log message

[3]

@log_decorator
def runtime_log_msg(host, ip):
    print(f'This is runtime log message from {host}: {ip}')
runtime_log_msg('localhost','183.98.215.25')

--> 결과

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[30], line 1
----> 1 runtime_log_msg('localhost','183.98.215.25')

TypeError: log_message() takes 0 positional arguments but 2 were given

- 갑작스럽게 인자를 주어서 오류가 났다.

 

---

 

def log_decorator(param_func):
    def log_message(*args, **kargs):
        time_str=time.strftime('%c',time.localtime(time.time()))
        print(time_str,end='')
        print('--->',end='')
        return param_func(*args, **kargs)
    
    return log_message

- *args: 딕셔너리 형식을 제외한 모든 형식을 인자로 받을 수 있다.

- **kwarg: 딕셔너리로 받는 형식의 인자를 받을 수 있다.

@log_decorator
def test_log_msg():
    print('This is test log message')

@log_decorator
def runtime_log_msg(host, ip):
    print(f'This is runtime log message from {host}: {ip}')

- runtime_log_msg 함수를 딕셔너리 형식으로 받는 것으로 바꾸었다.

--> 결과

test_log()
Thu Jun  8 15:41:50 2023--->This is test log message
runtime_log_msg('localhost','183.98.215.25')
Thu Jun  8 15:41:50 2023--->This is runtime log message from localhost: 183.98.215.25

[4]

 

@log_decorator
def runtime_log_msg(arg_dict):
    print(f'This is runtime log message from {arg_dict["host"]}: {arg_dict["ip"]}')

param_dict={'host':'localhost','ip':'183.98.215.25'}
runtime_log_msg(param_dict)

--> 결과

Thu Jun  8 15:41:52 2023--->This is runtime log message from localhost: 183.98.215.25

2. Generator

- iterator를 생성해주는 함수로, 함수안에 yield 키워드를 사용된다.

- 특징

  • iterable한 순서가 지정된다.(모든 generator는 iterator)
  • 느슨하게 평가된다.(순서의 다음 값은 필요에 따라 계산된다.)
  • 함수의 내부 로컬 변수를 통해 내부상태가 유지된다.
  • 무한한 순서가 있는 객체를 모델링할 수 있다.(명확한 끝이 없는 데이터 스트림이다.)
  • 자연스러운 스트림 처리를 위 파이프라인으로 구성할수 있다.

1) 코딩문

[1]

def square_numbers(nums):
    result=[]
    for i in nums:
        result.append(i*i)
    return result

- 들어오는 수를 제곱해주는 함수이다.

my_nums = square_numbers([1,2,3,4,5])
print(my_nums)

--> 결과

[1, 4, 9, 16, 25]

[2]

def square_numbers(nums):
    for i in nums:
        yield i*i

- 제너레이터로 표현한 것이다.

- yield: 암시적으로 return이 호출되며, 한번 더 실행되면 실행되었던 yield 다음 코드가 실행된다.

my_nums = square_numbers([1,2,3,4,5])
print(my_nums)

- 이렇게 선언시 객체 레퍼런스 값만 나온다.

--> 결과

<generator object square_numbers at 0x000001BCA00B33C0>

 

---

 

print(next(my_nums))
1
print(next(my_nums))
4
print(next(my_nums))
9
print(next(my_nums))
16
print(next(my_nums))
25
print(next(my_nums))
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
Cell In[45], line 1
----> 1 print(next(my_nums))

StopIteration: 

- yield가 호출되고 다음  yield코드를 실행했다.

- 마지막에 에러가 뜬 이유는 리스트에 있는 수를 전부다 호출했기 때문이다.

 

2) 코딩문

[1]

my_nums = square_numbers([1,2,3,4,5])
for num in my_nums:
    print(num)

--> 결과

1
4
9
16
25

3) 코딩문

[1]

my_nums = [x*x for x in [1, 2, 3, 4, 5]]

print (my_nums)

for num in my_nums:
    print (num)

- 일반적인 리스트를 선언했을 때이다.

--> 결과

[1, 4, 9, 16, 25]
1
4
9
16
25

[2]

my_nums = (x*x for x in [1, 2, 3, 4, 5])#식이 들어가 있어 튜플은 아님

print (my_nums)

for num in my_nums:
    print (num)

- 제너레이터 객체로 뽑을 때이다.

--> 결과

<generator object <genexpr> at 0x000001BCA00D9C10>
1
4
9
16
25

[3]

my_nums = (x*x for x in [1, 2, 3, 4, 5])#식이 들어가 있어 튜플은 아님

print (my_nums)


print(list(my_nums))

- list를 통해 제너레이터에 있는 모든 데이터를 list로 변환시킨다.

--> 결과

<generator object <genexpr> at 0x000001BCA00D92E0>
[1, 4, 9, 16, 25]

3. Web Scraping

- 웹 스크래핑(web scraping): 원하는 특정한 정보를 웹에서 추출하는 것이다. HTTP를 통해 웹사이트의 내용을 긁어다 원하는 형태로 가공하는 것이다.

- 웹 크롤링(web crawling): 자동화 봇(웹 크롤러)이 웹을 돌아다니면서 정보를 얻는 것이다. 웹에서 사이트들을 기어다니며 필요 정보를 수집한다.

 

1) 코딩문

[1]

- 우선 시작전 폴더 경로를 한번 재조정했다. source\python 경로였지만 상위폴더로 올라가 source폴더에서 진행햇다.

- 그리고 source 폴더안에 web_scrap 폴더를 생성하고 data폴더와 driver 폴더를 생성한다.

- 주피터 랩에서 봤을 때이다.

- 그리고 터미널에서 conda install requests를 통해 새로운 라이브러리를 설치한다.

- requests: 파이썬의 HTTP 클라이언트 라이브러리이다.

 

2) 코딩문

[1]

import requests

-  requests를 import한다.

r=requests.get('https://www.google.co.kr/')
print(r)

- requests.get으로 http요청을 한다.

--> 결과

<Response [200]>

- 200은 서버측 성공 응답코드를 의미한다.

 

[2]

print(r.text[:500]) #html 소스 출력
#r.text로 입력하면 해당 웹페이지의 html소스를 다 출력한다.

--> 결과

<!doctype html>
<html lang="ko">
 <head>
  <meta charset="utf-8">
  <title>Daum</title>
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta property="og:url" content="https://www.daum.net/">
  <meta property="og:type" content="website">
  <meta property="og:title" content="Daum">
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Expires" content="-1">
  <meta name="referrer" content="origin">
  <meta property="og:image" content="https://i1.daumcdn.net/svc/image/U03/

3) 코딩문

[1]

- bs4 라이브러리와 lxml 라이브러리(이미 설치되어 있을 수 있다.)를 설치한다.

- lxml: 구문을 분석하기 위한  parser이다. 즉, BeautifulSoup은 response.text를 통해 가져온 HTML 문서를 탐색해서 원하는 부분을 뽑아내는 역할을 한다.

r=requests.get('https://www.daum.net/')
from bs4 import BeautifulSoup

- BeautifulSoup: HTML과 XML 문서들의 구문을 분석하기 위한 파이썬 패키지이다. HTML로부터 데이터를 추출하기 위해 사용할 수 있는 파싱된 페이지의 파스 트리를 만드는데, 이는 웹 스크래핑에 유용하다.

 

[2]

html = """<html><body><div><span>
        <a href=http://www.naver.com>naver</a>
        <a href=https://www.google.com>google</a>
        <a href=http://www.daum.net/>daum</a>
        </span></div></body></html>"""
soup = BeautifulSoup(html, 'lxml')

- html 변수에 있는 코드문을 lxml 파서를 통해 BeautifulSoup객체로 만들어준다.

- soup은 해당 html의 정보르를 가지게 된다.

---

print(type(soup))

--> 결과

<class 'bs4.BeautifulSoup'>

---

print(soup)

--> 결과

<html><body><div><span>
<a href="http://www.naver.com">naver</a>
<a href="https://www.google.com">google</a>
<a href="http://www.daum.net/">daum</a>
</span></div></body></html>

---

print(soup.prettify())

- prettify()로 깔끔하게 정리할 수 있다.

--> 결과

<html>
 <body>
  <div>
   <span>
    <a href="http://www.naver.com">
     naver
    </a>
    <a href="https://www.google.com">
     google
    </a>
    <a href="http://www.daum.net/">
     daum
    </a>
   </span>
  </div>
 </body>
</html>

---

print(soup.find('a'))

- find로 a 태그를 추출한다.

--> 결과

<a href="http://www.naver.com">naver</a>

---

print(soup.find('a').get_text())

- find로 a태그를 찾고  get_text()로 태그 내의 문장을 가져온다.

--> 결과

naver

---

print(soup.find_all('a'))

- find_all로 a태그를 전부 추출한다.

--> 결과

[<a href="http://www.naver.com">naver</a>, <a href="https://www.google.com">google</a>, <a href="http://www.daum.net/">daum</a>]

---

site_names = soup.find_all('a')
for site in site_names:
    print(site.get_text())

--> 결과

naver
google
daum

[3]

html2 = """
<html>
 <head>
  <title>작품과 작가 모음</title>
 </head>
 <body>
  <h1>책 정보</h1>
  <p id="book_title">토지</p>
  <p id="author">박경리</p>

  <p id="book_title">태백산맥</p>
  <p id="author">조정래</p>

  <p id="book_title">감옥으로부터의 사색</p>
  <p id="author">신영복</p>
 </body>
</html>
"""
soup2=BeautifulSoup(html2,'lxml')
print(soup2.find('title'))

- title 태그 출력

--> 결과

<title>작품과 작가 모음</title>

 

---

 

print(soup2.title)

- 해당방법으로도 태그를 출력할 수 있다.

--> 결과

<title>작품과 작가 모음</title>

 

--

 

print(soup2.body)

-  body태그를 출력한다.

--> 결과

<body>
<h1>책 정보</h1>
<p id="book_title">토지</p>
<p id="author">박경리</p>
<p id="book_title">태백산맥</p>
<p id="author">조정래</p>
<p id="book_title">감옥으로부터의 사색</p>
<p id="author">신영복</p>
</body>

 

--

 

print(soup2.body.h1)

- body 태그에 있는 h1태그를 추출한다.

--> 결과

<h1>책 정보</h1>

 

--

 

print(soup2.h1)

- h1 태그를 추출한다.

--> 결과

<h1>책 정보</h1>

 

--

 

print(soup2.find('p',{'id':'book_title'}))

- find('태그명', {'속성명' : '값'}): 해당 조건에 맞는 첫 번째 태그를 가져온다. p태그에 id값이 book_title인 태그를 가져오는 것이다.

--> 결과

<p id="book_title">토지</p>

[4]

print(soup2.select('body'))

- select 메소드는 CSS Selector로 tag 객체를 찾아 반환한다.

- body태그를 찾는 코드문이다.

--> 결과

[<body>
<h1>책 정보</h1>
<p id="book_title">토지</p>
<p id="author">박경리</p>
<p id="book_title">태백산맥</p>
<p id="author">조정래</p>
<p id="book_title">감옥으로부터의 사색</p>
<p id="author">신영복</p>
</body>]

 

---

 

print(soup2.select('body h1'))

- body태그에서 h1 태그를 추출한다.

--> 결과

[<h1>책 정보</h1>]

 

---

 

print(soup2.select('p#book_title'))

- p태그에서 id값이 book_title은 태그를 전부 추출한다.

--> 결과

[<p id="book_title">토지</p>, <p id="book_title">태백산맥</p>, <p id="book_title">감옥으로부터의 사색</p>]

 

---

 

print(soup2.select('p#author'))

- p태그에서 id값이 author인 태그를 전부 추출한다.

--> 결과

[<p id="author">박경리</p>, <p id="author">조정래</p>, <p id="author">신영복</p>]

4) 코딩문

[1]

html3 = """
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>사이트 모음</title>
</head>
<body>
<p id="title">
<b>자주 가는 사이트 모음</b>
</p>
<p id="contents">이곳은 자주 가는 사이트를 모아둔 곳입니다.</p>
<a href="http://www.naver.com" class="portal" id="naver">네이버</a> <br>
<a href="https://www.google.com" class="search" id="google">구글</a> <br>
<a href="http://www.daum.net" class="portal" id="daum">다음</a> <br>
<a href="http://www.nl.go.kr" class="government" id="nl">국립중앙도서관</a>
</body>
</html>
"""
soup3=BeautifulSoup(html3, 'lxml')
print(soup3.select('a.portal'))

- CSS class로 찾는다.

- a태그에서 class가 portal인 태그를 전부 출력한다.

--> 결과

[<a class="portal" href="http://www.naver.com" id="naver">네이버</a>, <a class="portal" href="http://www.daum.net" id="daum">다음</a>]

 

---

 

print(soup3.select('a#naver'))

- a태그 중 id가 naver인 태그를 추출한다.

--> 결과

[<a class="portal" href="http://www.naver.com" id="naver">네이버</a>]

 

[2]

sim=requests.get('https://www.similarweb.com/top-websites/computers-electronics-and-technology/search-engines/')
print(sim)

--> 결과

<Response [403]>

- 403이 뜨면 forbidden에러, 브라우저가 아닌것 같으면 막음

 

---

 

url="https://www.similarweb.com/top-websites/"
html=requests.get(url, headers={'User-Agent' : 'Mozilla/5.0'})
print(html)

- requests.get() 함수의 headers 매개변수를 사용하여 요청에 HTTP 헤더를 포함할 수 있다.

- requests.get() 에 header 내에 'User-Agent'를 넘겨주면 해결됩니다.

--> 결과

<Response [200]>

5) 코딩문

[1]

* 여기서 부터는 멜론사이트의 html코드를 가져와서 곡 제목을 추출할 예정이다.

url="https://www.melon.com/chart/index.htm"
html=requests.get(url, headers={'User-Agent' : 'Mozilla/5.0'})
print(html)

- 멜론 사이트를 요청한다.

https://www.melon.com/chart/index.htm

 

Melon

음악이 필요한 순간, 멜론

www.melon.com

--> 결과

<Response [200]>

[2]

soup=BeautifulSoup(html.text,'lxml')
site_tag_list=soup.select('div.rank01>span>a')

- class가 rank01인 태그에서 span태그 안에 있는 a태그를 전부 추출한다.

print(len(site_tag_list))

- 추출된 코드의 수를 나타낸다.

 

--> 결과

100

[3]

print(site_tag_list[:10])

- 상위 태그 10개를 출력한다.

--> 결과

[<a href="javascript:melon.play.playSong('1000002721',36430773);" title="퀸카 (Queencard) 재생">퀸카 (Queencard)</a>, <a href="javascript:melon.play.playSong('1000002721',36416114);" title="Spicy 재생">Spicy</a>, <a href="javascript:melon.play.playSong('1000002721',36356993);" title="I AM 재생">I AM</a>, <a href="javascript:melon.play.playSong('1000002721',36411342);" title="UNFORGIVEN (feat. Nile Rodgers) 재생">UNFORGIVEN (feat. Nile Rodgers)</a>, <a href="javascript:melon.play.playSong('1000002721',36318125);" title="Kitsch 재생">Kitsch</a>, <a href="javascript:melon.play.playSong('1000002721',36502910);" title="모래 알갱이 재생">모래 알갱이</a>, <a href="javascript:melon.play.playSong('1000002721',34061322);" title="사랑은 늘 도망가 재생">사랑은 늘 도망가</a>, <a href="javascript:melon.play.playSong('1000002721',36411344);" title="이브, 프시케 그리고 푸른 수염의 아내 재생">이브, 프시케 그리고 푸른 수염의 아내</a>, <a href="javascript:melon.play.playSong('1000002721',34908740);" title="우리들의 블루스 재생">우리들의 블루스</a>, <a href="javascript:melon.play.playSong('1000002721',36391236);" title="손오공 재생">손오공</a>]

[4]

print(site_tag_list[0].get_text())

- 첫번째 코드문의 텍스트를 추출한다.

--> 결과

퀸카 (Queencard)

[5]

for i in range(100):
    print(i+1,"위: ",site_tag_list[i].get_text())

- for문을 이용해 추출한 코드문에서 텍스트를 나열한다.

--> 결과

1 위:  퀸카 (Queencard)
2 위:  Spicy
3 위:  I AM
4 위:  UNFORGIVEN (feat. Nile Rodgers)
5 위:  Kitsch
6 위:  모래 알갱이
7 위:  사랑은 늘 도망가
8 위:  이브, 프시케 그리고 푸른 수염의 아내
9 위:  우리들의 블루스
10 위:  손오공
11 위:  다시 만날 수 있을까
12 위:  꽃
13 위:  Allergy
14 위:  Hype boy
15 위:  무지개
16 위:  Polaroid
17 위:  London Boy
18 위:  Ditto
19 위:  아버지
20 위:  이제 나만 믿어요
21 위:  사랑..그게 뭔데
22 위:  Cupid
23 위:  A bientot
24 위:  손이 참 곱던 그대
25 위:  인생찬가
26 위:  사랑해 진짜
27 위:  연애편지
28 위:  헤어지자 말해요
29 위:  OMG
30 위:  파이팅 해야지 (Feat. 이영지)
31 위:  잠깐 시간 될까
32 위:  물론
33 위:  찬란한 하루
34 위:  보금자리
35 위:  사건의 지평선
36 위:  Teddy Bear
37 위:  Dangerously
38 위:  부동의 첫사랑
39 위:  After LIKE
40 위:  심(心)
41 위:  I Don't Think That I Like Her
42 위:  Attention
43 위:  LOVE DIVE
44 위:  ANTIFRAGILE
45 위:  The Planet
46 위:  Thirsty
47 위:  Heaven(2023)
48 위:  NIGHT DANCER
49 위:  Dynamite
50 위:  빛이 나는 너에게
51 위:  사실말야내가말야그게그러니까말이야
52 위:  사람 Pt.2 (feat. 아이유)
53 위:  한강에서 (Feat. BIG Naughty)
54 위:  한사람만 (2023) (여름날 우리 X 이홍기 (FT아일랜드))
55 위:  사랑인가 봐
56 위:  Like Crazy
57 위:  나의 바람 (Wind And Wish)
58 위:  Angel Pt. 1 (Feat. Kodak Black, NLE Choppa, JVKE, Muni Long)
59 위:  KNOCK
60 위:  너의 모든 순간
61 위:  봄날
62 위:  안녕이라고 말하지마
63 위:  Butter
64 위:  FRIEND THE END
65 위:  첫 키스에 내 심장은 120BPM
66 위:  CHRISTIAN
67 위:  Nxde
68 위:  건물 사이에 피어난 장미 (Rose Blossom)
69 위:  Permission to Dance
70 위:  TOMBOY
71 위:  우리 사랑 이대로 (여름날 우리 X 규현 (KYUHYUN), 정은지)
72 위:  Love Me Like This
73 위:  사랑하기 싫어
74 위:  That's Hilarious
75 위:  해요 (2022)
76 위:  사랑하지 않아서 그랬어
77 위:  Dreamers [Music from the FIFA World Cup Qatar 2022 Official Soundtrack] (Feat. FIFA Sound)
78 위:  취중고백
79 위:  STAY
80 위:  Candy
81 위:  그라데이션
82 위:  Salty & Sweet
83 위:  Monologue
84 위:  ELEVEN
85 위:  Shut Down
86 위:  on the street (with J. Cole)
87 위:  우리 왜 헤어져야 해 (여름날 우리 X 전상근)
88 위:  정이라고 하자 (Feat. 10CM)
89 위:  FEARLESS
90 위:  내가 아니라도
91 위:  Say I Love You
92 위:  F*ck My Life
93 위:  다정히 내 이름을 부르면
94 위:  That’s Not How This Works (feat. Dan + Shay)
95 위:  Pink Venom
96 위:  특
97 위:  새삥 (Prod. ZICO) (Feat. 호미들)
98 위:  Nostalgia
99 위:  발걸음
100 위:  NIGHT DANCER (BIG Naughty Remix)

6) 코딩문

* 파이썬 이미지를 추출하는 것을 만들려고 한다.

[1]

url='https://www.python.org/static/img/python-logo.png'
html=requests.get(url)
print(html)

- 파이썬 홈페이지에서 파이썬 이미지의 주소를 복사했다.

https://www.python.org/

 

Welcome to Python.org

The official home of the Python Programming Language

www.python.org

--> 결과

<Response [200]>

[2]

import os
image_file_name=os.path.basename(url)
print(image_file_name)

- os.path.basename(path): 경로명 path의 기본 이름을 반환한다. 입력받은 경로의 기본 이름을 반환하는 것이다.

--> 결과

python-logo.png

[3]

import requests
import os

url='https://www.python.org/static/img/python-logo.png'#추출한 웹주소
html=requests.get(url)#get 방식으로 웹사이트를 호출
image_file_name=os.path.basename(url)#입력받은 경로의 기본 이름을 반환
folder_name='data'#저장할 폴더명

image_path=os.path.join(folder_name, image_file_name)#폴더명과 사진이름을 합친다.
print(image_path)

image_file=open(image_path,'wb')
#사진을 쓰기모드로 저장한다, 사진은 이진파일이므로 텍스트가 아니라서 바이트 형식으로쓴다.(wb)
chunk_size=1000000 #1기가
for chunk in html.iter_content(chunk_size):
#iter_content:Chunk_size 단위로 데이터를 쪼개서 받는다.
    image_file.write(chunk)

image_file.close()

--> 결과

data\python-logo.png

7) 코딩문

* 다음영화에서 1~20위 영화기록과 영화포스터를 추출할 것이다.

https://movie.daum.net/ranking/reservation

 

랭킹 | 다음영화

Daum영화에서 자세한 내용을 확인하세요!

movie.daum.net

[1]

import requests
from bs4 import BeautifulSoup
url = "https://movie.daum.net/ranking/reservation"
html = requests.get(url)
html

--> 결과

<Response [200]>

[2]

soup = BeautifulSoup(html.text, 'lxml')
title_tags = soup.select('a.link_txt')
title_tags

- a태그에서 class가 link_txt인 구문을 전체출력한다.

--> 결과

[<a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=160244">범죄도시3</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=43294">플래시</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=165969">트랜스포머: 비스트의 서막</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=163777">엘리멘탈</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=52733">극장판 포켓몬스터DP : 아르세우스 초극의 시공으로</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=129156">가디언즈 오브 갤럭시: Volume 3</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=155850">귀공자</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169897">그 여름</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=133193">인어공주</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169553">자우림, 더 원더랜드</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=167558">분노의 질주: 라이드 오어 다이</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=158655">남은 인생 10년</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=161806">스즈메의 문단속</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=167146">명탐정코난: 하이바라 아이 이야기 ~흑철의 미스터리 트레인</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=121">아기공룡 둘리-얼음별 대모험 리마스터링</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=167476">부기맨</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=154241">슈퍼 마리오 브라더스</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169681">하나님의 마음</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=160409">슬픔의 삼각형</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169987">익스트림 페스티벌</a>,
 <a class="link_txt" data-tiara-layer="home" href="/main">홈</a>,
 <a class="link_txt" data-tiara-layer="ranking" href="/ranking/reservation">랭킹</a>,
 <a class="link_txt" data-tiara-layer="premovie" href="/premovie/theater">상영예정작</a>,
 <a class="link_txt" data-tiara-layer="contents" href="/contents/news">콘텐츠</a>]

- 하지만 마지막 4개줄은 영화와 관련없는 코드가 있다.

[3]

title_tags = title_tags[:-4]
print(len(title_tags))

- [:-4]를 선언해 마지막 4개의 줄은 제외시킨다.

--> 결과

20

[4]

title_tags

-->결과

[<a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=160244">범죄도시3</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=43294">플래시</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=165969">트랜스포머: 비스트의 서막</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=163777">엘리멘탈</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=52733">극장판 포켓몬스터DP : 아르세우스 초극의 시공으로</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=129156">가디언즈 오브 갤럭시: Volume 3</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=155850">귀공자</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169897">그 여름</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=133193">인어공주</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169553">자우림, 더 원더랜드</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=167558">분노의 질주: 라이드 오어 다이</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=158655">남은 인생 10년</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=161806">스즈메의 문단속</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=167146">명탐정코난: 하이바라 아이 이야기 ~흑철의 미스터리 트레인</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=121">아기공룡 둘리-얼음별 대모험 리마스터링</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=167476">부기맨</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=154241">슈퍼 마리오 브라더스</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169681">하나님의 마음</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=160409">슬픔의 삼각형</a>,
 <a class="link_txt" data-tiara-layer="moviename" href="/moviedb/main?movieId=169987">익스트림 페스티벌</a>]

[5]

movie_names=[]
for i, tag in enumerate(title_tags):
    print(i+1, tag.text)
    movie_names.append(tag.text)

- enumerate함수로 리스트가 있을때 순서와 리스트의 값을 전달한다.

--> 결과

1 범죄도시3
2 플래시
3 트랜스포머: 비스트의 서막
4 엘리멘탈
5 극장판 포켓몬스터DP : 아르세우스 초극의 시공으로
6 가디언즈 오브 갤럭시: Volume 3
7 귀공자
8 그 여름
9 인어공주
10 자우림, 더 원더랜드
11 분노의 질주: 라이드 오어 다이
12 남은 인생 10년
13 스즈메의 문단속
14 명탐정코난: 하이바라 아이 이야기 ~흑철의 미스터리 트레인
15 아기공룡 둘리-얼음별 대모험 리마스터링
16 부기맨
17 슈퍼 마리오 브라더스
18 하나님의 마음
19 슬픔의 삼각형
20 익스트림 페스티벌

[6]

image_tags=soup.select('div.poster_movie>img')
print(len(image_tags))

- class가 poster_movie인 div태그에서 img태그를 전체 출력한다.

--> 결과

20

[7]

print(image_tags[0])

--> 결과

<img alt="범죄도시3" class="img_thumb" src="https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Fb05fec37909f3c46d8ada73ba1d2bc2f8868e869"/>

[8]

image_urls=[]
for image_tag in image_tags:
    image_urls.append(image_tag.get('src'))
image_urls

- for문으로 해당 코드문에서 img태그의 src값만 추출해 나열한다.

--> 결과

['https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Fb05fec37909f3c46d8ada73ba1d2bc2f8868e869',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F947a0d62f2772aa0f5c73b86b631779ef1183879',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F69b2d6ef76c2c5b37b0641b187d1efd7f0636e41',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Fe4ce2c6ae33edb0ef32d5614b367f85c10a7316c',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F1dd23ff0117caadf6e2fc7db6184eec157e8d8f5',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F6b0eb68a4c944965ae78c83112bbb799c25b876b',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Fa41e4f0459791741de8afed19cc1164027c1abc0',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F4cac76629657c47ae3a2f512b06bf3b6a7cfd901',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Fbba5ebdc0a4edab6b44ed2592227a39b179d52da',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F816304398cc241d37ef83215fac3c5be82b4be6c',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F6fed61e73b455aba36c3c4b434b6fafe2944e698',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F0df0e75760a60ae1d17cee78a3294770b54f03c4',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F3a684ccaeb7aeac8e3f060ffe7249f7fe039443a',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F64e400b5accb1ba88ad13adad4c8b3b962812a1a',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F353b6aea0624a60cfeb7a7d402e5e2409a22d28d',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Faba4ad78b86bedd4014b738b68e88e915aa0a686',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F8876ecefc861afc397a9943ab781bdf0316c4983',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Ff3bb48813acf0cbc6bd9b988916455de3288f266',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2F4a969d22500d00bf312707c53dc5433bcf942c68',
 'https://img1.daumcdn.net/thumb/C408x596/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fmovie%2Fde6cc50d966aa3eb9f0f2d24a643157cb123e58f']

---

print(len(image_urls))

--> 결과

20

[9]

import os
def download_image(img_folder, url, image_name):
    html_image = requests.get(url)
    image_file=open(os.path.join(img_folder, image_name+'.jpg'),'wb')
    chunk_size=1000000
    for chunk in html_image.iter_content(chunk_size):
        image_file.write(chunk)
        
    image_file.close()

- 저장할 폴더(img_folder), 주소(url), 파일이름(image_name)을 통해 사진을 추출하는 함수이다.

- 파이썬 사진추출하고 코드가 비슷한다.

image_folder='data/image'
for url, name in zip(image_urls,movie_names):
    download_image(image_folder, url, name)

- data/image폴더에 사진을 저정하고 for문을 돌려 사진을 추출한다.

--> 결과

8) 코딩문

* Vibe 음악채널에서 노래제목하고 가수를 추출할 것이다.

https://vibe.naver.com/chart/total

 

오늘 종합 Top 100

[VIBE] 좋아하는 음악, 좋아할 음악이 모두 여기에

vibe.naver.com

[1]

import requests
from bs4 import BeautifulSoup
url='https://vibe.naver.com/chart/total'
html=requests.get(url).text
soup=BeautifulSoup(html, 'lxml')
soup # 팝업창 코드 때문에 가려진다.

--> 결과

<!DOCTYPE html>
<html lang="ko"><head><meta charset="utf-8"/><meta content="IE=edge" http-equiv="X-UA-Compatible"/><meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport"/><meta content="telephone=no" name="format-detection"/><meta content="좋아하는 음악은 물론, 좋아할 음악까지 들려주는 취향 저격 뮤직 서비스" name="description"/><meta content="app-id=1338631589" name="apple-itunes-app"/><meta content="website" property="og:type"/><meta content="https://music-phinf.pstatic.net/20201019_118/16031004163365Jexk_JPEG/about.jpg" property="og:image"/><meta content="NAVER VIBE(바이브)" property="og:title"/><meta content="#나만을 위한 음악이 듣고 싶을 땐 #내돈내듣 VIBE." property="og:description"/><meta content="https://vibe.naver.com" property="og:url"/><meta content="summary_large_image" name="twitter:card"/><meta content="https://music-phinf.pstatic.net/20201019_118/16031004163365Jexk_JPEG/about.jpg" name="twitter:image"/><meta content="NAVER VIBE(바이브)" name="twitter:title"/><meta content="NAVER VIBE(바이브)" name="twitter:site"/><meta content="VIBE" name="twitter:creator"/><meta content="#나만을 위한 음악이 듣고 싶을 땐 #내돈내듣 VIBE." name="twitter:description"/><link href="/favicon.ico" rel="shortcut icon" type="image/x-icon"/><link href="/favicon.ico" rel="icon" type="image/x-icon"/><link href="/images/icon/icon_120x120.png" rel="apple-touch-icon"/><link href="/images/icon/icon_120x120.png" rel="apple-touch-icon" sizes="120x120"/><link href="/images/icon/icon_152x152.png" rel="apple-touch-icon" sizes="152x152"/><link href="/images/icon/icon_167x167.png" rel="apple-touch-icon" sizes="167x167"/><link href="/images/icon/icon_180x180.png" rel="apple-touch-icon" sizes="180x180"/><title>VIBE (바이브)</title><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/css/common.ed19d1a3.css" rel="prefetch"/><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/common.1a071474.js" rel="prefetch"/><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/vendor-animation.af612e73.js" rel="prefetch"/><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/vendor-coreplayer.4488b4ec.js" rel="prefetch"/><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/vendor-lottie.4ba12901.js" rel="prefetch"/><link as="style" href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/css/app.7677e838.css" rel="preload"/><link as="style" href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/css/chunk-vendors.ae881fe1.css" rel="preload"/><link as="script" href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/app.fb20b8a6.js" rel="preload"/><link as="script" href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/chunk-vendors.226c86d3.js" rel="preload"/><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/css/chunk-vendors.ae881fe1.css" rel="stylesheet"/><link href="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/css/app.7677e838.css" rel="stylesheet"/></head><body><noscript><strong>자바스크립트가 비활성화 되어있어 화면을 표시할 수 없습니다. 브라우저 설정에서 자바스크립트를 활성화 후 다시 시도해 주세요.</strong></noscript><div class="app" id="app"></div><script src="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/chunk-vendors.226c86d3.js"></script><script src="https://cdn-vibe.pstatic.net/v1/vibe/vibeweb/20230608145941_resources/js/app.fb20b8a6.js"></script></body></html>

- 팝업창에 코드가 가려져 있다.

해당 팝업창은 아직 내리지 않는다.

[2]

1) 크롬 기준으로 [Chrome 맞춤설정 및 제어]->[도움말]->[Chrome 정보]를 들어간다.

2) 버전을 확인한다.

- 114.0.5735임을 알수 있다.(뒷자리는 신경쓸 필요없다.)

3) ChromeDriver를 들어가서 해당 버전의 웹 드라이버를 다운 받는다.

https://chromedriver.chromium.org/downloads

 

ChromeDriver - WebDriver for Chrome - Downloads

Current Releases If you are using Chrome version 114, please download ChromeDriver 114.0.5735.90 If you are using Chrome version 113, please download ChromeDriver 113.0.5672.63 If you are using Chrome version 112, please download ChromeDriver 112.0.5615.49

chromedriver.chromium.org

4) 본인의 운영체제에 맞추어서 다운로드한다.(필자는 윈도우를 쓰고 있다.)

5) 폴더 source/web_scrap으로 들어간다.

- driver폴더에 들어가서 그곳에서 압출해제를 진행한다.

- chromedriver.exe만 driver폴더로 옮겨놓는다.

6) conda install selenium으로 서버에 selenium을 설치한다.

 

Selenium

- 사이트의 다양한 HTML 요소에 클릭, 키보드 입력 등 이벤트를 주기 위해 이용된다.

- 반복하는 웹상의 업무를 자동화할 수 있다.

7) 버전을 확인한다. 그러나 3.141로 옛날 버전이다.

8) n을 입력해 다운로드를 취소한다.

9) conda install selenium=4으로 입력해 다시한번더 다운로드를 시도한다. 그러나 오류가 뜨면서 실패할 것이다.

10) anaconda selenium을 검색해 해당 사이트에 접속한다.

11) conda install -c conda-forge selenium을 복사한다.

conda install -c conda-forge selenium=4

12) 해당 코드를 입력해 다운로드를 시작한다. 코드 맨 오른쪽에 =4를 붙여준다.

13) 4.91로 최신버전이 설치됨을 볼수 있다.

14) 해당 X표시에 [오른쪽 마우스 클릭]->[검사]로 들어갑니다.

- 그리고 해당 빨간색 네모칸에 있는 아이콘을 눌러 X아이콘의 html 구문을 찾습니다.

15) 팝업 닫기 코드문을 확인할 수 있습니다.

16) 해당 코드문에서 [오른쪽 마우스]->[Copy]->[Copy XPath]를 통해서 해당 구문의 XML을 복사한다.

- Xpath:  W3C의 표준으로 확장 생성 언어 문서의 구조를 통해 경로 위에 지정한 구문을 사용하여 항목을 배치하고 처리하는 방법을 기술하는 언어이다.

- XML: W3C에서 개발된, 다른 특수한 목적을 갖는 마크업 언어를 만드는데 사용하도록 권장하는 다목적 마크업 언어이다.

 

[3]

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

- 셀레니움을 import한다.

driver=webdriver.Chrome(service=Service('driver/chromedriver.exe'))

- webdriver.Chrome(executable_path) 함수를 사용하여 드라이버를 로드한다. 여기서는 driver라는 변수에 저장한다.

--> 결과

driver.get('https://vibe.naver.com/chart/total')

- get함수에 url을 넣고 실행하면 해당 사이트로 이동한다.

--> 결과

xpath="""//*[@id="app"]/div[2]/div/div/a[2]"""
driver.find_element(By.XPATH, xpath).click()

- 복사한 xpath를 붙여넣기한다.

- 선택한 요소에 키보드 입력을 명령으로 주어 텍스트 입력등 을 수행할 수 있다.

- 해당 코드문을 수행하면 vibe사이트에 있는 팝업창이 내려간다.

--> 결과

팝업창이 내려갔다.

soup=BeautifulSoup(driver.page_source, 'lxml')
#print(soup) #팝업창 없는 html코드문 출력

#팝업창에 가려진 html코드문을 출력할 수 있다\

driver.close()

- 해당 코드문을 실행시 크롬드라이버가 종료된다.

9) 코딩문

[1]

#노래제목 추출한다.
title_list=soup.select('div.title_badge_wrap>span>a')
print(len(title_list))

--> 결과

100

[2]

#가수를 추출한다.
author_list=soup.select('td.artist')
print(len(author_list))

--> 결과

100

[3]

for i in range(100):
    print(i+1,'위: ','제목-',title_list[i].get_text(),'|| 작가-',author_list[i].get_text())

--> 결과

1 위:  제목- 퀸카 (Queencard) || 작가- (여자)아이들
2 위:  제목- I AM || 작가- IVE(아이브)
3 위:  제목- Spicy || 작가- aespa
4 위:  제목- Kitsch || 작가- IVE(아이브)
5 위:  제목- UNFORGIVEN (feat. Nile Rodgers) || 작가- LE SSERAFIM (르세라핌)
6 위:  제목- Cupid || 작가- FIFTY FIFTY
7 위:  제목- 꽃 || 작가- 지수 (JISOO)
8 위:  제목- Ditto || 작가- NewJeans
9 위:  제목- Hype boy || 작가- NewJeans
10 위:  제목- 이브, 프시케 그리고 푸른 수염의 아내 || 작가- LE SSERAFIM (르세라핌)
11 위:  제목- Teddy Bear || 작가- STAYC(스테이씨)
12 위:  제목- 사건의 지평선 || 작가- 윤하
13 위:  제목- After LIKE || 작가- IVE(아이브)
14 위:  제목- 손오공 || 작가- 세븐틴 (SEVENTEEN)
15 위:  제목- OMG || 작가- NewJeans
16 위:  제목- LOVE DIVE || 작가- IVE(아이브)
17 위:  제목- I Don't Think That I Like Her || 작가- Charlie Puth
18 위:  제목- KNOCK || 작가- 이채연
19 위:  제목- 파이팅 해야지 (Feat. 이영지) || 작가- 부석순(SEVENTEEN)
20 위:  제목- 건물 사이에 피어난 장미 (Rose Blossom) || 작가- H1-KEY(하이키)
21 위:  제목- NIGHT DANCER || 작가- imase
22 위:  제목- Attention || 작가- NewJeans
23 위:  제목- CHRISTIAN || 작가- Zior Park
24 위:  제목- Dangerously || 작가- Charlie Puth
25 위:  제목- 헤어지자 말해요 || 작가- 박재정
26 위:  제목- Love Me Like This || 작가- NMIXX
27 위:  제목- When I Get Old || 작가- Christopher, 청하
28 위:  제목- Allergy || 작가- (여자)아이들
29 위:  제목- ANTIFRAGILE || 작가- LE SSERAFIM (르세라핌)
30 위:  제목- 심(心) || 작가- DK(디셈버)
31 위:  제목- 너의 모든 순간 || 작가- 성시경
32 위:  제목- 오르트구름 || 작가- 윤하
33 위:  제목- Poppy (Korean Ver.) || 작가- STAYC(스테이씨)
34 위:  제목- 찬란한 하루 || 작가- 멜로망스(Melomance)
35 위:  제목- Monologue || 작가- 테이
36 위:  제목- 물론 || 작가- 허각
37 위:  제목- 드라마 || 작가- 아이유(IU)
38 위:  제목- 빛이 나는 너에게 || 작가- 던(DAWN)
39 위:  제목- 나의 X에게 || 작가- 경서
40 위:  제목- 그라데이션 || 작가- 10CM
41 위:  제목- Nxde || 작가- (여자)아이들
42 위:  제목- That's Hilarious || 작가- Charlie Puth
43 위:  제목- 사랑인가 봐 || 작가- 멜로망스(Melomance)
44 위:  제목- ELEVEN || 작가- IVE(아이브)
45 위:  제목- 부동의 첫사랑 || 작가- 10CM
46 위:  제목- 사랑..그게 뭔데 || 작가- 지아
47 위:  제목- Salty & Sweet || 작가- aespa
48 위:  제목- 밤이 무서워요 (Lonely Night) || 작가- 주주 시크릿
49 위:  제목- TOMBOY || 작가- (여자)아이들
50 위:  제목- 어떻게 이별까지 사랑하겠어, 널 사랑하는 거지 || 작가- AKMU(악뮤)
51 위:  제목- 밤하늘의 별을 (2020) || 작가- 경서
52 위:  제목- 취중고백 || 작가- 김민석(멜로망스)
53 위:  제목- STAY || 작가- The Kid LAROI, Justin Bieber
54 위:  제목- Flowers || 작가- Miley Cyrus
55 위:  제목- 그때 그 순간 그대로 (그그그) || 작가- WSG워너비(가야G)
56 위:  제목- VIBE (feat. Jimin of BTS) || 작가- 태양
57 위:  제목- 새삥 (Prod. ZICO) (Feat. 호미들) || 작가- 지코 (ZICO)
58 위:  제목- 주저하는 연인들을 위해 || 작가- 잔나비
59 위:  제목- 잠깐 시간 될까 || 작가- 이무진
60 위:  제목- Pink Venom || 작가- BLACKPINK
61 위:  제목- Candy || 작가- NCT DREAM
62 위:  제목- 다정히 내 이름을 부르면 || 작가- 경서예지, 전건호
63 위:  제목- Shut Down || 작가- BLACKPINK
64 위:  제목- 그댄 행복에 살텐데 (2022) || 작가- 최유리
65 위:  제목- 안녕이라고 말하지마 || 작가- V.O.S
66 위:  제목- 나의 바람 (Wind And Wish) || 작가- 비투비
67 위:  제목- 사랑은 늘 도망가 || 작가- 임영웅
68 위:  제목- Heaven(2023) || 작가- 임재현
69 위:  제목- 신호등 || 작가- 이무진
70 위:  제목- FRIEND THE END || 작가- 볼빨간사춘기
71 위:  제목- 나의 마음에 (Seed)  || 작가- 태양
72 위:  제목- 밤편지 || 작가- 아이유(IU)
73 위:  제목- 정이라고 하자 (Feat. 10CM) || 작가- BIG Naughty (서동현)
74 위:  제목- 바람 || 작가- 윤하
75 위:  제목- FEARLESS || 작가- LE SSERAFIM (르세라핌)
76 위:  제목- 첫눈처럼 너에게 가겠다 || 작가- 에일리(Ailee)
77 위:  제목- 한사람만 (2023) (여름날 우리 X 이홍기 (FT아일랜드)) || 작가- 이홍기(FT아일랜드)
78 위:  제목- 빙글빙글 (Prod. R.Tee) || 작가- 헤이즈 (Heize)
79 위:  제목- Kill Bill || 작가- SZA
80 위:  제목- 도깨비불 (Illusion) || 작가- aespa
81 위:  제목- Cookie || 작가- NewJeans
82 위:  제목- 모래 알갱이 || 작가- 임영웅
83 위:  제목- 모든 날, 모든 순간 (Every day, Every Moment) || 작가- 폴킴
84 위:  제목- 고백 || 작가- 멜로망스(Melomance)
85 위:  제목- 자격지심 (Feat. ZICO) || 작가- BE'O(비오)
86 위:  제목- 우리 사랑 이대로 (여름날 우리 X 규현 (KYUHYUN), 정은지) || 작가- 규현(KYUHYUN), 정은지
87 위:  제목- NOT SORRY (Feat. pH-1) (Prod. by Slom) || 작가- 이영지
88 위:  제목- 우리들의 블루스 || 작가- 임영웅
89 위:  제목- Candy (Feat. Zion.T) || 작가- 박재범
90 위:  제목- 딱 10CM만 || 작가- 10CM, BIG Naughty (서동현)
91 위:  제목- 사랑하기 싫어 || 작가- 지아
92 위:  제목- 마지막 사랑 || 작가- 신예영
93 위:  제목- Say I Love You || 작가- 우디 (Woody)
94 위:  제목- Made You Look || 작가- Meghan Trainor
95 위:  제목- 스티커 사진 || 작가- 21학번
96 위:  제목- 라일락 || 작가- 아이유(IU)
97 위:  제목- 팡파레 || 작가- 다비치
98 위:  제목- Unholy || 작가- Sam Smith, Kim Petras
99 위:  제목- strawberry moon || 작가- 아이유(IU)
100 위:  제목- Cupid (Twin Ver.) || 작가- FIFTY FIFTY