Day72

2021. 1. 25. 11:22교육과정/KOSMO

키워드 : 파이썬 스크래핑 (엄밀한 의미에서의 크롤링은 아님) / Requests 라이브러리와 urllib 라이브러리 / 파이썬 API / HTML 크롤링 / 이미지 크롤링 / 

 

 

****

 

 

1. 스크랩핑과 크롤링

 

 크롤링 ( crawling )  조직적, 자동화된 방법으로 탐색하는 컴퓨터 프로그램으로,
 여러 인터넷 사이트 페이지(문서, html 등)를 수집하여 분류한다. 
 대체로 찾아낸 데이터를 저장한 뒤, 쉽게 찾을 수 있도록 인덱싱한다. 
 스크래핑 ( scraping )  HTTP 를 통해 웹 사이트의 내용을 가져온 뒤, 원하는 형태로 가공하며
 웹 사이트의 데이터를 수집하는 모든 작업을 뜻하는 포괄적인 의미를 갖는다. 
 크롤링도 스크래핑 기술의 일부이다. 
 파싱 ( parsing )  어떤 페이지(문서, html 등) 에서 원하는 데이터를 특정 패턴이나 순서로 추출하여 가공한다. 
 일련의 문자열을 의미있는 토큰(token) 으로 분해하고,
 이들로 이루어진 파스 트리 (parse tree) 를 만드는 과정이다. 

 인터프리터나 컴파일러의 구성 요소 가운데 하나로,
 입력 토큰에 내제된 자료 구조를 빌드하고 문법을 검사하는 역할을 한다. 

 

 

※ 파이썬에서 웹을 요청할 수 있는 라이브러리

  1) requests 라이브러리 - 추가 다운로드
  2) urllib 라이브러리 - 내장 모듈

 

※ 차이점

   1- requests는 요청 메소드(get/post)를 구분하지만 urllib는 보내는 데이타 여부에 따라 구분됨
   2- 데이타 보낼 때 requests는 딕셔러니 형태로 urllib는 인코딩한 바이너리 형태로 보낸다

 

  requests   urllib
  데이터를 보낼 때 딕셔너리 형태로 보냄
  GET/POST 여부에 관계없이 사용가능.
  없는 페이지를 요청해도 에러를 띄우지 않는다.
  많은 API를 제공하고 편리하여 추천되는방식.

  데이터를 보낼 때 인코딩하여 바이너리 형태로 보낸다.
   (  -> csv 파일에 저장할 때는 'wb' 형식으로 작성 필요 )
  데이터의 여부에 따라 get / post 요청을 구분
  없는 페이지 요청 시 에러

 


2. Requests 라이브러리 

 

requests 라이브러리 추가

메뉴 > File > Settings > Project Interpreter > + 버튼 > 'requests' 검색 후 인스톨

 

※ requests 모듈

  (1) Rest API 지원
        import requests
        resp = requests.get('http://www.mywebsite.com/user')
        resp = requests.post('http://www.mywebsite.com/user')
        resp = requests.put('http://www.mywebsite.com/user/put')
        resp = requests.delete('http://www.mywebsite.com/user/delete')
  (2) 파라미터가 딕셔너리 인수로 가능
        data = {'firstname':'John', 'lastname':'Kim', 'job':'baksu'}
        resp = requests.post('http://www.mywebsite.com/user', data=userdata)
  (3) json 디코더 내장 (따로 json 모듈 사용 안해도 됨)
        resp.json()

 >> 별다른 지정 없이 url 로 데이터를 가져오고자 할 때는 get 방식을 주로 사용한다. 

 >> header 가 아닌 body 부분의 데이터를 가져오고자 할 때는 post 방식을 주로 사용한다. 

 

 

(1) get 방식을 사용하여 데이터 받아오기

import requests

url = 'http://www.google.com'
res = requests.get(url)

    ① 단순 출력시 : response 에 대한 200 이라는 응답코드가 객체로 출력된다. 

        >> 받아온 데이터를 확인하려면 text 나 content 로 출력해야 한다. 

print(res)

# 실행결과
<Response [200]>

    ② text 출력시 : response 로 받아온 데이터를 문자열로 출력한다.

print(res.text)

# 실행결과
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ko">.......

 

 

    ③ content 출력시 : response 로 받아온 데이터를 바이트로 출력한다.

        ( b '문자' : binary text 로 받아온다.  --- 배열 내에 한 문자씩 들어있음 )        ....... (참고) ( r '문자' : raw string )

print(res.content)

# 실행결과
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ko"><h...........

 

 

(2) 헤더 출력해보기

    ① 단순 출력하기 : 딕셔너리 구조로 출력된다. 

print(res.headers)

# 실행결과
{'Date': 'Mon, 25 Jan 2021 00:58:02 GMT', 'Expires': '-1', 'Cache-Control': 'p........

    ② 딕셔너리 구조를 key >>>> value 형식으로 출력하기

for key,value in res.headers.items():
    print(key, ">>>>", value)

# 실행결과
Date >>>> Mon, 25 Jan 2021 01:03:44 GMT
Expires >>>> -1
Cache-Control >>>> private, max-age=0
Content-Type >>>> text/html; charset=ISO-8859-1
....

 


3. urllib 라이브러리

 

      - URL를 다루는 모듈을 모아 놓은 패키지
      - Http Ftp를 사용하여 데이터를 다운로드 할 때 사용하는 라이브러리

      - request 모듈 : 웹 요청을 보내고 받는 기능을 하는 모듈
        >> urlretrieve() 함수를 이용하여 이미지를 다운로드 받아 파일로 저장한다.

 

(1) urllib 의 request 라이브러리 사용시 urlopen 을 사용하여 웹 문서에 접근할 수 있다. 

from urllib import request

site = request.urlopen('http://www.google.com')

 

 

    ① 단순 출력시 : 객체를 출력한다. 

print(site)

# 실행결과
<http.client.HTTPResponse object at 0x000001E3037A4748>

    ② read( ) 사용시 : 웹 문서를 읽고 출력한다. 

                            >>> resquests에서 content 로 받아온 것과 같은 결과를 출력

page = site.read()
print(page)

# 실행결과
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ko"><head><m....

 

    ③ 웹 페이지 상태값 출력하기

print(site.status)

# 실행결과
200

 

(2) 헤더 정보 출력하기

    ① getheaders( ) 사용시 : 리스트 안의 튜플 구조로 출력된다. 

headers = site.getheaders()
print(headers)

# 실행결과
[('Date', 'Mon, 25 Jan 2021 01:13:16 GMT'), ('Expires', '-1'), ('Cache-Control', 'private, max....

 

    ② 헤더의 ' 키 >>>>> 헤더의 값 ' 으로 출력하기

for key, hd in headers:
    print(key, '>>>>>', hd)

# 실행결과
Date >>>>> Mon, 25 Jan 2021 01:14:43 GMT
Expires >>>>> -1
Cache-Control >>>>> private, max-age=0
Content-Type >>>>> text/html; charset=ISO-8859-1
....

 

 

(3) 잘못된 url 로 접근했을 때의 예외처리

from urllib.error import URLError

try:
    예외가 발생할 수도 있는 구문
except URLError as e:
    예외 발생시 수행할 작업
else:
    정상 처리되었을 때 수행할 작업
finally:
    무조건 수행할 작업

 

try:
    site = request.urlopen('http://www.google.com')

except URLError as e:
    print('잘못된 접근입니다.')
    print(e)
else:
    headers = site.getheaders()
    print(headers)
finally:
    print('시스템을 종료합니다.')

# 실행결과
[('Date', 'Mon, 25 Jan 2021 01:37:44 GMT'), ('Expires', '-1'), ('Cache-Con....
시스템을 종료합니다.

 

 

(4) urllib 라이브러리의 request 모듈을 사용하여 이미지 가져오기 - urlretrieve ( ) 사용

 

    ① 이미지의 주소와 저장할 파일명을 먼저 지정한다.

        이 때, 이미지가 저장될 폴더를 미리 생성한다. 

        ( # 주의사항 : data 폴더는 미리 만들어져 있어야 한다. 또는 mkdir 로 폴더 생성 조건문 작성한다. )

from urllib import request

url = 'https://t1.daumcdn.net/daumtop_chanel/op/20170315064553027.png'
imgName = 'data/daum.png'

    ② urlretrieve( ) 함수를 사용하여 이미지를 가져와서 저장할 수 있다. 

request.urlretrieve(url, imgName)
print('저장됨')

 

(5) urlretrieve( ) 과 urlopen( ) 의 차이

   # urlretrieve(): 파일로 바로 저장
   # urlopen(): 파일로 바로 저장하기 않고 메모리에 로딩을 한다.
  [참고] 파일저장 기본방식
      f = open('a.txt','w')
      f.write("테스트 내용")
      f.close()

      위의 과정을 with 문으로 축약시, close( ) 필요없음
      with open("a.txt","w") as f:
            f.write("테스트 내용")

    ① urllib.request.urlopen( ) 이용하여 다음 이미지를 test.png 로 저장하기

from urllib.request import *

url = 'https://t1.daumcdn.net/daumtop_chanel/op/20170315064553027.png'
img = urlopen(url).read()

with open('data/test.png', 'wb') as f:
    f.write(img)

 

 

(6) urljoin( ) 을 사용하여 url 경로를 변경하기

  urllib.parse.urljoin() : 상대경로를 절대경로로 변환하는 함수

    ① url 의 마지막 단락을 수정하기 (1) - 경로 변경하기

from urllib.parse import *

baseUrl = 'http://www.example.com/html/a.html'
print( urljoin(baseUrl, 'b.html') )

# 실행결과
http://www.example.com/html/b.html

    ② url 의 마지막 단락을 수정하기 (2) - 경로 추가하기

from urllib.parse import *

baseUrl = 'http://www.example.com/html/a.html'
print( urljoin(baseUrl, 'sub/c.html') )

# 실행결과
http://www.example.com/html/sub/c.html

    ③ url 의 마지막 단락과 그 상위 경로 변경하기 - (1)

from urllib.parse import *

baseUrl = 'http://www.example.com/html/a.html'
print( urljoin(baseUrl, '/sub/c.html') )

# 실행결과
http://www.example.com/sub/c.html

    ④ url 의 마지막 단락과 그 상위 경로 변경하기 - (2)

from urllib.parse import *

baseUrl = 'http://www.example.com/html/a.html'
print( urljoin(baseUrl, '../sub/c.html') )

# 실행결과
http://www.example.com/sub/c.html

    ⑤ url 의 마지막 단락과 그 상위 경로 변경하기 - (3)

from urllib.parse import *

baseUrl = 'http://www.example.com/html/a.html'
print( urljoin(baseUrl, '../temp/c.html') )

# 실행결과
http://www.example.con/temp/c.html

    ⑥ url 의 앞에서부터 변경하기

from urllib.parse import *

baseUrl = 'http://www.example.com/html/a.html'
print( urljoin(baseUrl, 'http://www.daum.net') )

# 실행결과
http://www.daum.net

 

 

(+) import 시 주의사항

from urllib import request
>>> request.urlretrieve(url, filename)

from urllib import request as req
>>>req.urlretrieve(url, filename)

from urllib.request as req
>>>req.urlretrieve(url, filename)

import urllib.request
>>>urllib.request.urlretrieve(url, filename)

 

 


4. 파이썬에서의 웹 API 활용 - (1) openweathermap.org

 

  * API (Application Programming Interface)
      : 어느 프로그램 기능을 외부 프로그램에서 사용할 수 있도록 만든 것
        즉, 서로 다른 프로그램이 기능을 공유할 수 있도록 한 것
  ** Web API
      : 웹상의 많은 정보를 공유할 수 있도록 제공하는 것
        단점은 해당 제공자의 사정에 의해 변동이 심하다.

 ` 다음 개발자 센터
 ` 네이버 개발자 센터
 ` 구글 개발자 센터
 ` [그외] https://www.apistore.co.kr/api/apiList.do

 

 

(1) http://openweathermap.org 회원 가입 후 키 발급

 1. 회원가입 : 메뉴 > Sign Up > 사용용도 : Education > 대충가입 (무료는 1번에 60번 호출 가능 )
 2. 개발자모드 : Sign In > API Keys 에서 내가 발급받은 키 (추가 키 가능)
 3. 발급받고 바로 지정 안됨 (시간소요)

 

(2) 발급받은 API 키를 변수로 지정한다. 

apikey = "1db4718~~~~"

 

(3) 날씨를 확인하고자 하는 도시명을 배열로 담는다. 

cities = ["Seoul,KR", "Tokyo,JP", "New York,US"]

 

(4) 홈페이지 내 API 메뉴를 클릭, API doc 을 참고하여 데이터를 받아오기 위한 스크립트를 작성하고 변수에 지정한다. 

api = "http://api.openweathermap.org/data/2.5/weather?q={city}&APPID={key}"

 

(5) 각 도시별 날씨정보를 확인할 수 있는 url 을 확인할 수 있다. 

for cname in cities:
    url = api.format(city=cname, key=apikey)
    print(url)

# 실행결과
http://api.openweathermap.org/data/2.5/weather?q=Seoul,KR&APPID=1db47184ebbc18af53fd996be840d270
http://api.openweathermap.org/data/2.5/weather?q=Tokyo,JP&APPID=1db47184ebbc18af53fd996be840d270
http://api.openweathermap.org/data/2.5/weather?q=New York,US&APPID=1db47184ebbc18af53fd996be840d270

>>> url 클릭시 json 구조로 데이터가 제공된다. 

{"coord":{"lon":126.9778,"lat":37.5683},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":284.15,"feels_like":280.34,"temp_min":284.15,"temp_max":284.15,"pressure":1026,"humidity":46},"visibility":10000,"wind":{"speed":2.57,"deg":90},"clouds":{"all":0},"dt":1611549995,"sys":{"type":1,"id":8105,"country":"KR","sunrise":1611528063,"sunset":1611564442},"timezone":32400,"id":1835848,"name":"Seoul","cod":200}

 

(6) url 에 들어있는 데이터를 콘솔에 출력하기 위하여 requests 라이브러리를 임포트한 뒤 get 방식으로 가져온다. 

    출력된 데이터는 json 형식으로 보이지만 실제 데이터 타입은 단순 텍스트인 상태이다. 

import requests

...

for cname in cities:
    url = api.format(city=cname, key=apikey)
    res = requests.get(url)
    print(res.text)

# 실행결과
{"coord":{"lon":126.9778,"lat":37.5683},"weather":[{"id":800,"main":"Clear","description":"cle....
{"coord":{"lon":139.6917,"lat":35.6895},"weather":[{"id":802,"main":"Clouds","description":"sca....
{"coord":{"lon":-74.006,"lat":40.7143},"weather":[{"id":804,"main":"Clouds","description":"over....

 

(7) 데이터 타입도 json 으로 변환하기 위해 json 라이브러리를 임포트하고, 데이터를 로드한다. 

import requests
import json

....

for cname in cities:
    url = api.format(city=cname, key=apikey)
    res = requests.get(url)
    data = json.loads(res.text)
    print(data)

# 실행결과
{'coord': {'lon': 126.9778, 'lat': 37.5683}, 'weather': [{'id': 800, 'main': 'Clear', 'descri....
{'coord': {'lon': 139.6917, 'lat': 35.6895}, 'weather': [{'id': 802, 'main': 'Clouds', 'descri....
{'coord': {'lon': -74.006, 'lat': 40.7143}, 'weather': [{'id': 804, 'main': 'Clouds', 'descrip....

 

(8) json 타입의 데이터로부터 원하는 정보를 출력할 수 있다. 

import requests
import json

....

for cname in cities:
    url = api.format(city=cname, key=apikey)
    res = requests.get(url)
    data = json.loads(res.text)
    print('   도시 : ', data["name"])
    print('   습도 : ', data["main"]["humidity"])
    print('   기압 : ', data["main"]["pressure"])

# 실행결과
   도시 :  Seoul
   습도 :  46
   기압 :  1026
   ....

 

(9) 온도의 경우 화씨로 제공되므로, 변환하는 함수를 작성하여 섭씨로 출력한다. 

import requests
import json

....
k2c = lambda k: k - 273.15

for cname in cities:
    url = api.format(city=cname, key=apikey)
    res = requests.get(url)
    data = json.loads(res.text)
    print('   최고온도 : ', data["main"]["temp_max"])
    print('   최고온도 : ', k2c(data["main"]["temp_max"]))
    
# 실행결과
   최고온도 :  284.15
   최고온도 :  11.0
   ....

 

(10) json 구조를 파악하여 날씨 세부정보를 출력할 수 있다. 

import requests
import json

....
k2c = lambda k: k - 273.15

for cname in cities:
    url = api.format(city=cname, key=apikey)
    res = requests.get(url)
    data = json.loads(res.text)
    print('   날씨 : ', data["weather"][0]["description"])
    
# 실행결과
   날씨 :  clear sky
   날씨 :  scattered clouds
   날씨 :  overcast clouds    

 


5. 파이썬 API 활용 - (2) tour.go.kr 공공데이터

 

(1) 공공데이터 포털 회원 가입 후 관광자원통계서비스 페이지에서 일반인증키를 발급받는다. 

  > 관광자원통계서비스 > 상세기능 > 유료관광지방문객수조회
     : 전국의 주요 유로관광지 방문객수를 조회하기 위한 서비스로서
       기간,지역, 관광지별 외국인 방문객수와 내국인 방문객수를 조회한다.

 

(2) url 이후에 물음표 쿼리스트링을 사용하여 확인하고자 하는 상세 옵션을 지정하여 url 을 만들수 있다. 

from urllib import request
from urllib import parse
import json

access_key = 'ZWFpv5iqMUVs~~~'

url = 'http://openapi.tour.go.kr/openapi/service/TourismResourceStatsService/getPchrgTrrsrtVisitorList'
queryParams = '?_type=json'
queryParams += '&serviceKey=' + access_key
queryParams += '&YM=' + '201201'
queryParams += '&SIDO=' + parse.quote('부산광역시')
queryParams += '&GUNGU=' + parse.quote('해운대구')
queryParams += '&RES_NM=' + parse.quote('부산시립미술관')

print(url + queryParams)

# 실행결과

 

(3) request 라이브러리를 사용하여 완성된 url 로 데이터를 가져올 수 있다. 

    읽어온 데이터에서 한글이 깨지지 않도록 디코딩을 해준다. 

req = request.Request(url + queryParams)
res = request.urlopen(req)
returnData = res.read().decode('utf-8')
print(returnData)

 

(4) 받아온 데이터에서 필요한 정보만 추출하기 위해 json 으로 변환한다. 

 

(5) 외국인 관광객수와 내국인 관광객수를 추출하여 출력할 수 있다. 

 


6. 파이썬 스크래핑 - Beautifulsoup 라이브러리

 

  파이썬의 표준 라이브러리를 사용하여 웹 서버에 접속 및 데이터를 요청하고
  서버로부터 받아온 데이터를 분석하고 정보를 제공하는 방법 외에도,

  유용한 외부 라이브러리를 사용할 수 있다. 
  * requests : 웹요청을 보내고 받는 기능
  * beautifulsoup4 : 서버로부터 받은 데이터를 분석하는데 사용
       - 스크래이핑 할 수 있는 라이브러리
       - 다운로드 기능은 없음 ( 다운로드는 urllib를 이용함 )
       - 추가 설치 필요
(1) 외부 라이브러리 설치
      * pip : PyPI(Python Package Index : 파이썬 패키지 인덱스)를 관리하는 시스템
      ( pip 명령어 인식 : C:\ProgramData\Anaconda3\Scripts 환경변수 PATH에 지정되어 있어야 함 )

      > pip install requests (* 주의 : s 붙음 )
      > pip install beautifulsoup4

(2) 파이참에서 설치
      프로젝트 선택 후 메뉴 > File > Settings
      왼쪽 Project > Project Interpreter 오른쪽 + 버튼
      검색창에서 requests를 찾아서 install package
      request s가 붙어야 한다.

      bs4도 추가하려면 BeautifulBS4를 찾아서 패키지 인스톨 해야 한다.
  bs4 라이브러리 : 웹에서 가져온 HTML코드를 파이썬에서 사용하기 편하게 파싱해주는 라이브러리
[참고] 웹에서 가져온 HTML코드 가져오는 방법
- requests 모듈
- urllib  request 모듈
BeautifulSoup 모듈
- find()
- find_all()
[참고] 파서의 종류 
- lxml : c로 만들어져 속도 빠름
- html5lib : 파이썬으로 만들어서 lxml보다 느림
- html.parser (*): 파이썬 버전을 확인해서 사용

 

 

(1) BS 를 사용하여 읽어온 데이터를 파싱할 수 있다. 

from bs4 import BeautifulSoup

html = """
    <html><body>
        <h1>스크레이핑 연습</h1>
        <p>웹페이지 분석하자</p>
        <p>데이타 정제하기</p>
    </body></html>
"""

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

 

(2) 파싱 후 원하는 요소에 접근하여 출력할 수 있다. 

from bs4 import BeautifulSoup

html = """
    <html><body>
        <h1>스크레이핑 연습</h1>
        <p>웹페이지 분석하자</p>
        <p>데이타 정제하기</p>
    </body></html>
"""

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

h = soup.html.body.h1
print(h)
print(h.text)		# 내용만 가져오기
print(h.string)		# string 을 가져오기

# 실행결과
<h1>스크레이핑 연습</h1>
스크레이핑 연습
스크레이핑 연습

 

(3) 요소를 찾아 출력하기

    ① 요소가 여러 개일 경우에도 리스트 형식으로 출력된다. 

from bs4 import BeautifulSoup

html = """
    <html><body>
        <h1>스크레이핑 연습</h1>
        <p>웹페이지 분석하자</p>
        <p>데이타 정제하기</p>
    </body></html>
"""

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

p = soup.find_all('p')
print(p)

# 실행결과
[<p>웹페이지 분석하자</p>, <p>데이타 정제하기</p>]

    ② 리스트로부터 태그 사이의 내용만 추출하여 출력한다. 

from bs4 import BeautifulSoup

html = """
    <html><body>
        <h1>스크레이핑 연습</h1>
        <p>웹페이지 분석하자</p>
        <p>데이타 정제하기</p>
    </body></html>
"""

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

p = soup.find_all('p')
for i in p:
    print(i.text)

# 실행결과
웹페이지 분석하자
데이타 정제하기

 

 

(4) 리스트의 내용과 해당 경로를 추출하기

     ( 속성추출 : attrs['속성명'] )

    ① 요소가 여러 개일 경우 리스트 형식으로 출력된다. 

from bs4 import BeautifulSoup

html = """
    <html>
        <body>
            <ul>
                <li><a href='http://www.naver.com'>네이브</a></li>
                <li><a href='http://www.daum.net'>다아음</a></li>
            </ul>
        </body>
    </html>
"""

soup = BeautifulSoup(html, 'html.parser')
a = soup.find_all('a')
a = soup.find_all('a')
    
# 실행결과
[<a href="http://www.naver.com">네이브</a>, <a href="http://www.daum.net">다아음</a>]

 

    ② 리스트 상태인 데이터로부터, 태그 사이의 텍스트와 태그 안의 속성값을 추출하여 출력할 수 있다. 

from bs4 import BeautifulSoup

html = """
    <html>
        <body>
            <ul>
                <li><a href='http://www.naver.com'>네이브</a></li>
                <li><a href='http://www.daum.net'>다아음</a></li>
            </ul>
        </body>
    </html>
"""

soup = BeautifulSoup(html, 'html.parser')
a = soup.find_all('a')

for i in a:
    print(i.text, ':', i.attrs['href'])
    
# 실행결과
네이브 : http://www.naver.com
다아음 : http://www.daum.net

 

(5) BS 에서 CSS 선택자 ( selector ) 찾기

  BeautifulSoup 모듈에서
     - HTML의 구조(=트리구조)에서 요소를 검색할 때 : find() / find_all()
     - CSS 선택자 검색할 때 : select() / select_one()

 

html = """
    <html><body>
        <div id='course'>
            <h1>빅데이터 과정</h1>
        </div>
        <div id='subjects'> 
            <ul class='subs'>
                <li>머신러닝</li>
                <li>데이터 처리</li>
                <li>데이타 분석</li>
            </ul>
        </div>
    </body></html>
"""

    ① id 를 select ( ) 로 추출하면 해당 아이디를 갖는 태그 전체가 리스트로 포함되어 출력된다. 

from bs4 import BeautifulSoup

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

div1 = soup.select('#course')
print(div1)

# 실행결과
[<div id="course">
<h1>빅데이터 과정</h1>
</div>]

    ②  id 를 select_one ( ) 로 추출하면 해당 아이디를 갖는 태그 한 묶음만 출력된다. 

from bs4 import BeautifulSoup

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

div2 = soup.select_one('#course')
print(div2)

# 실행결과
<div id="course">
<h1>빅데이터 과정</h1>
</div>

    ③ id 를 select( ) 로 추출하여 자손인 li 출력하기

from bs4 import BeautifulSoup

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

li = soup.select('#subjects > ul > li')
for i in li:
    print(i)

# 실행결과
<li>머신러닝</li>
<li>데이터 처리</li>
<li>데이타 분석</li>

 


7. 네이버에서 환율 정보를 선택자 사용하여 가져오기

 

(1) 필요한 라이브러리 임포트

from bs4 import BeautifulSoup
from urllib import request as req

 

(2) url 로부터 스크립트를 읽어오는지 확인한다. 

from bs4 import BeautifulSoup
from urllib import request as req

url = 'https://finance.naver.com/marketindex/'

res = req.urlopen(url)
page = res.read()
print(page)

# 실행결과
b'\n<script language=javascript src="/template/head_js.nhn?referer=info.finance.naver.com&....

 

(3) 선택자를 사용하여 달러 정보를 가져올 수 있으나, 태그가 함께 출력된다. 

from bs4 import BeautifulSoup
from urllib import request as req

url = 'https://finance.naver.com/marketindex/'

res = req.urlopen(url)

soup = BeautifulSoup(res, 'html.parser')
usd = soup.select_one('div.head_info > .value')
print(usd)

# 실행결과
<span class="value">1,101.70</span>

 

(4) string 을 사용하여 value 만 출력할 수 있다. 

from bs4 import BeautifulSoup
from urllib import request as req

url = 'https://finance.naver.com/marketindex/'

res = req.urlopen(url)

soup = BeautifulSoup(res, 'html.parser')
usd = soup.select_one('div.head_info > .value').stirng
print(usd)

# 실행결과
1,102.20

 

 


8. 교보문고에서 도서 정보를 선택자 사용하여 가져오기

 

(1) 필요한 라이브러리 임포트

from urllib.request import urlopen
from bs4 import BeautifulSoup

 

(2) url 로부터 스크립트를 읽어오는지 확인한다. 

html = urlopen("http://www.kyobobook.co.kr/search/SearchKorbookMain.jsp?vPstrCategory=KOR&vPstrKeyWord=python&vPplace=top")

soup = BeautifulSoup(html, 'html.parser')
print(soup)

# 실행결과
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<!-- header -->
<head>
....

 

(3) 선택자를 사용하여 원하는 정보( 도서명 ) 를 가져온다. 

html = urlopen("http://www.kyobobook.co.kr/search/SearchKorbookMain.jsp?vPstrCategory=KOR&vPstrKeyWord=python&vPplace=top")

soup = BeautifulSoup(html, 'html.parser')
titles = soup.select('div.title strong')
for title in titles:
    print(title.text)

# 실행결과
 혼자 공부하는 파이썬
 Do it! 점프 투 파이썬
 이것이 취업을 위한 코딩 테스트다 with 파이썬
 파이썬 증권 데이터 분석
 ....

 

(4) 전체 도서 갯수 가져오기

html = urlopen("http://www.kyobobook.co.kr/search/SearchKorbookMain.jsp?vPstrCategory=KOR&vPstrKeyWord=python&vPplace=top")

soup = BeautifulSoup(html, 'html.parser')
titles = soup.select('div.title strong')

print('총 : ', len(titles), '권')

# 실행결과
총 :  30 권

 

(5) 첫 번째 도서 제목 가져오기

html = urlopen("http://www.kyobobook.co.kr/search/SearchKorbookMain.jsp?vPstrCategory=KOR&vPstrKeyWord=python&vPplace=top")

soup = BeautifulSoup(html, 'html.parser')
titles = soup.select('div.title strong')

print(titles[0].text)

# 실행결과
혼자 공부하는 파이썬

 

(6) 도서 이름으로 이미지 파일 저장하기

from urllib.request import urlopen
from bs4 import BeautifulSoup
from urllib import request

html = urlopen("http://www.kyobobook.co.kr/search/SearchKorbookMain.jsp?vPstrCategory=KOR&vPstrKeyWord=python&vPplace=top")

soup = BeautifulSoup(html, 'html.parser')
url = soup.select('div.cover > a > img')

for i in url:
    isrc = i.attrs['src']
    title = i.attrs['alt'].strip().replace('/','_')     # 파일명에 / 가 들어갈 수 없어 _ 으로 대체
    imgName = 'imgs/{}.png'.format(title)
    request.urlretrieve(isrc, imgName)
    
# 실행결과
imgs/혼자 공부하는 파이썬.png
imgs/Do it! 점프 투 파이썬.png
imgs/이것이 취업을 위한 코딩 테스트다 with 파이썬.png
imgs/파이썬 증권 데이터 분석.png
....

 


8. urlparse( ) 와 beautifulsoup  차이점

 

  urllib.parse.urlparse( )   - url 구문을 분석하기 위한 용도의 모듈

  - 속성을 얻어오거나, 튜플처럼 인덱스로 접근할 수 있다. 
  beautifulsoup   - text 로 되어있는 html 코드에 접근하기 쉽도록 가공해주는 라이브러리

  - html 을 객체로 만들어 원하는 요소에 접근하기 쉽다.

 

반응형

'교육과정 > KOSMO' 카테고리의 다른 글

Day74  (0) 2021.01.27
Day73  (0) 2021.01.26
Day71  (0) 2021.01.22
Day70  (0) 2021.01.21
Day69  (0) 2021.01.20