# Instagram Crawler ## 분석을 해보자 프로필 주소 https://www.instagram.com/dlwlrma GET 파라미터로 뒤에 ```?__a=1```를 붙이면 유저 피드를 가져올 수 있다. https://www.instagram.com/dlwlrma?__a=1 으로 요청을 보내면?? ![](https://i.imgur.com/5jBOmXP.png) JSON 형식의 response를 받음 ``` JSON 포맷이 궁금하면? JSON 이쁘게 출력해주는 사이트 - https://jsonformatter.curiousconcept.com/ ``` display_url 값이 각 게시물 사진의 source url ex) https://scontent-icn1-1.cdninstagram.com/v/t51.2885-15/e35/s1080x1080/70506894_2402153720035448_4657675671201413047_n.jpg?_nc_ht=scontent-icn1-1.cdninstagram.com&_nc_cat=1&_nc_ohc=ekNEXVgJ8EMAX9-8hEs&oh=d1bdcd7c255e7afb0a59081405d713a0&oe=5EAE379B ```oe 필드까지 복사해야 타임스탬프 에러가 나지 않음``` 근데 게시물은 400개가 넘는데 display_url을 검색하면 원본 사진 주소가 12개밖에 안나온다. -> 나머지는 스크롤을 내릴 때 추가로 가져온다는 걸 알 수 있다. 다음 게시물을 가져올 때 어떻게 요청을 보내는지 크롬 개발자도구에서 확인해보자 ![](https://i.imgur.com/rP10XEU.png) 대충 저 요청 아래부터 사진을 주르륵 받는걸 봐서 느낌이 온다. 자세히보자 <br> ![](https://i.imgur.com/wgOzbAq.png) 위 링크 복붙해서 들어가보면 다음 게시물의 사진을 찾을 수 있다. 인스타그램에서는 다음 게시물들을 가져오기 위해 graphql이라는 쿼리를 사용하는데, graphql 쿼리요청을 보내면 다음 페이지의 사진/동영상을 받아온다. 이제 이 쿼리의 GET 파라미터를 필요에 맞게 변경해서 요청을 보내면 응답으로 받은 JSON에서 사진/동영상의 원본 주소를 가져오면 될 것 같다! URL 인코딩이 되어 있으니 디코딩을 해주자 ``` https://www.instagram.com/graphql/query/?query_hash=e769aa130647d2354c40ea6a439bfc08&variables={"id":"1692800026","first":12,"after":"QVFEenZvZV9MV0REMjR6RHhrWi1Mbk5ibEJ0LXprbnR3bmY0ZW04WGR1YW9XMHA4cXl6QkpvNDJyZTV5X2tZSmdmclo1R254X3Y5Mm5rVk9TamlCeEtCMw=="} ``` (총기)분해 ㄱㄱ ``` https://www.instagram.com/graphql/query/ ?query_hash=e769aa130647d2354c40ea6a439bfc08 &variables={ "id":"1692800026", "first":12, "after":"QVFEenZvZV9MV0REMjR6RHhrWi1Mbk5ibEJ0LXprb nR3bmY0ZW04WGR1YW9XMHA4cXl6QkpvNDJyZTV5X2t ZSmdmclo1R254X3Y5Mm5rVk9TamlCeEtCMw==" } ``` - ***qeury_hash*** : 요청 쿼리 길이를 줄이기 위해 전체 쿼리를 해쉬값으로 요청함 이 query_hash는 fix된 값이라 변하지 않는다. 꿀^^ - ***variables*** : 유저정보 및 불러올 게시물 정보가 담겨있다 + ***id*** : 유저 아이디 - 유저별 고유값 + ***first*** : 불러올 게시물 수 - after를 기준으로 최대 다음 50개의 게시물을 불러옴 (순서는 최신 게시물 -> 오래된 게시물 순) + ***after*** : end_cursor - 다음 게시물을 불러올 때 이전 쿼리에서 게시물을 어디까지 불러왔는지 기준이 되는 필드 ## 개발 목표 ### 기본 목표 - username(ex: dlwlrma)을 사용자에게 입력받으면 user id 및 게시물 수 파싱 - 크롤링 대상 user의 모든 사진 및 비디오 파일 다운로드 ### 추가 구현 - hashtag검색 기반으로 검색어를 입력받으면 사진 및 비디오 다운로드 - 멀티스레드/비동기 요청을 사용해 크롤링 성능 향상 ### 개발환경 및 필요한 모듈 #### 기본목표 구현 Python 3.5 requests re beautifulsoup #### 추가 구현 asyncio/aiohttp (http 비동기요청) aiofiles