픽사베이 (https://pixabay.com/ko/)
를 이용한 한개의 이미지 수집, 여러이미지 수집에 대해서 크롤링해보려고합니다.
#임포트+타임+셀레니움
import chromedriver_autoinstaller
import time
from selenium import webdriver
가장먼저 url확인을 해주려고합니다.
강아지사진을 선택하려고하고 그 부분에 대한 url을 가져왔더니 아래와 같습니다.
고양이로 하고싶다면 강아지를 고양이로 변경하면 됩니다!
#크롬웹브라우저를통해 강아지가 검색된 url가져오기
driver = webdriver.Chrome()
driver.get(url)
#원하는 이미지의 xpath+이미지url 구하기
image_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]/div/div/div[3]/div[2]/div/a/img'
image_url = driver.find_element('xpath', image_xpath).get_attribute('src')
print('image_url: ', image_url)
이미지에는 src라는 속성이 있고 거기에는 url이 있습니다.
소스의 속성을 알아내면 이미지의 주소를 알아낼 수 있습니다.
그래서 get_attribute('src')를 이용해서 소스(src)를 구하면 주소를 받을 수 있습니다.
#출력결과
클릭시 이미지 다운이 됩니다.
#이미지 읽어오기를 하기 위한 임포트
from urllib.request import Request, urlopen
url라이브러리 안에있는 request입니다.
urlib.request의 장점은 장점은 여러가지 서버로부터 html, css,자바스크립트뿐만아니라 이미지와 동영상등을 접속해서 가져올 수 있습니다.
바이너리코드로 읽어들인 후 파일객체로 쓰게 되면 내 컴퓨터에 복원될 수 있다는것도 장점입니다.
#이미지 읽어오기를 하기 위한 임포트
image_byte = Request(image_url, headers={'User-Agent':' html의 user-Agent 의 내용을 적기)'})
#객체파일만들기
pic이 파일 이름이 됩니다. 객체파일형태도 함께 적어주기 #wrabt
f = open('pic.jpg', 'wb') # w:write, r:read, a:append, b:binary(글자가아닌파일), t:text
#객체파일만들기
f.write(urlopen(image_byte).read())
파일을 만들고(write) image_byte를 가져와서 urlopen하고 read읽어주고 내 컴퓨터에 write해주겠다는 의미입니다.
#파일 닫기
파일을 닫아야 저장이 됩니다.
f.close()
**headers는 html의 user-Agent를 복사해서 오면 됩니다.
사람인양 유저에이전트를 보내고 접속을 해서 해당이미지를 바이트로 가져옵니다.
이미지 영상을 가져와서 객체를 만들어줍니다
open이라는 매소드는 파일을 만들어줄수도있고 읽어줄수도 있는 매소드입니다
2. 여러개 이미지 수집하기
#임포트하기
import time
from selenium.webdriver.common.by import By
#url 가져오기
driver = webdriver.Chrome()
driver.get(url)
#20바퀴를 돌면서 스크롤내리기(스크롤내리면 새로운 이미지 생성)
for _ in range(20):
driver.execute_script("window.scrollBy({ top: window.innerHeight, behavior: 'smooth' })")
time.sleep(0.5)
▶ top은 윈도우에서 스무스하게 20번 내려와줘 라는 뜻
#xpath를 활용하여 사진이름지정 및 파일에 저장
image_area_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]'
image_area = driver.find_element(By.XPATH, image_area_xpath)
image_elements = image_area.find_elements(By.TAG_NAME, 'img')
#빈 리스트를 생성해서 for문을 활용하기
for image_element in image_elements:
image_url = image_element.get_attribute('src')
print(image_url)
image_urls.append(image_url)
▶ 이미지 주소있는 부분에다가 주소에 담아주고 프린트를 해주고 위에 빈 리스트에 append해줍니다.
스크롤20번하면서 추출한 이미지.
#폴더에 저장하기
import os
from urllib import parse
os : 경로에 대한 모듈
parse :
#이미지를 변수 url에 저장
for i in range(len(image_urls)):
image_url = image_urls[i]
url = parse.urlparse(image_url)
** parse.urlparse는 이미지를 분해할 수 있는 매소드
#파일이름.확장명으로 결과값나오게하기
name, ext = os.path.splitext(url.path)
#url에서 사람처럼 접근하고 파일가져오기
image_byte = Request(image_url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'})
#dog이미지뒤에 1,2,3,4 등 숫자,확장명 붙이기
f = open(f'dog{i}.{ext}', 'wb')
#데이터를 읽어와서 파일을 쓰고 close로 저장하기
f.write(urlopen(image_byte).read())
f.close()
이렇게하면 파일에 dog사진이 엄청많이 저장되어있습니다.
3. 함수로 리팩토링
이미지를 검색하고 다음페이지를 누르면 주소창이 pagi=2로 변하게됩니다
또 다음페이지는 3으로 변한다는 규칙을 알았습니다.
#키워드를 넣고 어떤걸 검색할건지?, 2초후에 다시 다음페이지로 넘기는 for문 돌기
def crawl_and_save_image(keyword, pages):
image_urls = []
for i in range(1, pages+1):
driver.get(url)
time.sleep(2)
#20번 반복(스크롤 부드럽게 내리기)
for _ in range(20):
driver.execute_script("window.scrollBy({ top: window.innerHeight, behavior: 'smooth' })")
time.sleep(0.5)
image_area_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]'
image_area = driver.find_element(By.XPATH, image_area_xpath)
image_elements = image_area.find_elements(By.TAG_NAME, 'img')
#이미지 소스가져와서 image_url에 넣기
for image_element in image_elements:
image_url = image_element.get_attribute('src')
print(image_url)
image_urls.append(image_url)
#작업 경로에 폴더가 없는지 확인, 없으면 선물이라는 디렉토리를 만듦
if not os.path.exists(keyword):
os.mkdir(keyword)
#파일저장
for i in range(len(image_urls)):
image_url = image_urls[i]
url = parse.urlparse(image_url)
#이미지url은 /으로 나눈다음에 [-1]로구하면 파일네임 추출가능, 저장은 파일네임 그대로 저장
filename = image_url.split('/')[-1]
image_byte = Request(image_url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'})
f = open(f'{keyword}/{filename}', 'wb')
f.write(urlopen(image_byte).read())
f.close()
#실행
driver = webdriver.Chrome()
crawl_and_save_image('선물', 2)