이 게시글은 데이터사이언스엔지니어링_전문가 과정을 수강하며 복습을 위해 정리한 글입니다.
웹 크롤링은 웹 브라우저를 통해 진행 됨
관련 패키지 : webbrowser
# 브라우저 컨트롤 모듈 import
import webbrowser
브라우저 실행 : webbrowser.open
매개변수 : url을 전달(접속하고자 하는 웹 사이트)
- url은 파라미터를 포함할 수 있음
- https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=python
- https://search.naver.com/search.naver? : 검색을 위한 필수 주소
- where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=python : 서버에 전달되는 파라미터 (query=검색어)
반환값이 True면 브라우저 실행이 정상 완료
# 네이버 사이트 브라우저 함수로 접속하기
url = 'www.naver.com' # 네이버 도메인
webbrowser.open(url)
# 검색어 적용
search_url = 'https://search.naver.com/search.naver?'
search = 'query=django'
url = search_url + search
webbrowser.open(url)
파이썬을 이용한 웹 데이터 수집
1. 문서 내용 요청 후 읽어오기 urllib 패키지
- urlopen()접속
- read() 데이터 읽어오기
- text 속성을 사용해서 데이터 읽어올 수도 있음
2. 문서에서 원하는 내용 추출하기(파싱)
import requests
# 파이썬 기본 패키지 : HTTP 요청을 보내는 모듈
url = 'http://www.tistory.com'
# request 패키지의 get(url) 함수 사용 : urllib의 open()과 read()를 한번에 진행
response = requests.get(url)
# URL 변수에 저장되어 있는 웹주소로 요청신호를 보냄
# 서버(tistory)는 해당 페이지의 소스코드를 클라이언트로 전송하면서 응답하게 됨
# response 변수에는 http://www.tistory.com의 소스코드(html)가 저장되어 있음
# 정상 응답인지 확인
response.status_code # 응답에대한 상태코드
# 200은 정상응답
# 400번대 코드 : 클라이언트의 요청이 잘못되었다의 의미(url주소가 틀렸거나 권한이 없는 페이지를 요청했거나...)
# 500번대 코드 : 클라이언트는 문법에 맞게 요청을 했는데 서버측에서 인증이 안되었거나, 서버가 망가졌거나의 상태
# 요청에 의해 전달된 코드 확인
# 응답객체.text 속성을 통해 확인
response.text
# 브라우저가 사이트에 요청해서 받은 결과 코드랑 동일한 코드가 문자열 형태로 반환됨
파라미터 전달 방법
- 파라미터 : 사이트의 문서를 요청할 때 서버로 전달되는 정보
함수의 파라미터처럼 문서를 찾기위한 정보나 명령을 수행하기 위한 정보를 같이 전달하게 되는데 그 정보를 파라미터라고함
-서버에 파라미터 전송방법 :
1. url뒤에 ?뒤에 파라미터=값&파라미터=값 으로 전송
2. 파라미터를 dict로 구성해서 get(params=dict)
base_url = "https://sports.news.naver.com/news" # 기본 url
param_url = 'https://sports.news.naver.com/news?oid=477&aid=0000312064' # 파라미터가 포함된 url
# 파라미터 전달 방식 1 : get방식 - url 파라미터 포함
# site에 따라 접근 거부할 수도 있음
res1 = requests.get(param_url)
res1.status_code
# 파라미터 전달 방식 2 : get방식 : params= dict사용
# oid=477&aid=0000312064
param = {'oid':477, 'aid':'0000312064'}
res2 = requests.get(base_url, params=param)
res2.status_code
urllib 패키지 사용한 소스 추출
from urllib.request import urlopen # 사이트에 요청 신호를 보내는 함수
url = 'https://www.naver.com'
html = urlopen(url)
html
#<http.client.HTTPResponse at 0x2a60cc87c70> : 상태코드와 소스코드가 있습니다.
# 응답객체에서 소스코드 읽어오기
# - 응답객체.read() - 한번 읽어오면 그 후에는 읽어도 빈 문자열이 나옴
rawtext = html.read()
문서에서 원하는 내용 추출하기(파싱)
html문서에서 원하는 내용 추출
- BeautifulSoup 라이브러리 사용 : 태그 형식으로 된 text를 파싱할 때 사용
- find() / findAll() 등 함수 사용
Beautiful Soup
- import bs4
- 데이터를 추출하는데 필요한 기능이 들어 있는 라이브러리(파싱 라이브러리)
- 외부라이브러리 : 설치해야함
- 주피터 노트북은 기본패키지라 설치하지 않아도 됨
- 파이참 설치방법
- File/Settings
- Project Interpreter에서 bs4 검색
- [Install Package]
import bs4
url = 'http://www.naver.com'
html = urlopen(url)
########################################################
# 응답 객체인 html을 BeautofumSoup(응답객체, 파서기) 함수에 전달
# bs4 파싱객체를 반환
bs_obj = bs4.BeautifulSoup(html,'html.parser')
type(bs_obj) # bs4.BeautifulSoup
print(bs_obj.prettify()) # # html 소스코드를 들여쓰기 하여 계층적인 구조로 표현 (가독성이 높다)
Beautiful Soup 패키지의 파싱 함수
- find(태그,[{속성명:속성값}])
- 지정한 태그 중 첫번째 만나는 태그만 추출 또는 지정한 태그 중 해당 속성과 속상값을 갖고있는 태그의 첫번째 태그
- findAll(태그,[{속성명:속성값}])
- 지정한 태그 모두 찾아서 추출
- 첫번째 이외의 태그를 추출할 때 사용
- list 형태로 반환
- find_all(태그,[{속성명:속성값}])
- findAll 함수와 동일
# html코드를 파싱 객체로 변환
bs_obj = bs4.BeautifulSoup(html_str,"html.parser")
print(type(bs_obj))
#<class 'bs4.BeautifulSoup'> bs4 객체 - 관련함수 사용 가능
bs_obj.find('div')
# 여는 div 태그부터 닫는 div 태그까지
bs_obj.find('div').text
# html코드에서 첫번째 만나는 div태그의 내부 문자열 반환
bs_obj.find('li')
# fing() : ul_t 객체 안에서 첫번째 만나는 li 태그를 반환
uls = bs_obj.findAll('li') # ul_t 객체 안의 모든 li태그를 반환
uls # list형태로 반환
uls[2].text
# 반복문을 이용해서 모든 원소의 text 추출
for li in uls :
print(li.text)
class 속성값을 이용하여 태그 추출
html_str = """
<html>
<body>
<ul class="greet">
<li>hello</li>
<li>bye</li>
<li>welcome</li>
</ul>
<ul class="reply">
<li>ok</li>
<li>no</li>
<li>sure</li>
</ul>
</body>
</html>
"""
bs_obj = bs4.BeautifulSoup(html_str,'html.parser')
# 태그중에 특정 속성을 갖고 있는 태그를 추출
# ul 태그중 class 속성값이 greet인 태그를 추출
# 첫번째 ul 태그를 추출
bs_obj.find('ul')
# ul태그를 찾고 class 속성값이 greet인걸 확인 후에 반환
bs_obj.find('ul',{'class':'greet'})
# ul 태그중 class 속성값이 reply인 태그를 추출
bs_obj.findAll('ul')[1]
bs_obj.find('ul',{'class':'reply'}) # ul 태그중에 class 속성값이 reply인 첫번째 ul태그 반환
bs_obj.findAll('ul',{'class':'reply'}) # ul 태그중에 class 속성값이 reply인 모든 ul태그 반환
# 해당 ul태그가 여러개면 모두 반환
# bs_obj 객체의 모든 li태그 추출
bs_obj.find_all('li') # lit로 반환
bs_obj.findAll('li') # 6개의 li객체 반환
# class속성값이 greet 인 ul 태그 내의 모든 li 태그 추출
bs_obj.find('ul').find_all('li')
bs_obj.find_all('ul')[0].find_all('li')
bs_obj.find('ul',{'class':'greet'}).find_all('li')
bs_obj.find_all('ul',{'class':'greet'})[0].find_all('li')
id 속성값을 이용하여 태그 추출
html_str = """
<html>
<body>
<h1 id='title'>Hello Python</h1>
<p id="crawling">웹 크롤링</p>
<p id="parsing">파싱</p>
</body>
</html>"""
bs_obj = bs4.BeautifulSoup(html_str, 'html.parser')
# h1태그 중 id가 title인 태그 추출
bs_obj.find('h1',{'id':'title'})
# p태그 중 id가 parsing인 태그
bs_obj.find('p',{'id':'parding'})
bs4 형제 노드 찾기
p1 = bs_obj.find('p')
p1.next_sibling # 첫번째 p태그를 기준으로 다음 p태그를 반환
p1.next_sibling.next_sibling # 첫번째 p태그를 기준으로 다음 다음 p태그를 반환
속성값 추출하기
- a태그의 href속성
bs_obj.find_all('a')[0]['href']
# 'https://www.naver.com/'
bs_obj.find_all('a')[0].text
# '네이버'
hrefs=[]
name=[]
for a in bs_obj.find_all('a') :
name.append(a.text)
hrefs.append(a['href'])
- select사용
# selector : select(태그) 함수에 인수로 전달
# 해당 태그를 모두 찾아서 list로 반환
bs_obj.select('a')
bs_obj.select('div')
# id 선택자 : #을 활용
bs_obj.select('div #mainMenuBox') # 리스트로 반환
# id는 유일
bs_obj.select('#mainMenuBox')
bs_obj.select('#mainMenuBox li') # 자손 li를 찾음 : ul 태그 내부의 li가 반환
bs_obj.select('#mainMenuBox > li') # 자식태그인 li를 찾음
# 클래스 선택자(.클래스명)를 이용
bs_obj.select('.box') # 클래스 속성값이 box인 태그 모두를 추출
# 클래스 속성값이 box인 태그 중 두번째 태그안의 모든 a태그
bs_obj.select('.box')[1].select('a')
# 클래스 속성값이 box인 태그 중 두번째 태그안의 모든 a태그의 첫번째 태그
bs_obj.select('.box')[1].select('a')[0]
bs_obj.select('.box')[0].select('a')[0].text
웹 크롤링 시 주의사항
- 웹 사이트는 언제든지 변경될 수 있기 때문에 지금 실행하는 코드가 실행되지 않을 수 있다
'프로그래밍 > Crawling' 카테고리의 다른 글
[WebCrawling] 네이버 뉴스 섹션별 토픽 기사 크롤링 2022.ver (0) | 2022.08.03 |
---|---|
[WebCrawling] 네이버 뉴스 섹션 토픽 크롤링 2022.ver (0) | 2022.08.03 |
[WebCrawling] 네이버 뉴스 메뉴 크롤링 2022.ver (0) | 2022.08.03 |
[WebCrawling] 크롤링 결과데이터 csv파일로 저장하기 (0) | 2020.10.10 |
[WebCrawling] 네이버 기사 댓글 크롤링하기 2020.ver (0) | 2020.08.19 |