프로그래밍

[데이터 수집] 빅데이터 수집 시스템 개발(BeautifulSoup)

RainIron 2021. 6. 15. 09:38
반응형

※ 개요

- 웹 크롤링(Web Crawling)

- 웹 스크래핑(Web Scraping): 웹 페이지 내에서 정보를 수집

- 수집 툴

  * requests

  * BeautifulSoup

  * Selenium: 동적인 컨텐츠까지 접근하여 수집 가능

 

- 웹 페이지 동작 순서

  사용자 클릭 or 동작 -> 요청이 서버로 전달 -> 서버는 해당 컨텐츠 서칭 -> 웹 브라우저로 컨텐츠 다운로드(html 형태, 안에는 실행 가능한 Javascript 내장) -> 추가로 Javascript가 서버에 또 다른 컨텐츠 요청 가능


※ Requests(웹서버에 대한 요청 전달)

- 웹 서버에 접속

- 요청 ≒ 웹 브라우저 주소창에 URL을 입력하고 엔터를 치는 행위

         ≒ URL 클릭(링크)

- request <-> response(형식: HTML)

 

import requests

response = requests.get('http://www.google.com')
if response.status_code == 200:
    print(response.text[:100])
else:
    print(response.status_code)

- requests.get(URL) : 사이트에 대해 요청을 보냄 => return response

- response.status_code == 200 이면 정상적으로 응답을 받음 / status_code의 값을 확인하여 response 상태를 파악

- response의 text에는 HTML이 들어있음

def download_page(url):
    try:
        return requests.get(url).text
    except:
        print('error!')

- response가 가지고 있는 html return

 

* HTML 기초 개념

- <head> 태그와 <body> 태그로 구성

- <style> 적용 위치에 따라 해당 태그 스타일 적용

  (<head> 태그에서 <body> 태그 안에 들어갈 div, span 등의 스타일을 정의할 수 있다.)

- <script> 는 동적으로 작동될 수 있는 필드

  => function을 작성해 Element에 동작을 가할 수 있다.

- <div> 는 Block Level Element (블락은 온전히 차지)

- <span> 는 In-Line Element (할당 공간만 차지)

- HTML에서는 엔터가 공백 1개로만 인식된다. => <br> 태그를 넣어 줄바꿈을 해준다.

- <p> 는 문단으로 글을 쓰기 위한 태그

- <b> 는 글씨체를 Bold로 변경

- <ul> 는 UnorderedList


※ BeautifulSoup

- 코드 예시

from bs4 import BeautifulSoup

example_html = """
<html>
<head>
<title>Your Title Here</title>
</head>
<body bgcolor="#ffffff">
<center>
<img align="bottom" src="clouds.jpg"/>
</center>
<hr/>
<a href="http://somegreatsite.com">Link Name</a> is a link to
another nifty site
<h1>This is a Header</h1>
<h2>This is a Medium Header</h2>
Send me mail at <a href="mailto:support@yourcompany.
com">support@yourcompany.com</a>.
<p>This is a paragraph!</p>
<p>
<b>This is a new paragraph!</b><br/>
<b><i>This is a new sentence without a paragraph break, in bold
italics.</i></b>
<a>This is an empty anchor</a>
</p>
<hr/>
</body>
</html>
"""

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

* Naver 첫 페이지에서 text를 가져와 parser로 끊어보기

contents = requests.get('http://naver.com').text
naver_text = BeautifulSoup(contents, 'html.parser')

* 가져온 text에서 'a' 태그 내용 중 속성 'href' 출력하기

# Extracting Tag
links = naver_text.find_all('a', href=True)
for link in links:
    if '#' not in link['href']:
        print(link['href'])

- find_all(태그명, href, text)

text의 경우 단순히 'text'면 해당 문자와 동일한 경우만, re.compile('text')와 같이 정규표현식을 사용하면 포함하는 문자열을 얻을 수 있다.

 

* naver_text 안에서 <>블락 안에 'h'가 들어간 태그의 이름을 출력하기

import re

for tag in naver_text.find_all(re.compile('h')):
    print(tag.name)

* BeautifulSoup.find(태그명, id = 'x'): id가 'x'인 내용 찾기

* BeautifulSoup.find(태그명, src = 'x'): src가 'x'인 내용 찾기

* BeautifulSoup.find_all(태그명, text = 'text'): 'text'와 동일한 내용 찾기

* BeautifulSoup.find_all(태그명, text = re.compile('text')): 'text'를 포함한 내용 찾기

* BeautifulSoup.insert(index, 내용): index의 위치에 내용 넣기

tmp = naver_text.new_tag('h2')
tmp.string = 'Frist H2'
naver_text.insert(0, tmp)

* BeautifulSoup.append(내용): 맨 뒤 인덱스에 내용 추가

* BeautifulSoup.wrap(내용): 내용을 태그로 감싸기

* BeautifulSoup.특정 태그.extract(): 제거한 후 제거한 것을 리턴

* BeautifulSoup.특정 태그.decompose(): 영구 삭제

* BeautifulSoup.find(태그).prettify(): 태그 안에 들어있는 String 내용 리턴(__str__)

 

* naver 홈페이지에서 증권 버튼을 입력하여 가는 url 찾기

import requests
from bs4 import BeautifulSoup

contents = requests.get('http://naver.com').text
naver_text = BeautifulSoup(contents, 'html.parser')

for i in naver_text.find_all(class_ = 'nav'):
    if i['data-clk'] == 'svc.stock':
        print(i['href'])

* naver 홈페이지에서 증권 홈페이지에 있는 주요 뉴스 6개 제목을 가져오기

1) 네이버 첫 페이지 접속

2) 증권 링크에 설정된 url 추출

3) 추출한 url을 request로 전달

4) request로 받은 요청을 수행 후, 주요 뉴스 헤드라인 추출

import requests
from bs4 import BeautifulSoup

contents = requests.get('http://naver.com').text
naver_text = BeautifulSoup(contents, 'html.parser')

finance_url = ''
for i in naver_text.find_all(class_ = 'nav'):
    if i['data-clk'] == 'svc.stock':
        finance_url = i['href']

finance_cont = requests.get(finance_url).text
fi_text = BeautifulSoup(finance_cont, 'html.parser')

main_news_ul = fi_text.find(class_ = 'section_strategy').ul

for i in main_news_ul:
    if i.find('a') == -1:
        continue
    print(i.find('a').text)

코드 실행 결과

* 증권 홈페이지에서 코스피 지수 이미지를 가져오기

import requests
from bs4 import BeautifulSoup

contents = requests.get('http://naver.com').text
naver_text = BeautifulSoup(contents, 'html.parser')

finance_url = ''
for i in naver_text.find_all(class_ = 'nav'):
    if i['data-clk'] == 'svc.stock':
        finance_url = i['href']

finance_text = requests.get(finance_url).text
finance_text = BeautifulSoup(finance_text, 'html.parser')

img_src = finance_text.find('img', src = True, alt="코스피지수 상세보기")

final_request = requests.get(img_src['src'])

with open('sampling.jpg', 'wb') as f:
    f.write(final_request.content)
반응형