크롤링을 위해서는 HTML언어에 관해 조금 알아둘 필요가 있다.
f12를 눌러 크롬 개발자모드에 들어가면 여러 태그들을 볼 수 있고 copy selector를 통해 복사할 수도 있고 ctrl+f로 원하는 태그가 잘 선택되었는지 확인할 수 있다.
CSS Selector에는 네가지 정도가 존재한다.
<h1>제목</h1>
👉 h1
<div id = "aaa"> 안녕 </div>
👉#aaa
<div class="aaa"> 안녕 </div>
👉.aaa
<div class="aaa"> <span> 안녕 </span> </div>
👉.aaa > span
2번째 자식태그 선택
<div class="aaa"> <span> 안녕 </span> <span> 바이 </span> </div>
👉.aaa > span : nth-child(2)
크롤링은 보통 BeautifulSoup와 Selenium을 이용하여 많이 진행한다.
BTS기사에 대한 크롤링을 진행하였다.
from bs4 import BeautifulSoup
import requests
#Get 요청, naver 서버에 대화 시도
response = requests.get('https://search.naver.com/search.naver?where=news&sm=tab_pge&query=BTS&sort=0&photo=0&field=0&pd=0&ds=&de=&cluster_rank=56&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:all,a:all&start=1')
#네이버에서 html 제공, text 메소드로 태그 내 텍스트만 추출
html = response.text
#html 번역선생님으로 수프 만듦
soup = BeautifulSoup(html, 'html.parser')
titles = soup.select('a.news_tit')
for title in titles:
art_title = title.text
link = title.attrs['href']
print(art_title, link)
1~10페이지의 기사를 크롤링하였다. 기사 url의 끝부분을 fstring으로 바꿔가면서 크롤링하였다.
pageNum=1
#1, 11, 21....91
for page in range(1,100,10):
print(f'{pageNum}번째 페이지입니다.')
#Get 요청, naver 서버에 대화 시도
response = requests.get(f'https://search.naver.com/search.naver?where=news&sm=tab_pge&query=BTS&sort=0&photo=0&field=0&pd=0&ds=&de=&cluster_rank=56&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:all,a:all&start={page}')
#네이버에서 html 제공, text 메소드로 태그 내 텍스트만 추출
html = response.text
#html 번역선생님으로 수프 만듦
soup = BeautifulSoup(html, 'html.parser')
titles = soup.select('a.news_tit')
for title in titles:
art_title = title.text
link = title.attrs['href']
print(art_title, link)
pageNum += 1
저번에 셀레니움을 설치할 때 크롬드라이버로인해 얼마나 오류가 많이 났었는지 모른다 ㅜ 그런데 셀레니움이 업데이트 되면서 크롬드라이버매니저가 생겨서 자동으로 관리를 해준다는 꿀팁을 얻었다!!🥰
pip install selenium
pip install --upgrade selenium
pip install webdriver_manager
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager # 크롬드라이버 자동업데이트
import time
service = Service(executable_path=ChromeDriverManager().install())
browser = webdriver.Chrome(service=service)
아마 파이썬으로 해당코드를 돌리면 잘 실행이 되는 것 같은데, 코랩에서 돌리니까 계속 에러가 났다. 그래서 구글링을 통해 다시 찾아봤다.
pip install selenium
pip install --upgrade selenium
pip install webdriver_manager
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager # 크롬드라이버 자동업데이트
import time
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
browser = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
이게 정확히 뭔진 잘 모르는데;;; 이러니까 잘 돌아가더라😊
네이버 > 쇼핑 > 검색창에 아이폰13 검색 > 맨 밑까지 커서 내리기 > 쇼핑리스트 크롤링
#웹페이지주소이동
browser.get("https://www.naver.com")
time.sleep(2)
browser.find_element(By.CSS_SELECTOR,'a.nav.shop').click()
time.sleep(1)
#검색창 찾기 = 클릭
search = browser.find_element(By.CSS_SELECTOR, 'input.co_srh_input._input ')
#검색어 입력
search.send_keys('아이폰13')
search.send_keys(Keys.ENTER)
time.sleep(2)
# 스크롤 전 높이
before_h = browser.execute_script("return window.scrollY") #execute_script = 자바스크립트 명령어 실행
# 무한 스크롤 - 반복문
while True:
# 맨 아래로 스크롤을 내린다. body = 모든 웹사이트에 존재
# 키보드의 END키 누르면 웹페이지 맨아래로이동
browser.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END)
time.sleep(1) # 스크롤 사이 페이지 로딩시간
after_h = browser.execute_script("return window.scrollY")
if after_h == before_h:
break
before_h = after_h # 스크롤 후 높이가 다르면 before_h를 업데이트
items = browser.find_elements(By.CSS_SELECTOR, 'li.basicList_item__2XT81')
lst=[]
i=1
for item in items:
name = item.find_element(By.CSS_SELECTOR, 'div.basicList_title__3P9Q7').text
price = item.find_element(By.CSS_SELECTOR, 'span.price_num__2WUXn').text
link = item.find_element(By.CSS_SELECTOR, 'div > a.basicList_link__1MaTN').get_attribute('href')
print(i,name, price,link)
i += 1
크롤링한 쇼핑리스트에서 핫딜상품을 제거해 주었다. (try-except구문을 사용하였는데, try에서 오류가 나면 except로 넘어간다.) 추가로 openpyxl을 사용하여 크롤링한 결과물을 엑셀파일로 저장해 보았다.
import openpyxl
from openpyxl import Workbook
wb = Workbook()
sheet = wb.active
sheet.append(['Ranking','Name','Price','Link'])
#웹페이지주소이동
browser.get("https://search.shopping.naver.com/search/all?query=%EC%95%84%EC%9D%B4%ED%8F%B013&cat_id=&frm=NVSHATC")
time.sleep(2)
# 스크롤 전 높이
before_h = browser.execute_script("return window.scrollY") #execute_script = 자바스크립트 명령어 실행
# 무한 스크롤 - 반복문
while True:
# 맨 아래로 스크롤을 내린다. body = 모든 웹사이트에 존재
# 키보드의 END키 누르면 웹페이지 맨아래로이동
browser.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END)
time.sleep(1) # 스크롤 사이 페이지 로딩시간
after_h = browser.execute_script("return window.scrollY")
if after_h == before_h:
break
before_h = after_h # 스크롤 후 높이가 다르면 before_h를 업데이트
items = browser.find_elements(By.CSS_SELECTOR, 'li.basicList_item__2XT81')
i=1
for item in items:
try:
hotdeal = item.find_element(By.CSS_SELECTOR, 'span.thumbnail_sale__T-L2g').text
continue
except:
name = item.find_element(By.CSS_SELECTOR, 'div.basicList_title__3P9Q7').text
price = item.find_element(By.CSS_SELECTOR, 'span.price_num__2WUXn').text
link = item.find_element(By.CSS_SELECTOR, 'div > a.basicList_link__1MaTN').get_attribute('href')
sheet.append([i,name, price,link])
i += 1
#간격조절
sheet.column_dimensions['A'].width = 10
sheet.column_dimensions['B'].width = 30
sheet.column_dimensions['C'].width = 20
sheet.column_dimensions['D'].width = 40
#크롤링 데이터 저장
wb.save(filename='iphone13_nohotdeal_crawling.xlsx')
추가로 네이버이미지검색에서 강아지를 쳤을 때 나오는 사진들을 크롤링해보았다. 나중에 이미지와 관련된 프로젝트를 하면 유용하게 사용할 수 있을 것 같다.
#from selenium import webdriver
#from selenium.webdriver.chrome.service import Service
#from webdriver_manager.chrome import ChromeDriverManager
#from selenium.webdriver.common.keys import Keys
#from selenium.webdriver.common.by import By
#import time
import os
import urllib.request # 이미지 저장 모듈
#service = Service(executable_path=ChromeDriverManager().install())
# 사용자 정의 검색어 받아오기 - Type your answer
keyword = "강아지"
# 폴더 만들기
if not os.path.exists(f'{keyword}'): # 해당 폴더의 존재여부를 boolean값으로 출력해줌
# not True = False : 해당폴더가 기존에 존재하지 않으면 새 폴더를 만든다!
os.mkdir(f'{keyword}')
url = f'https://search.naver.com/search.naver?sm=tab_hty.top&where=image&query={keyword}'
#browser = webdriver.Chrome(service=service)
browser.implicitly_wait(5)
browser.maximize_window() # 화면크기 최대화
browser.get(url)
time.sleep(2)
# 무한스크롤
# 스크롤 전 높이
before_h = browser.execute_script("return window.scrollY") #execute_script = 자바스크립트 명령어 실행
# 무한 스크롤 - 반복문
while True:
# 맨 아래로 스크롤을 내린다. body = 모든 웹사이트에 존재
# 키보드의 END키 누르면 웹페이지 맨아래로이동
browser.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END)
time.sleep(1) # 스크롤 사이 페이지 로딩시간
after_h = browser.execute_script("return window.scrollY")
if after_h == before_h:
break
before_h = after_h # 스크롤 후 높이가 다르면 before_h를 업데이트
# 이미지 태그 추출
imgs = browser.find_elements(By.CSS_SELECTOR, 'img._image._listImage')
for i, img in enumerate(imgs, 1): # enumerate(대상, 시작값)
# 이미지 다운을 위해선 태그에있는 이미지의 주소가 필요하다.
# Type your answer
img_src = img.get_attribute('src')
print(i, img_src)
# img를 index값의 파일명으로 png파일로 저장
urllib.request.urlretrieve(img_src, f'{keyword}/{i}.png')
열심히 교육해주신...
https://flannel-gardenia-fde.notion.site/5688867ae21f4ca0a66e4725a8f1ef34