일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 파이썬 pandas
- 밑바닥부터 시작하는 딥러닝
- Django
- 머신러닝
- Pandas
- 텍스트 분류
- 히스토그램
- 최소자승법
- 기초통계
- 결정계수
- 밑바닥부터 시작하는 딥러닝2
- 오래간만에 글쓰네
- F분포
- 모두의 딥러닝
- word2vec
- 코사인 유사도
- 은준아 화이팅
- numpy
- 차원축소
- rnn
- 텐서플로2와 머신러닝으로 시작하는 자연어처리
- student t분포
- 군집화
- 구글 BERT의 정석
- 감성분석
- 자연어 처리
- 기술통계학
- 다층 퍼셉트론
- 회귀분석
- 가설검정
- Today
- Total
데이터 한 그릇
데이터 크롤링(1) 본문
urllib 모듈
import urllib.request
from urllib.request import urlopen
import requests
url = 'https://www.naver.com'
html = urlopen(url)
print(html.status) #응답코드
응답코드가 200이 나온다면 제대로 인터넷 사이트에 접속했다고 할 수 있다.
하지만 400대가 나온다면 오류가 뜬 상태.
request 모듈
url = 'https://www.naver.com'
cont = requests.get(url)
print(cont)
print(type(cont))
print(dir(cont))
print(cont.status_code)
print(cont.text) #=> 문자로 가져옴(string)
print(cont.content) #바이트 자료형으로 가져옴
url 을 설정해주고 request.get(<url>) 을 입력해서 사이트 정보를 받아온다.
이때 request.get(<url>) 으로 받아온 정보에 .text 를 사용하면 문자열로 받아오는 것이고 .content 를 사용하면 바이트 자료형으로 정보를 가져온 것.
정보 안에는 html 정보들이 담겨 있음 (태그, 속성 등등)
여기까지는 모든 정보를 다 가져왔다면 자신이 원하는 정보를 가져와야 한다.
예를 들어서 원하는 태그만을 가져오고 싶을 수 있고, 원하는 태그의 속성을 가져오고 싶을 수 있다.
BeatifulSoup
import requests
import bs4
url = 'https://www.naver.com' #여기까지 되면 데이터를 url 에서 읽어와야 됨
res = requests.get(url)#데이터를 읽어오는 콛
bs_obj = bs4.BeautifulSoup(res.text) #res.text 는 string 타입형 content가 바이트
print(bs_obj)
print(type(bs_obj))
request 임포트 해주고 bs4 를 임포트 해준다.
앞선 방법처럼 사이트의 정보를 모두 받아서 res 에 넣어준다.
사이트의 문자형 자료형들을 bs4 Beautiful 객체에 넣어준다.
프린트 해보면 정보가 다 나오고 있음을 알 수 있다.
1)find
반환 데이터 타입 tag
print(bs_obj.find('div')) #요소 찾기는 find
#최초로 발견되는 div를 가져온다.
find 괄호 안에 원하는 태그를 넣어주면 사이트의 모든 정보 중에서 첫 번째 원하는 태그 정보를 가져와 준다
밑의 코드는 find 예시
import bs4
#request.get 안하고 바로 쓰기
html_str = '<html><div>hello</div></html>'
bs_obj = bs4.BeautifulSoup(html_str,'lxml')
print(bs_obj)
print(bs_obj.find('div'))
print(type(bs_obj.find('div')))
<html><body><div>hello</div></body></html>
<div>hello</div>
<class 'bs4.element.Tag'>
위와 같은 결과를 가져온다.
bs_obj.find('div') 의 값은 태그가 달린 정보이다.
태그 안의 메시지를 찾고 싶다면 bs_obj.find('div').text 를 하면 된다.
ul = bs_obj.find('ul')
print(ul)
print('--------------------------')
ul_li = ul.find('li')
print(ul_li)
ul_li.text
ul 태그를 찾고 그 안에 첫 번째 li 를 찾고 싶다면
find 로 ul 을 찾고 찾은 것에서 다시 한번 find 해주면 된다.
bs_obj.a
print(bs_obj.find('a').get_text())
print(bs_obj.a.get_text())
find에서 태그 접근법이 . 만 찍어도 가능.
get_text() 로도 텍스트 접근 가능
2)find_all()
find는 하나만 가져오지만 find_all 은 해당 사항을 모두 가져온다.
html_str = """
<html>
<body>
<ul>
<li>hello</li>
<li>bye</li>
<li>welcome</li>
</ul>
</body>
</html>
"""
bs_obj = bs4.BeautifulSoup(html_str, 'lxml')
ul = bs_obj.find('ul')
ul_li = ul.find_all('li')
print(ul_li)
for element in ul_li:
print(element.text)
ul_li[0]
앞서서는 find를 두 번 사용해서 하나의 li 를 가져왔다면 모든 li 를 가지고 오고 싶을 때 find_all 을 사용한다.
s_obj.find_all('a')
bs_obj.find_all('a')[0].get_text()
bs_obj.find_all('a')[1].get_text()
이때 li 는 시퀀스의 특징을 가지기 때문에 인덱스를 사용할 수 있다.
하나만 가져오는 find와 . 을 사용한 접근법은 시퀀스 특징 x. 따라사 인덱스 사용 불가.
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,'lxml')
ul_reply = bs_obj.find('ul', {"class":"reply"}) #속성값은 딕셔너리로
print(ul_reply)
find와 findall을 이용해서 특정 태그를 가져올 수 있음을 살펴봤다.
태그에 접근하여 태그를 불러올 때 특정 태그를 지목할 수 있다.
class 를 이용하는 방법이 대표적인데 , 딕셔너리를 이용해서 가져온다.
인자에 불러오고 싶은 태그를 넣어주고, 오른쪽 매개변수에 딕셔너리 형태로 클래스 명을 넣어줘서 불러온다.
ul_reply = bs_obj.find('ul', attrs={"class":"reply"}) #이렇게 해도 됨
ul_reply
attrs 를 이용해서 불러올수도 있다.
import bs4
html_str = """
<html>
<body>
<ul class="ko">
<li>
<a href="https://www.naver.com/">네이버</a>
</li>
<li>
<a href="https://www.daum.net/">다음</a>
</li>
</ul>
<ul class="sns">
<li>
<a href="https://www.google.com/">구글</a>
</li>
<li>
<a href="https://www.facebook.com/">페이스북</a>
</li>
</ul>
</body>
</html>
"""
bs_obj = bs4.BeautifulSoup(html_str,'lxml')
atag = bs_obj.find_all('a')
print(atag)
for i in atag:
print(i['href']) #요소의 속성을 불러오기
지금까지 우리는 '태그' 를 불러오는 방법을 살펴봤다.
원하는 태그명을 집어 넣거나, 특정 태그를 불러오기 위해서 클래스를 이용해서 딕셔너리에 클래스명을 넣어 불러왔다.
이번에는 특정 태그의 속성을 불러오는 방법이다.
<태그>[<요소명>] 을 적어주면 태그 속성의 값을 가져올 수 있다.
print(bs_obj.a.attrs)
print(bs_obj.find('a').attrs)
print(bs_obj.a['href'])
print(bs_obj.a.attrs['href'])
print(bs_obj.a.get('href'))
태그의 요소값을 불러오는 방식은 다양하다.
uclass =bs_obj.find(True,{"class":'ko'})
print(uclass)
앞서서 딕셔너리를 이용해서 특정 클래스의 값을 가져왔는데,
단 하나만 가져왔다. 이때 태그와 상관없이 모든 특정 class 값들을 불러오고 싶다면 위와 같이
태그를 적는 란에 True를 적어준다.
bs_obj = bs4.BeautifulSoup(html_str,'lxml')
dv = bs_obj.find(id='result') #find 한거랑 똑같은 결과
print(dv)
위의 코드는 속성값을 이용하여 태그들을 가져오는 방법.
3)select_one()
import bs4
html_str = """
<html>
<body>
<ul class="ko">
<li>
<a href="https://www.naver.com/">네이버</a>
</li>
<li>
<a href="https://www.daum.net/">다음</a>
</li>
</ul>
<ul class="sns">
<li>
<a href="https://www.google.com/">구글</a>
</li>
<li>
<a href="https://www.facebook.com/">페이스북</a>
</li>
</ul>
<div id = "result">페이지</div>
</body>
</html>
"""
bs_obj = bs4.BeautifulSoup(html_str,'lxml')
ul_li = bs_obj.select_one('ul') #find 한거랑 똑같은 결과
ul_li = bs_obj.select_one('ul>li')
select_one() 은 find와 똑같은 효과를 가진다.
4)select()
select() 는 find_all 과 같은 효과를 가진다.
bs_obj.select('a') #select 는 find_all 과 같은 역할
a태그를 모두 가져온다.
bs_obj.select('.ko')
select 안에 .<클래스명> 을 적어줘서 class가 ko인 값들을 모두 가져온다.
bs_obj.select('ul.sns > li:nth-of-type(2)')
부모, 자식의 선택자 기법을 이용해서 특정 태그도 가져올 수 있다.
406 오류가 뜰 때 웹에서 데이터를 가져오는 방법
import bs4
import requests
#200 이 떠야지 정상
#Response [406] 은 기계가 사이트 접속하려고 할 때 사이트에서 자체 차단하는 오류임
url = 'https://www.melon.com/'
header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}
res = requests.get(url, headers = header)
bs_melon = bs4.BeautifulSoup(res.text,'lxml')
print(bs_melon)
header 없이 가져오게 된다면 response가 406 이 뜨게 된다.
406은 기계가 사이트 접속하려고 할 때 사이트에서 자체 차단하는 오류다.
res = requests.get(url, headers = header) 가 해결 방법.
우리가 url 을 통해서 데이터를 요청할 때 오류가 발생하는 경우,
headers 에다가 클라이언트(유저) 정보를 딕셔너리 방식으로 넣어주면 된다.
그럼 데이터 정보를 받아올 수 있다.
user-agent 경로 찾는 순서
f12 -> ctrl+r -> network -> news.naver.com -> user-agent
'크롤링' 카테고리의 다른 글
Selenium 크롤링(2) : 커피빈 크롤링 (0) | 2021.07.01 |
---|---|
Selinium 크롤링(1) (0) | 2021.07.01 |
크롤링 연습_할리스 커피 (0) | 2021.06.30 |
데이터 크롤링(2) (0) | 2021.06.30 |