반응형

출처 : https://domdom.tistory.com/175

 

[크롤링] 파이썬으로 인스타그램 게시물 크롤링하기 (json)

처음 인스타그램 사이트에 들어가면 로그인창이 나와요. 일단 로그인을 해줍니다! https://www.instagram.com/ 그리고서, 원하는 게시물을 크롤링 하기 위해 게시물을 검색해볼게요. 저는 강아지를 좋

domdom.tistory.com

 

이분 코드로 진행해보았고 사진파일저장 & 엑셀저장까지 추가적으로 개발했다

 

 

 

빠르게 인스타그램 크롤링 하는방법 시작!!

 

1. 파이썬 다운로드

다운로드 url : https://www.python.org/downloads/

 

Download Python

The official home of the Python Programming Language

www.python.org

 

위 경로에 들어가서 파이썬 다운로드

 

다운로드할때 나는 D드라이브 경로로 별도지정해서 다운로드했다.

 

다운로드 끝났으면 CMD 창 (명령프로토콜)에서 확인해야하는데, 시작 바에서 CMD 치면 나온다.

 

파이썬이 잘 다운로드됐나 확인하기위하여 명령어를 입력해본다.

 

phtyon --version

파이썬 버전이 출력되면 정상적으로 된것.

 

 

2. vscode 다운로드

다운로드 URL: https://code.visualstudio.com/download

나는 윈도우 유저라서 시스템인스톨러 64bit 윈도우 용으로 다운받았다.

 

 

3. 인스타그램 로그인

 

1) 로그인 후 F12 버튼 누름

키보드에서 F12 누르면 관리자 창이 뜨는데 name 쪽을 보면 아직 깨끗하다.

 

2) 내가 원하는 태그명 검색

 

태그를 검색하면 주소창이 아래와 같은 형식으로 변경될것이다.

https://www.instagram.com/explore/tags/태그이름/ 

 

3) URL 변경

https://www.instagram.com/explore/tags/태그이름/?a=1

기존 url 에서?a=1 를 붙여서 들어가보면 json 파일 형식이 노출될것임.

 

이때 다시 f12로 들어가보면

?_a=1 이라는 name 이 보이고, 걔를 클릭해보면

Request Header가 존재하는데, 이 창을 유지한 상태로 냅둔다.

 

3. 필요 라이브러리 다운

 

1). cmd (명령 프로토콜)창에서 필요한 라이브러리들 다운받는다.

pip install openpyxl 
pip install requests
pip install datetime

요거 세개가 필요하다.

세줄 써있다고 한꺼번에 입력하지말고 한줄 입력 후 다운받아지면 그다음줄 입력하면된다.

 

4. vscode 실행 & 코드작성

 

1) 원하는 위치에 폴더하나 만들고 vscode를 실행한다. ex) D드라이브에 폴더하나 생성 

 

2) vscode 실행 > 파일 > 폴더열기 

    1.test 폴더를 연다.

 

 신뢰 안내창나오면 신뢰합니다 체크

문서하나 생성해서 test.py 로 py 파일 생성

 

 

정상적으로 생성됐으면 사진 저장할 폴더를 하나 만들어준다.

요 아이콘눌러서 images 라는 이름으로 생성

 

그리고 test.py에 아래 코드를 복붙. test 말고 다른이름으로 해서 생성해도되지만 꼭 .py가 붙어야된다.

 

from pprint import pprint
from openpyxl.workbook.workbook import Workbook
import requests
import json

from datetime import datetime

# 헤더값은 각자의 f12의 내용 참고해서 작성해야됨. 아래 코드의 값과 다를 수 있음.

header = {
    'accept': '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
    'cookie': 'f12에서 찾아서 넣어야됨 쿠키값',
    'referer': "f12에서 찾아서 넣어야됨",
    'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"',
    'sec-ch-ua-mobile': '?0',
	'sec-ch-ua-platform':'windows',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-origin',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
    'x-asbd-id': 'f12에서 찾아서 넣어야됨',
    'x-ig-app-id': 'f12에서 찾아서 넣어야됨',
    'x-ig-www-claim': 'f12에서 찾아서 넣어야됨',
    'x-requested-with': 'XMLHttpRequest'
}


dataList = []
URL = 'https://www.instagram.com/explore/tags/태그명/?__a=1' 

# 개수확인용도
pidCount = 0

while(True):

    res = requests.get(URL, headers =header)
    res = res.json()

    if 'next_page' not in res['data']['recent'].keys() or int(res['data']['recent']['next_page']) == 0: break
    max_id = res['data']['recent']['next_max_id'] 

    for n in res['data']['recent']['sections']: 

        for m in ((n['layout_content']['medias'])): 
            # m : 인스타 게시글 1개
            m = m['media']
            data = {} 
            data['pagePk'] = m['code']
            data['URL'] = 'https://www.instagram.com/p/'+ data['pagePk']+"/"
            data['user_name'] = (m['user']['username']) 
            
            # 이미지/동영상 체크
            keys = m.keys()
            if 'carousel_media' in keys:
                data['image'] = (m['carousel_media'])
            else:
                data['image'] = [{'image_versions2':{"candidates":[{'url':'동영상업로드'}]}}]


            dataList.append(data)
            pidCount = pidCount+1
            pprint (pidCount) # 개수확인용도

    URL = 'https://www.instagram.com/explore/tags/'+'태그명'+'/?__a=1&max_id='+max_id



# 엑셀 다운로드 및 이미지 저장

from openpyxl import Workbook
wb = Workbook()
ws = wb.active


#시트생성
sheet1 = wb['Sheet']
sheet1.title = '수집 데이터'
sheet1['A1'] = '아이디'
sheet1['B1'] = 'URL'
sheet1['C1'] = '이미지'

sheetIndex = 2

for data in dataList:
    sheet1['A'+str(sheetIndex)] = data['user_name']
    sheet1['B'+str(sheetIndex)] = data['URL']
     
    # 이미지링크 엑셀에 저장
    for imgUrl in data['image']:

        url = imgUrl['image_versions2']['candidates'][0]['url']
        sheet1['C'+str(sheetIndex)] = url
        
        # 이미지 폴더에 저장
        if not os.path.exists("./images/"+data['user_name']):
            os.mkdir("./images/"+data['user_name'])

        if url not in '동영상업로드':
            r = requests.get(url)
            file = open("./images/"+data['user_name']+'/'+data['user_name']+str(sheetIndex)+".jpg","wb")
            file.write(r.content)
            file.close()

        sheetIndex = sheetIndex+1



wb.save('./test1.xlsx')

 

 

헤더값은 아까 f12에서 구한 쿠키값..등등 제목보고 알아서 넣고

아까 이미지저장용 폴더를 images 라고 만들었는데, 다른 이름으로 생성하고싶으면 바꿔도된다. 하지만

위 코드에서 ./images 로 써져잇는 부분을 동일하게 꼭 바꿔줘야된다

 

최종적으로 저장되는 엑셀파일 이름도 wb.save('./test1.xlsx') 라고 되어있는데, 이부분을 원하는 엑셀이름으로 바꿔도됨.

 

이렇게하면, 1.test 라는 폴더안에 test1.xlsx 이 생성되고 images 폴더안에 사진들이 알아서 저장된다.

 

 

 

 

728x90
반응형

Execution failed for task  :compileJava'.

 

분명 Project Structure... 에서 JDK 버전도 제대로 적용시켜놨는데 자바 버전 차이로 안되는 이유를 찾아헤맸다.

 

Gradle을 쓰고있었는데 settings > Build, Executin, Deployment  > Gradle > Gradle JVM 설정이 변경이 안됐었다.

JVM설정 자바버전 동일하게 맞춰주니 정상적으로 빌드됨.

728x90
반응형

위 두가지 경우는 모두 내잘못이다.

 

mybatis 데이터 안넘어올때

 

1. dto 수정한적이 있는가?

2. 수정했다면, resultMap 에 해당 property & column을 추가하였는가?

3. select 할때 해당 데이터 컬럼명을 추가하였는가?

 

이 세가지만 보면 대체적으로 해결된다.

 

resultMap 안먹힐때

 

1. 데이터 받는 타입을 별도로 설정안했고 resultType 으로 받는가? 

2. 데이터 받는 타입을 resultMap으로 설정하였으며 resultMap 으로 받는가?

 

이게 이상하게..잘 안보이는데, 꼭 result type 인지 map 인지 확인하자

 

시간버리지말고!!!!!

728x90
반응형

로컬에서는 전~ 혀 문제가 없이 잘됨. 잘된다는 의미는

head 에 걸어놓은 js 파일들 전송 잘되고 css 안깨지고 백단에서도 오류가 없을 때.

 

그럴때 우선적으로 실서버 DB를 연결해서 실행해보자.

의외로 실서버 DB에 연결했을때 DB 세팅에서 놓친 부분이 있을 수 있다.

아주 위험한..주니어의 발상... 실서버 연결하면 안되요!!

 

그리고 JS / CSS 파일이 깨졌을 때 !

 

swiper.min.js 

Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

참고로 해당오류는 swiper-container / swiper-wrapper / swiper-slide 순서대로 안해줫을때 나타나는 오류이다

 

프론트의 문제가 아니라 백단에서 오류가 생겨서 F12 관리자 창에서도 Network 에 아무것도 안잡히고

'원인을 알수없는' 오류가 되어버린다.

 

분명 js/css 가 엉망진창이고 콘솔오류도 js에서 난다고 확인되는데 프론트에서 이상이 없다고 판단되면

실서버 DB붙여서 확인해볼것!

실서버 db 붙이면 안되요 ㅋㅋㅋㅋ 분명히 이유가 있습니다. 서버 로그를 확인하세요!

728x90
반응형

jsp단에서 java로 배열 array 전송 시 java.lang.NumberFormatException: For input string: "" 에러가 발생했다.

 

나의 경우

 

1. jsp에서 java 로 ajax 전송

var param = {
			"id" :"123",
			"isIssue" : "Y"
		     };

$.post('/경로', param, function(response){
			if (response.isSuccess) alert("성공);
});

 

2. 그리고 java 컨트롤러에서 잘 들어왔는지 확인 후 처리

@RequestMapping(value="/경로")
@ResponseBody
public JsonView codeCheck(TaxInvoice invoice) {
          //처리
}

들어올때 TaxInvoice 라는 dto 형식으로 들어오게되는데 해당 dto는 아래와 같다.

 

3. dto 형식

public class TaxInvoice {

  private String[] id;
  private String isIssue;

}

 

문제는 dto의 id를 보면 string[] array로 되어있었고 나는 파라미터를 보낼때 배열을 보내고싶었다.

var param = {
	"id" :["123","123"],
	"isIssue" : "Y"
};

 

그래서 위와같이 배열을 만들어서 넣어줬지만, 통하지 않았고 익셉션발생.

java.lang.NumberFormatException: For input string: "" (AbstractHandlerExceptionResolver.java : 133) *****
[07/27 10:56:32] OP-210727105632485-/opmanager/receipt/tax-invoice/update-status [AJAX] 	ERROR	1	-	-	-	***** [예외발생] {} (OpHandlerExceptionResolver.java : 76) *****
java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:592)
	at java.lang.Integer.parseInt(Integer.java:615)
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:327)
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:280)
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:95)
	at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:834)
	at org.springframework.validation.DataBinder.doBind(DataBinder.java:730)
	at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:189)
	at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:106)
	at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.bindRequestParameters(ServletModelAttributeMethodProcessor.java:150)
	at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:110)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

 

해결방법은 ajax post 옵션 설정에 있었다.

ajax 옵션 중 traditional : true를 추가해야 했었다.

 

축약형 $.post 형식으로 쓰고있어서 옵션을 예쁘게 넣는방법이 없나 고민했지만, 결국 풀어쓰기로했다.

 

var param = {
			"id" :["123","123"],
			"isIssue" : "Y"
		};

$.ajax({
		type : "post",
		url  : "/경로",
		data : param,
		traditional : true,
		dataType : "json",
		success: function (response){
			alert("성공");
			location.reload();
		}

	});

 

이걸몰라 삽질하고있었다니! 

 

728x90

+ Recent posts