인프런 커뮤니티 질문&답변

박종석님의 프로필 이미지
박종석

작성한 질문수

남박사의 파이썬 기초부터 실전 100% 활용

다른 페이지 ajax 크롤링 질문 드립니다.

작성

·

930

1

롯데시네마 페이지를 크롤링 해보려고하는데

위와 같이 제가 필요한 영화 상영 정보가 xhr 타입으로 넘어오는 걸 알게 되서 

ajax 크롤링 강의 영상보면서 따라하고 있는데 오류가 나타나서 질문 드립니다 ㅎㅎ

import requests
from bs4 import BeautifulSoup
import json
import pprint


url = "http://www.lottecinema.co.kr/LCHS/Contents/Cinema/Cinema-Detail.aspx?divisionCode=1&detailDivisionCode=1&cinemaID=1013"

dic =  {"MethodName":"GetPlaySequence",
        "channelType":"HO",
        "osType":"Chrome",
        "osVersion":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
        "playDate":"2019-12-10",
        "cinemaID":"1|1|1013",
        "representationMovieCode":""}

res = requests.post(url, data=dic)
result = json.loads(res.text)

print(result)

코드는 위와 같이 작성했는데

처음에 get 방식으로 요청을 해서 오류가 나타나길레  혹시 요청방식에 문제가 있나 보니까 post로 가는데 get으로 요청을

했어서 

요청 방식을 바꾸어서 post로 파라미터값과 함께 넘겨주어 봤는데도 오류가 나서 

오류 구문은 다음과 같습니다.

Traceback (most recent call last):

  File "C:/Git/my_web_cgv/ex2.py", line 23, in <module>

    result = json.loads(res.text)

  File "C:\Users\jong\AppData\Local\Programs\Python\Python37-32\lib\json\__init__.py", line 348, in loads

    return _default_decoder.decode(s)

  File "C:\Users\jong\AppData\Local\Programs\Python\Python37-32\lib\json\decoder.py", line 337, in decode

    obj, end = self.raw_decode(s, idx=_w(s, 0).end())

  File "C:\Users\jong\AppData\Local\Programs\Python\Python37-32\lib\json\decoder.py", line 355, in raw_decode

    raise JSONDecodeError("Expecting value", s, err.value) from None

json.decoder.JSONDecodeError: Expecting value: line 3 column 1 (char 4)

오류 구문을 구글링해서 찾아보니깐

Check the response data-body, whether actual data is present and a data-dump appears to be well-formatted.

In most cases your json.loadsJSONDecodeError: Expecting value: line 1 column 1 (char 0) error is due to :

  • non-JSON conforming quoting
  • XML/HTML output (that is, a string starting with <), or
  • incompatible character encoding

비슷한 질문이 올라와 있어서 번역기로 보니깐 다음과 같은 해결책을 제시해주는데 제가 가진 지식으로는

무슨 소리인지 어려움이 있어 이렇게 질문 남겨요 ㅠㅠ

 

답변 5

1

남박사님의 프로필 이미지
남박사
지식공유자

오류의 내용은 json.loads 에 넘어온 res.text 가 json 형태의 데이터가 아니라서 생기는 오류 입니다.

url = "http://www.lottecinema.co.kr/LCHS/Contents/Cinema/Cinema-Detail.aspx?divisionCode=1&detailDivisionCode=1&cinemaID=1013"

res.text 는 위 주소의 HTML 문서 내용이기 때문에 json 형태 "키": "값" 의 형태가 아니라서 당연히 json 형태로 변환이 불가능해서 생기는 오류가 맞습니다. xhr 방식으로 동작하는 주소는 스샷에서 처럼 TicketingData.aspx 혹은 CinemaData.aspx 로 시작하는 주소가 실제 xhr 로 동작하는 페이지로 보입니다. 그리고 ajax로 호출되는 해당 TicketingData.aspx 페이지로 데이터가 넘어가는걸 보시면

코드에서 작성하셨던 MethodName:... 등의 데이터가 그대로 전송되는게 아니라 해당 데이터가 paramList 라는 큰 변수안에 모두 속해 있는걸 볼 수 있습니다. 그러니까 

dic =  {
    "MethodName": "GetMoviePlayDates",
    "channelType": "HO",
    "osType": "Chrome",
    "osVersion": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
    "multiLanguageID": "KR"
}

위의 데이터를 다시 paramList 라는 변수로 모두 등록해야 합니다.

data = {"paramList": dic}

제가 위의 dic 데이터를 paramList 라는 변수로 다시 data 라는 변수에 모두 적용해서 해당 페이지를 호출 해봤더니 인코딩 오류가 또 발생했습니다. 서버쪽으로 POST 형태로 데이터를 전송하니 UTF-8 Bytes 형태로 보내기 위해서 encode() 함수를 사용했습니다.(꼭 해보셔서 어떤 오류가 나는지 확인하세요)

따라서 전체적으로 정리해보면

import requests
from bs4 import BeautifulSoup
import json
import pprint

dic =  {
    "MethodName": "GetMoviePlayDates",
    "channelType": "HO",
    "osType": "Chrome",
    "osVersion": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
    "multiLanguageID": "KR"
}

# 위의 dic 변수의 내용을 paramList 라는 변수명으로 다시 설정합니다.
# encode() 를 하지 않으면 해당 페이지를 접속했을경우 인코딩 오류가 발생합니다.
data = {"paramList": str(dic).encode()}

# 실제 ajax로 호출되는 주소는 아래 주소 입니다.
url = "http://www.lottecinema.co.kr/LCWS/Ticketing/TicketingData.aspx?nocashe=0.1769098203549624"

# 해당 주소로 paramList 변수의 데이터를 POST 형태로 전송합니다.
r = requests.post(url, data=data)

result = json.loads(r.text)

print(result)

위의 코드가 정상 동작 합니다.

많은 도움이 됐습니다. 감사합니다. :)

남박사님의 프로필 이미지
남박사
지식공유자

감사합니다~

0

남박사님의 프로필 이미지
남박사
지식공유자

넵 화이팅 하십시요~~~!!! 

궁금한점 생기시면 언제든 질문주시기 바랍니다 ^^

0

박종석님의 프로필 이미지
박종석
질문자

감사합니다. 어디서 문제가 생기는지 확실히 이해 했습니다.

크롤링 성공해서 flask 강의 올려주신 걸로 페이지 만드는 것 까지 꼭 성공하고 싶네요 ㅎ

0

남박사님의 프로필 이미지
남박사
지식공유자

제가 답변을 수정하는 사이에 다시 질문을 주셨네요. 제가 질문을 잘못 이해해서 다시 답변을 수정했습니다. 코드 짜고 테스트 해보느라 시간이 걸리는 와중에 다시 질문을 주신거 같습니다. ㅎㅎㅎ 원래 답변 다시 확인 부탁드립니다.

0

박종석님의 프로필 이미지
박종석
질문자

{'IsOK': 'false', 'ResultMessage': 'ParamList가 존재하지 않습니다.', 'ResultCode': None, 'EventResultYn': None}

import requests
from bs4 import BeautifulSoup
import json

url = "http://www.lottecinema.co.kr/LCWS/Ticketing/TicketingData.aspx?nocashe=0.9677176967145242"
dic = {
    "MethodName":"GetMoviePlayDates",
    "channelType":"HO","osType":"Chrome",
    "osVersion":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
    "multiLanguageID":"KR"
}
res =requests.post(url, data=dic).json()
print(res)

위와 같이 요청을 보내면

다음과 같이

{'IsOK': 'false', 'ResultMessage': 'ParamList가 존재하지 않습니다.', 'ResultCode': None, 'EventResultYn': None}

이런 형태로 반환이 되는데 

이런 식으로 받으려고 하는데 어디가 문제인지 알 수 있을까요 ?

박종석님의 프로필 이미지
박종석

작성한 질문수

질문하기