크롤링이란 웹페이지에 있는 여러 정보를 포함한 데이터들을 긁어모으는 행위를 말한다.
즉, 웹페이지에 있는 정보를 수집하는 것이라 할 수 있다.
이러한 크롤링을 통해 필요한 정보를 수집하는 것이 이점이 무엇이냐 하면, 얼마전부터 시작된 AI의 모델링을 할 때 꼭 필요한 많은 양의 데이터를 수집할 수 있으며 좋은 모델을 만들 때도 사용되기에 매우 중요한 기술이라 할 수 있다.
이 라이브러리는 접근할 웹 페이지의 데이터를 요청/응답 받기 위한 라이브러리이다.
import requests as req
1. 수집할 웹 페이지의 주소 정의
url = 'https://www.naver.com'
2. 라이브러리를 이용해서 웹 페이지 요청
res = req.get(url)
3. 웹 페이지 확인
res.text
위 코드대로 한다면 수 많은 테그들이 정렬되지 않고 출력된다.
이 라이브러리는 웹 페이지에서 원하는 데이터를 추출하기 쉽게 python 객체로 변환해주는 라이브러리이다.
from bs4 import BeautifulSoup as bs
# bs(변환할 데이터, 변환방식)
html = bs(res.text, 'lxml')
html.select_one('title').text
결과로 title태그에 담긴 요소를 반환 받는다.
만약 .text를 사용하지않는다면 태그도 함께 긁어오니 주의해야한다.
또한, select_one은 하나의 태그만 긁어오고, select는 리스트 형태로 ()내부에 있는 태그 모두를 긁어온다.
리스트 형태로 긁어온 태그들은 1개만 있어도 인덱싱을 통해 접근 해야한다.
가끔 그냥 이렇게 하면 RemoteDisconnected 오류가 나올 수 있다.
이 오류는 정상적인 접은 방법이 아닐 경우 이렇게 오류가 날 수 잇는데, 브라우저로 요청을 보냈다라는 것을 서버에서 인식할 수 있도록 user-agent값을 구성하고 보내줘야한다.(버전도 신경써야함)
naver_news_url = 'https://news.naver.com/main/main.naver?mode=LSD&mid=shm&sid1=105'
header_option = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}
res = req.get(naver_news_url, headers = header_option)
가끔 크롤링이 잘 안된다 싶을땐 iframe으로 구성된 페이지 인지도 잘 확인해야한다.
iframe페이지의 경우 url이 한번 더 수정되어야 하기 때문에 크롤링이 되지 않는다. 특히 네이버가 iframe을 아주 즐겨 사용한다.
import requests as req
from bs4 import BeautifulSoup as bs
# 기본적인 라이브러리 호출
header_option = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}
finance_url = 'https://finance.naver.com/marketindex/'
res = req.get(finance_url, headers = header_option)
html = bs(res.text, 'lxml')
1. iframe 접근
currency_url = 'https://finance.naver.com'+html.select_one('iframe')['src']
#html.select_one('iframe')['src']이 부분에서 iframe의 url을 가져오고 가져온 url을 iframe 외부의 링크랑 더해주면 완성!
이렇게 만들어진 링크로 크롤링을 하면 잘 된다.
이 라이브러리 또한 여러가지 라이브러리를 제공한다.
!pip install selenium
!pip install 을 해야 사용이 가능하다.
from selenium import webdriver as wb
#html 요소에 접근하기 위한 방법을 제공하는 라이브러리
from selenium.webdriver.common.by import By
#키보드 값을 제공하는 라이블러리
from selenium.webdriver.common.keys import Keys
driver = wb.Chrome()
driver.get('https://www.naver.com')
#html 요소 접근하기
searchInput = driver.find_element(by='id',value='query')
# 접근한 요소에 key값 입력하기
searchInput.send_keys('돈까스\n')
#검색 버튼 찾기
search_Btn = driver.find_element(By.CLASS_NAME, value='btn_search')
#버튼 클릭하기
search_Btn.click()
#브라우저 뒤로 가기
driver.back()
#브라우저 스크롤 제어
body = driver.find_element(By.TAG_NAME, value='body')
body.send_keys(Keys.PAGE_DOWN)
selenium은 beautifulSoup과 request보다 더 많은 기능을 제공하고있다.
그 이유가 selenium은 동적 페이지에서 크롤링이 가능하기 때문이다.
가끔 너무 빨리 페이지 전환을 하거나 아직 html문서가 나오지 않았는데 실행문장이 실행되어 크롤링이 잘 되지 않을 때가 있다.
이러한경우 문서가 잘 받아질 때 까지 기다려줘야하는데, 그때 필요한것이 time 라이브러리이다.
time.sleep()을 사용하면 지정한 초 만큼 기다렸다가 문장이 실행된다.
컴퓨터에게는 마우스 휠이라는게 존재하지 ㅇ낳는다. 그래서 키보드의 입력으로 스크롤을 내릴 수 있다.
body = driver.find_element(By.TAG_NAME,"body")
body.send_keys(Keys.END)
이렇게 하면 스크롤이 최 하단까지 내려간다.
그렇다면 마지막까지 계속 내리고싶다면?
while True :
a = driver.execute_script('return document.body.scrollHeight');
body.send_keys(Keys.END)
time.sleep(0.5)
b = driver.execute_script('return document.body.scrollHeight');
if a==b:
break;
파일을 저장하려면 일단 파일이 필요하다!
#폴더나 파일 생성 라이브러리
import os
try :
os.mkdir('C:\\Users\\smhrd\\Desktop\\포켓몬')
print('폴더 생성 완료')
except :
print('같은 이름의 폴더가 존재합니다')
동일한 이름으로 파일을 2번 생성하면 오류가 나기 때문에 예외처리를 해준다.
from selenium import webdriver as wb # 웹 드라이버
from bs4 import BeautifulSoup as bs # html 파싱기
# URL의 내용 파일로 다운로드 하는데 사용되는 라이브러리
from urllib.request import urlretrieve
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
# 수많은 라이브러리를 import 해준다.
#이미지 태그를 긁어오고,
imgs = driver.find_elements(By.CLASS_NAME, 'img-fluid')
#반복문을 사용해 저장
for i in tq(range(len(imgs))):
urlretrieve(imgs[i].get_attribute('src'), f'C:\\Users\\smhrd\\Desktop\\포켓몬\\포켓몬{i}.jpg')
get_attribute(속성)을 사용한다면 해당 태그에 있는 속성만 가져올 수 있다.
앞서 말한 iframe접근법에서 조금 더 쉽게 접근하는 방법이 이제야 나왔다.
만약 해당 페이지를 열어 접근했다면,
driver.switch_to.frame('searchIframe')
# 이 함수를 통해 내부에 존재하는 iframe으로 접근이 가능하다.
그리고 만약 다른 iframe에 존재하고자 한다면 이전 프레임(기본 프레임)으로 다시 돌아가서 다시 선택해야한다.
# 이전 프레임으로 전환후 새롭게 나타난 프레임으로 다시 변환
driver.switch_to.default_content()
driver.switch_to.frame('entryIframe')
지금까지 크롤링 기초 맛보기를 해보았다.
그다지 내용은 많지 않지만 선택자를 많이 햇갈릴 수 있기 때문에 여러번 시도해보는것을 추천한다.