반응형
* 위 강의노트는 패스트캠퍼스에서 주관하는 강의를 수강하고 작성한 노트입니다.
데이터 수집을 위한 Python
1. beautifulsoup 모듈
breautifulsoup 모듈 사용하여 HTML 파싱하기(parsing)
- parsing이란?
- html 모듈 내에서 우리가 원하는 특정 값만 추출하는 과정
from bs4 import BeautifulSoup # 모듈 실행
- html 문자열 파싱
- 문자열로 정의된 html 데이터 파싱하기
html = '''
<html>
<head>
<title>BeautifulSoup test</titile>
</head>
<body>
<div id = 'upper' class = 'test' custom = 'good'>
<h3 title = Good Content Title>Contents Title</h3>
<p>Test contents</p>
</div>
<div id 'lower' class = 'test' costom = 'nice'>
<p>Test Test Test 1</p>
<p>Test Test Test 2</p>
<p>Test Test Test 3</p>
</div>
</body>
</html>
'''
- find 함수
- 특정 html tag를 검색
- 검색 조건을 명시하여 찾고자 하는 tag를 검색
soup = BeautifulSoup(html)
soup.find('h3') # 특정 태그를 탐색
>> <h3 title = Good Content Title>Contents Title</h3>
soup.find('p') # 태그가 여러개인 경우 가장 첫번째 태그를 출력
>> <p>Test contents</p>
soup.find('div')
>> <div id = 'upper' class = 'test' custom = 'good'>
<h3 title = Good Content Title>Contents Title</h3>
<p>Test contents</p>
</div>
# 같은 태그이나 다른 속성을 찾고 싶을 때
soup.find('div', custom = 'nice')
>> <div id 'lower' class = 'test' costom = 'nice'>
<p>Test Test Test 1</p>
<p>Test Test Test 2</p>
<p>Test Test Test 3</p>
</div>
# 여러개의 태그로 속성을 찾고 싶을 때
attrs = {'id' : 'upper', 'class' : 'test'}
soup.find('div', attrs = attrs)
>> <div id = 'upper' class = 'test' custom = 'good'>
<h3 title = Good Content Title>Contents Title</h3>
<p>Test contents</p>
</div>
- find_all 함수
- find가 조건에 만족하는 하나의 tag만 검색한다면, find_all은 조건에 맞는 모든 tag를 리스트로 반환
soup.find_all('p') ## 조건에 맞는 모든 태그 출력
>> [<p>Test contents</p>,
<p>Test Test Test 1</p>,
<p>Test Test Test 2</p>,
<p>Test Test Test 3</p>]
- get text 함수
- tag 안의 value를 추출
- 부모 tag의 경우, 모든 자식 tag의 value를 추출
soup.find('h3')
>> <h3 title = Good Content Title>Contents Title</h3>
tag = soup.find('h3')
tag.get_text ## 태그 안의 value값만 추출
>> 'Contexts Title'
tag = soup.find('div', id = 'upper') # 부모 태그를 호출할 경우
tag.get_text()
>> '\n Contents Title\n Test contents\n'
- attribute값 추출하기
- 경우에 따라 추출하고자 하는 값이 attribute에도 존재함
- 이 경우에는 검색한 tag에 attribute 이름을 []연산을 통해 추출 가능
- ex) div.find(‘h3’)[‘title’]
tag = soup.find('h3')
print(tag)
>> <h3 title = Good Content Title>Contents Title</h3>
tag['title']
>> 'Good Content Title'
id, class 속성을 이용하여 원하는 값 추출하기
import requests
from bs4 import BeautifulSoup
-
다음 뉴스 데이터 추출
- 뉴스기사에서 제목, 작성자, 작성일, 댓글 개수 추출
- tag를 추출할 때는 가장 그 tag를 쉽게 특정할 수 있는 속성을 사용
- id의 경우 원칙적으로 한 html문서 내에서 유일
-
id, class 속성으로 tag 찾기
- 타이틀
- 작성자, 작성일
url = 'https://news.v.daum.net/v/20190728165812603'
resp = requests.get(url) # html 객체 불러오기
soup = BeautifulSoup(resp.text)
title = soup.find('h3', class_ = 'tit_view')
title.get_text() ## 태그의 속성값 추출
>> '일론머스크 "테슬라에서 넷플릭스.유튜브 즐길 날 온다"'
soup.find_all('span', class_ = 'txt_info')[0] ## 기자이름
>> 이민우
soup.find_all('span', class_ = 'txt_info')[1] ## 입력시간
>> 입력 2019.07.28. 16:58
CSS를 이용하여 원하는 값 추출하기
- CSS를 이용하여 tag 찾기
- select, select_one함수 사용
- css selector 사용법
- 태그명 찾기 tag
- 자손 태그 찾기 - 자손 관계(tag tag)
- 자식 태그 찾기 - 다이렉트 자식 관계(tag > tag)
- 아이디 찾기 #id
- 클래스 찾기 .class
- 속성값 찾기 [name = ‘test’]
- 속성값 prefix 찾기 [name ^= ‘test’]
- 속성값 suffix 찾기 [name $= ‘test’]
- 속성값 substring 찾기 [name *= ‘test’]
- n번째 자식 tag 찾기 :nth-child(n)
url = 'https://news.v.daum.net/v/20190728165812603'
resp = requests.get(url) # html 객체 불러오기
soup = BeautifulSoup(resp.text)
soup.select('h3') # 'h3'에 해당되는 모든 태그를 리스트 형식으로 가져오기
>> <h3 class = 'tit_view' data-translation=''>~~</h3>
<h3 class 'txt_newsview>~~</3>
...
soup.select('#harmonyContainer') # '#'쓰고 아이디 명시
soup.select('div#harmonyContainer') # div 태그 이면서 harmony cotain 불러오기
soup.select('#harmonyContainer p') # 그 안에 들어오는 모든 p 태그를 가져와라
soup.select('h3.tit_view') # .을 찍어 해당 클래스 불러오기
# css로 가져오기
soup.select('h3[class^="tx"]') # tx로 시작하는 html 가져오기
soup.select('h3[class$="view"]') # view 로 끝나는 html 가져오기
정규표현식을 이용하여 원하는 값 추출하기
- 정규표현식으로 tag 찾기
import re
soup.find_all(re.compile('h\d')) # 정규표현식을 이용하여 태그의 패턴에 맞는 걸로 불러오기
soup.find_all('img', atts = {'src' : re.compile('.+\.jpg')})
soup.find_all('h3', class_ = re.compile('.+view$')) # view로 끝나는 모든 태그 불러오기
2. selenium 모듈
사이트에 로그인하여 데이터 크롤링하기
다음 뉴스 댓글 개수 크롤링하기
import request
- HTTP 상태코드
- 1XX(정보) : 요청을 받았으며 프로세스를 계속한다.
- 2XX(성공) : 요청을 성공적으로 받았으며 인식햇고 수용하였다.
- 3XX(리다이렉션) : 요청 완료를 위해 추가 작업 조치가 필요하다.
- 4XX(클라이언트 오류) : 요청의 문법이 잘못되었거나 요청을 처리할 수가 없다.
- 5XX(서버 오류) : 서버가 명백히 유효한 요청에 대해 충족을 실패했다.
url = 'https://comment.daum.net/apis/v1/posts/@20190728165812603'
resp = requests.get(url)
print(resp) # 클라이언트 오류
>> <Response [401]>
headers = {
'Authorization' : 'Bearer ~~~'
'Origin' : 'https://news.v.daum.net',
'Referer': 'https://news.v.daum.net/v/20190728165812603',
'User-Agent' : 'Mozilla/5.0~~'
}
resp = requests.get(url, headers = headers)
print(resp) # 요청 성공
>> <Response [200]>
resp.json() ## json 형식으로 출력
>> {'id' : ~~~,
'forumId' : -99,
...}
-
로그인하여 데이터 크롤링하기
- 특정한 경우, 로그인을 해서 크롤링을 해야만 하는 경우가 존재
- ex) 쇼핑몰에서 주문한 아이템 목록, 마일리지 조회 등
- 이 경우, 로그인을 자동화 하고 로그인에 사용한 세션을 유지하여 크롤링을 진행
-
로그인 후 데이터 크롤링하기
- endpoint 찾기 (개발자 도구의 network를 활용)
- id와 password가 전달되는 form data 찾기
- session 객체 생성하여 login진행
- 이후 session 객체로 원하는 페이지로 이동하여 크롤링
## 로그인 endpoint
url = 'https://www.hangcom.com/member/member_check.asp'
# id, password로 구성된 form data 생성하기
data = {
'id' : 'macmath22',
'pwd' : 'aaa'
}
# login
## endpoint(url)와 data를 구성하여 post 요청
## login의 경우 post로 구성하는 것이 정상적인 웹사이트
s = requests.Session() # 세션 생성
resp = s.post(url, data = data)
print(resp)
>> <Response [200]>
# crawling
## login시 사용했던 session을 다시 사용하여 요청
my_page = 'https://www.kangcom.com/mypage'
resp = s.get(my_page)
soup = BeautifulSoup(resp.text)
td = soup.select('td.a_bbslist55')[3] # 여러개의 요소중 원하는 것만 추출
mileage = td.get_text()
>> 0,000원
selenium 모듈로 웹사이트 크롤링하기
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support import By
from bs4 import BeautifulSoup
import time
-
seleinium
- 웹페이지 테스트 자동화용 모듈
- 개발/테스트용 드라이버(웹 브라우저)를 사용하여 실제 사용자가 사용하는 것처럼 동작
-
selenium 예제
- python.org로 이동하여 자동으로 검색하기
- python.org 사이트 오픈
- input 필드를 검색하여 Key 이벤트 전달
- python.org로 이동하여 자동으로 검색하기
chrome_driver = '/Users/aaron/chromedriver' # 드라이버 경로
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.python.org') # 브라우저 열기
search = driver.find_element_by_id('id-search-field') # id를 입력하는 란
time.sleep(2) # 2초간 정지
search.clear() # 입력된 것을 초기화
time.sleep(2) # 2초간 정지
search.send_keys('lambda') # 'lambda라는 문자열 전송
time.sleep(2) # 2초간 정지
search.send_keys(Keys.RETURN)
time.sleep(2) # 2초간 정지
driver.close() # 브라우저 닫기
- selenium을 이용한 다음뉴스 웹사이트 크롤링
- driver 객체의 find_xxx_by 함수 활용
chrome_driver = 'Users/aarom/chromedriver'
driver = webdriver.Chrome(chrome_driver) # 드라이버 실행
url = 'https://news.v.daum.net/v/20190728165812603'
driver.get(url)
src = driver.page_source
soup = BeautifulSoup(src)
src = driver.page_source # 페이지 소스 가져오기
soup = BeautifulSoup(src)
driver.close()
comment = soup.select_one('span.alex-count-area')
commnent.get_text() # 46 댓글 출력
반응형
'Study > ML_Basic' 카테고리의 다른 글
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 데이터 처리를 위한 Python(Numpy)(2) (0) | 2020.09.30 |
---|---|
머신러닝과 데이터 분석 A-Z 올인원 패키지-데이터 처리를 위한 Python(Numpy) – (1) (0) | 2020.09.30 |
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 데이터 수집을 위한 Python(1) (0) | 2020.09.10 |
[수강 후기]머신러닝과 데이터분석 A-Z 올인원 패키지 - python programming 기초 (0) | 2020.09.08 |
머신러닝과 데이터분석 A-Z 올인원 패키지 - Python Programming 기초(4) (0) | 2020.09.03 |