[TIL] 셀레니움으로 인스타그램 이미지 크롤링하는 기능 넣어주기

Lea·2020년 6월 21일
0

목표

구글맵에서 마커를 클릭하면 생성되는 인포윈도우에 인스타그램 상호명 해시태그 이미지 불러오기

작업 순서

  1. 화면에서 마커를 클릭하면, 마커에 해당하는 상호명을 서버로 전달해주는 api 생성
  2. 상호명을 url에 키워드로 넣어서 해당 url로 해시태그 이미지 크롤링
  3. 서버에서 크롤링된 이미지 api로 전달
  4. 인포윈도우에 이미지 코드 삽입

험난한 과정

1. 화면에서 마커를 클릭하면, 마커에 해당하는 상호명을 서버로 전달해주는 api 생성하기

html 파일에서 api를 어느 부분에 넣어줘야 할지 헷갈렸는데, 튜터님의 도움을 받아 api 구조를 잡고 연결할 수 있었다. 일단 마커 클릭 시 인포윈도우 연결해줬던 이벤트 코드에 이미지 호출하는 기능도 합쳤고, 이미지 호출해오는 함수를 for문에 바로 넣으면 헷갈릴 것 같다는 조언에 따라 getInstaImages 함수로 따로 분리해줬다.

https://www.instagram.com/explore/tags/검색키워드

그리고 인스타그램 해시태그 검색시 url은 이런 형태로 이뤄지기 때문에, api로 마커에 해당하는 상호명을 가져와서 서버에서 크롤링할 url을 만들어주었다.

for (let i = 0; i < markerList.length; i++) {
              markerList[i].addListener('click', function () {
                infoWindowList[i].open(map, markerList[i]);
                getInstaImages(i);
              });
              // 인스타 이미지 API 호출
              function getInstaImages(i) {
                $.ajax({
                  type: 'GET',
                  url: '/reviews?filter=' + titleList[i],
                  data: {},
                  success: function (response) {}
                  })
                  }
                  

2. 상호명을 url에 키워드로 넣어서 해당 url로 해시태그 이미지 크롤링하기
3. 서버에서 크롤링된 이미지 api로 전달하기

원래는 인스타그램 이미지 크롤링하려면 수업시간에 배웠던 Beautifulsoup만 활용해서 쉽게 해결될 줄 알았는데, 아무리 해도 잘 안 되어서 검색해보니 인스타그램은 코드 특성상 셀레니움을 써야... 크롤링을 할 수 있었다.

순간 욱해서 크롤링 해오는 기능 빼버릴까 싶었지만, 그래도 다행히 잘 정리해주신 분들이 많아서 마음을 다잡고 차근차근 따라하니 생각보다는 금방 크롤링할 수 있었다😃


참고했던 영상 링크

https://www.youtube.com/watch?v=wsT3C3OH_QQ


처음에는 셀레니움이라는 단어 듣자마자 새로운 기능이라 괜히 어렵게 느껴졌는데, (셀레니움 발음도 뭔가 어려운 것 같고...?) 웹드라이버 깔고나서 기본 코드 몇 줄 적용하고 나니 그 다음부터 원하는 값 추출하는건 원래 배웠던거랑 비슷했다.

그리고 영상에서는 크롤링 해올 때마다 chorme 창을 띄우게 되는데, 아무래도 실제 웹페이지에서 사용자가 클릭할 때마다 웹창이 뜨면... 너무 이상한 것 같아서 구글링을 통해 옵션값으로 창을 띄우지 않게 수정해줬다.

@app.route('/reviews', methods=['GET'])
def insta_crawl():
    keyword = request.args.get('filter')

    #이미지 크롤링
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('headless')
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("lang=ko_KR")
    driver = webdriver.Chrome(executable_path="choyeongkyung-sparta/bread_map/python_insta_selenium_crawl/webdriver/chromedriver.exe", chrome_options=chrome_options)
    url ="https://www.instagram.com/explore/tags/"+str(keyword)
    
    driver.get(url)
    sleep(2)
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')

    reviews = soup.select('div.EZdmt > div > div > div')

    image_list = []
    for image in reviews:
        image_tag = image.select_one('a > div > div > img')['src']
        image_list.append(image_tag)
    driver.close()
    return jsonify({'result': 'success', 'image_list': image_list})

4. 인포윈도우에 이미지 코드 삽입
서버로부터 크롤링된 이미지 url 리스트를 받은 후, 인포윈도우에 삽입하는건 예전에 했던 예제랑 비슷해서 수월하게 끝냈다. infowindow에 이미지 들어갈 div에 insta-image-wrapper-${i}라는 id를 부여하고, 해당 위치에 이미지 태그를 append해줬다.

function getInstaImages(i) {
                $.ajax({
                  type: 'GET',
                  url: '/reviews?filter=' + titleList[i],
                  data: {},
                  success: function (response) {
                    if (response['result'] == 'success') {
                      let images = response['image_list'];

                      image_tag = 
                                  `<div class="card-group"> 
                                    <div class="card"><img src=${images[0]}></div>
                                    <div class="card"><img src=${images[1]}></div>
                                    <div class="card"><img src=${images[2]}></div>
                                  </div>`
                      $(`#insta-image-wrapper-${i}`).empty()
                      $(`#insta-image-wrapper-${i}`).append(image_tag)
                    }
                  }
                  })
              }
            

완성된 모습

지도에서 마커를 클릭하면 뜨는 인포윈도우의 모습👏 근데 생각한 것보다 인스타그램 이미지 크롤링해오는데 속도가 좀 많이 오래 걸려서... 로딩되고 있다는 걸 보여줄 수 있게 코드를 추가해주었다.

인스타 이미지가 들어올 div에 초기값으로는 로딩 이미지가 나오고, 크롤링이 완료되면 해당 div를 비워준 다음 크롤링한 이미지를 띄우도록 작성했다.

요즘 부쩍 코딩을 하면서 느끼는 건, 모든 일이 다 그렇듯이 아무리 처음에 잘 기획했다고 느껴도 뭐든 계획대로 착착 진행되는 건 없다는 점이다. 이래저래 기존에 예상했던 작업 방향이나 과정과는 조금 달라지기 마련이고, 원하는 결과물에 가장 근접한 방향으로 그때 그때 판단해서 수정할 수밖에 없는 것 같다. 하지만 결국에 뭔가 바뀌더라도 어쨌든 기획서가 그 방향을 어디로 할지 잡아주는 역할을 하니까 기획서를 잘 작성하는게 중요하다는 점은 변함없는 듯하다.

다소 횡설수설 기록하긴 했지만 처음에 그렸던 기획서와 유사하게 1차로 페이지를 완성했으니, 이제 페이지 조금씩 다듬어가면서 DB 쌓는 부분을 만들어갈 예정이다. 남은 한 주도 앞으로 화이팅👊

profile
마케터로서 혼자 고민하고, 공부하고, 기록합니다.

0개의 댓글