Monday, March 28, 2011

google appengine url fetch 제약사항

mechanize로 네이버 로그인하기 에서 카페글 쓰기 때문에 고생하고 있다는 얘기를 썼었는데.. 결론부터 얘기하자면 헛고생이었습니다...
문제는, 카페에 로그인한 뒤 카페글 읽는 것이 firefox에서는 제대로 되는데 appengine에서는 제대로 동작하지 않는다는 것.

문제 해결을 위해 다음과 같이 진행했습니다.
1. firefox 의 javascript를 disable
2. firefox plug-in HttpFox를 이용해 request header와 response header를 한줄한줄 비교.
3. mechanize로 한줄한줄 작성하고 결과를 비교
4. appengine 으로 옮기고 실행

문제는, 1~3까지는 정상적으로 동작을 하는데 appengine으로 코드를 옮기기만 하면 에러가 난다는 것. 사실 에러까지는 아니고, IP가 틀리게 나와서 로그인을 다시해야 한다는 둥..의 메시지가 나옵니다.

이 문제로 며칠동안 삽질을 했었는데, 원인을 따라가다 보니 문제는 Host 헤더에 있는 것으로 보입니다. 즉, 카페글을 읽으려면 Host:cafe.naver.com 으로 표시가 되고, 실제로 mechanize에서도 해당 헤더를 포함시키면 정상동작합니다.
문제는 appengine에서는 보안 문제로 Host 헤더의 수정을 허용하지 않는다는 점입니다.

이 문제를 해결하자면, appengine이 아닌 다른 서버를 이용하거나, 네이버 검색글 읽기 같은 꽁수를 이용하는 방법이 있을텐데.. 개인적으로는 그만큼의 여력이나 의지가 있지 아니하여 그냥 이정도 선에서 정리했습니다.

결론은 네이버 카페글 스크래핑 포기.

Monday, March 21, 2011

mechanize로 네이버 로그인하기

네이버 웹스크래핑을 하던 중, 네이버에 로그인할 일이 생겼습니다.
그런데 제대로 동작하지를 않더군요. 검색을 해보니, 동일한 문제를 겪고 있는 분이 있었습니다:
mechanize를 이용해서 네이버 로그인을 시도하

문제는 mechanize가 javascript를 지원하지 않기 때문에 발생한 겁니다.
즉, 로그인을 시도하면 다음과 같은 코드가 내려오는데:

<html>
<script language=javascript>
location.replace("http://www.naver.com");
</script>
</html>


해당 코드는 http://www.naver.com으로 이동시키는 명령입니다. 하지만 javascript를 지원하지 않는 mechanize는 이를 처리하지 못하기 때문에.. open() 을 사용해서 직접 열어줘야 합니다.

즉 아래와 같이 하면 됩니다(위 링크에서는 직접 데이터를 날렸는데, 저는 form field에 직접 값을 채운 뒤 submit하는 코드로 작성했습니다).:

browser = mechanize.Browser(factory=mechanize.RobustFactory())
browser.set_handle_robots(False)

browser.open('https://nid.naver.com/nidlogin.login?url=http://naver.com/이동할 페이지 주소')
browser.select_form(name="frmNIDLogin")
browser["id"] = '네이버 ID'
browser['pw'] = '패스워드'
browser.submit() # (A) 이제 로그인이 되었습니다.

browser.open(http://naver.com/이동할 페이지 주소') # (B)애초에 가고자 했던 페이지로 이동

이렇게 하더라도, 카페글을 읽으려면 여전히 험난한데요. 이에 대해서는 조금더 연구해보고 글을 올려보도록 하지요.