ABOUT ME

IT와 컴퓨터 관련 팁, 파이썬 등과 아파트 정보, 일상적인 경험 등의 생활 정보를 정리해서 올리는 개인 블로그

  • 동적(JavaScript) 웹 페이지의 json 데이터 형식 이미지 다운로드 (with 파이썬)
    코딩 연습/코딩배우기 2022. 1. 11. 09:44
    반응형

    파이썬을 가지고 웹 스크래핑을 해봤다면, 동적으로 렌더링 된 웹 사이트에서 BeautifulSoup나 requests로 이미지 등의 콘텐츠를 스크래핑한다는 것이 어렵다는 것을 알 것이다.

    파이썬으로 다수의 unsplash 이미지 다운로드 해보기

    스크래핑을 연습할 대상 사이트는 unsplash.com이며, 페이지 소스보기를 해서 보면 javascript 소스로 되어있다.

    아래 소스코드는, 자바스크립트를 사용하는 동적인 웹 사이트에서 BeautifulSoup 또는 selenium을 사용하지 않고 개발자 도구를 최대한 활용하여 관련 데이터를 찾아낸 후,  

    requests 라이브러리로만 이미지를 스크래핑하는 것을 보여준다.


    개발자 도구(F12)의 Network > XHR에서 search?query=dog&...로 된 부분을 탭으로 open 해서 json 데이터를 확인하고,

    이미지를 다운로드하는 클래스를 만들어서 사용하는 방법을 알려주고 있다.


    코딩 절차는

    • 초기 변수(검색 키워드는 필수, 추출 이미지 개수와 이미지 품질은 선택적임)를 파라미터로 받아서 각각 대입,
    • URL에 f-string 포맷으로 변수를 세팅,
    • requets로 url에 접근하여 json 데이터 요청,
    • 이미지를 저장할 폴더 생성과 이미지명을 등록자 아이디로 만들어서,
    • 이미지를 다운로드하는 과정을 밟는다.

     

    서비스 이미지는 검색 키워드 당 30개인 듯하고,

    이미지 품질을 raw, full, regular, small, thumb 등으로 설정하여 받을 수 있다.

     

    json 데이터에는 여러 정보가 있다.

    그중에서 id와 이미지 url만을 사용한다.

     

     

    데이터 확인

    import requests
    
    url = 'https://unsplash.com/napi/search?query=dog&per_page=20&xp='
    r1 = requests.get(url, headers={'user-agent': 'Mozilla/5.0'})
    print(r1.text[:1000])
    print(r1.text[-200:])
    
    #################################################################
    
    [결과]
    {"photos":{"total":10000,"total_pages":500,"results":[{"id":"yihlaRCCvd4","created_at":"2018-06-29T10:15:36-04:00","updated_at":"2022-01-10T06:03:53-05:00","promoted_at":"2018-06-30T10:58:13-04:00","width":4016,"height":6016,"color":"#f3f3f3","blur_hash":"L$Nm~Ht7tlof~VaeV@fk%gogaKax","description":null,"alt_description":"dog running on beach during 
    daytime","urls":{"raw":"https://images.unsplash.com/photo-1530281700549-e82e7bf110d6?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MXx8ZG9nfHwwfHx8fDE2NDE4NDMzODU\u0026ixlib=rb-1.2.1","full":"https://images.unsplash.com/photo-1530281700549-e82e7bf110d6?crop=entropy\u0026cs=srgb\u0026fm=jpg\u0026ixid=MnwxMjA3fDB8MXxzZWFyY2h8MXx8ZG9nfHwwfHx8fDE2NDE4NDMzODU\u0026ixlib=rb-1.2.1\u0026q=85","regular":"https://images.unsplash.com/photo-1530281700549-e82e7bf110d6?crop=entropy\u0026cs=tinysrgb\u0026fit=max\u0026fm=jpg\u0026ixid=MnwxMjA3fDB8MXxzZWFyY2h8MXx8ZG9nfHwwfHx8fDE2NDE4NDMzODU\u0026ixlib=rb-1.2.1\u0026q=80\u0026w=1080","small":"https://images.unsplash.com/phot
    .....
    ..... 
    {"title":"dog winter"},{"title":"family"},{"title":"dog owner"}],"meta":{"keyword":"dog","title":"500+ Dog Pictures | Download Free Images on Unsplash","description":null,"index":false}}

    good4me.co.kr


    소스코드

    import requests
    import os
    
    class Imagescrapper:
        def __init__(self, search_keyword, per_page=20, quality='thumb'):
            self.search_keyword = search_keyword
            self.download_dir = search_keyword
            self.per_page = per_page
            self.cnt = 1
            self.quality = quality
    
        ## url setting
        def set_url(self):
            return f'https://unsplash.com/napi/search?query={self.search_keyword}&per_page={self.per_page}&xp='
    
        ## requests()
        def make_request(self):
            url = self.set_url()
            r1 = requests.get(url, headers={'user-agent': 'Mozilla/5.0'})
            return r1
        
        ## 데이터 변환
        def get_data(self):
            self.data = self.make_request().json()
    
        ## 저장할 디렉토리 생성 / 파일명도 만들어서 리턴
        def save_path(self, name):
            if not os.path.exists(self.download_dir):
                os.mkdir(self.download_dir)
            return f'{os.path.join(os.path.realpath(os.getcwd()), self.download_dir, name)}.jpg'
    
        ## 이미지 링크(URL)에 대해 requests.get() 다운로드(디렉토리에 저장)  
        def download_image(self, image_url, name):
            filepath = self.save_path(name)
            print(filepath)
            with open(filepath, 'wb') as f:
                f.write(requests.get(image_url, headers={'user-agent': 'Mozilla/5.0'}).content)
    
        ## 해당 객체의 메인 메소드 역할
        def scrapper(self):
            for _ in range(1):
                self.make_request()
                self.get_data()
                for item in self.data['photos']['results']:
                    name = item['id']
                    image_url = item['urls'][self.quality]
                    self.download_image(image_url, str(self.cnt).zfill(3) + '_' + name)
                    self.cnt += 1
    
    scraping = Imagescrapper('dogs', 30, 'full')  # raw, full, regular, small, thumb
    scraping.scrapper()

     

     

    폴더에 저장된 이미지 리스트

     

     

    ※ [출처] : Scrape Dynamically loaded websites with python | python webscraping technique 2020 | python project

     

     

     

    반응형
Designed by goodthings4me.