잡다한 프로젝트

인터넷 프로그래밍 크롤링 과제 2편 (php에서 잘 안된 내용이 무엇인지 해결 정리.)

studying develop 2019. 12. 20. 17:40

음 내가 원했던 것은 https://www.google.com/search?q=기묘한+이야기 이런 식으로 q="원하는 제목"을 추가해서 크롤링하려고 했다.

 

그래서 "https://www.google.com/search?q=기묘한+이야기" 이걸 내가 복사해서 php 에서 file_get_html()의 인자로 넣으면 잘 작동했다. 마찬가지로 주소를 html 파일에서 post로 php로 넘겨서 받은 값을 (위와 동일 한) file_get_html()의 인자로 넣으면 잘 작동했다.

 

단 !... html 파일에서 "기묘한 이야기" 이렇게 받고 이 공백을 + 로 바꾸어서 "https://www.google.com/search?=" 이 부분에 concat 시키면 안된다.... 그래서 내가 원인을 몇가지 생각해 보았었다.

 

내가 세웠던 원인

 

1. file_get_html()이 작동을 잘 안한다.

 

2. $_POST의 인코딩 값이 file_get_html에 넣어야 하는 인코딩 값과 다르다... 즉 인코딩 값을 utf-8(맞는 걸로) 바꿔서 보내줘야 한다....

 

3. Concat 시킨 값과 "https://www.google.com/search?q=기묘한+이야기" 통짜로 입력한 값이 다르다.

 

 

 

내가 조사한 내용

 

1. file_get_html()에 대해서 내부 구조를 알 수 있으면 좋은데 그게 아니라서 에러가 있으면 php.net에 보내서 물어보는 방식이었다. 그래서 아무리 찾아봐도 안나옴. 알게된 내용은 파라미터로 file 경로를 입력해줘야 한다는 점 인데 그게 url이랑 똑같다고 봐도 되는거겠지?...

 

2. 이 부분이 문제라고 생각했다. 왜냐면 한글 입력이 보통 인코딩이 다 다르게 되있어서..? 근데 내가 인코딩에 대해서 진짜 아무리 봐도 잘 모르겠어서 이 고민을 하느라 12시간 정도 걸린거 같다. 참고한 사이트와 내가 이해한 내용을 적어 보겠다. 

https://seowoosung.github.io/CharacterSet/

 

Character set과 Character encoding 정리

기본개념 character encoding: 문자나 기호들의 집합을 컴퓨터에서 표현하는 방법.(UTF8, UTF16) character set: 정보를 표현하기 위한 글자들의 집합을 정의한 것. 한 문자 집합을 여러 문자 인코딩에서도 사용가능(ex: 유니코드)

seowoosung.github.io

그러니까 내가 이해하기로는 인코딩은 두개를 일단 알아야 한다. character encoding과 character set. 여기서 캐릭터 인코딩은 문자나 기호들의 집합을 컴퓨터에서 표현하는 방법이다 (UTF-8). 음 내가 이해 하는 이 말은 우리가 보는 아는 글자 (키)에 대해 고유값( 발류)를 나타내는 방법이 많을 텐데 이것을 표현하는 방법이 character set이라고 생각할 수 있는것 같다. 즉 120이라는 발류가 있으면 이걸 몇 바이트로 표현할 수 있는지는 방법이 다양한데 EUC-KR은 127이하의 ASCII 영역은 1byte로 표현한다고 한다. 즉 컴퓨터에서는 같은 값을 몇바이트로 표현하는 가도 정해야 하므로 그것이 character encoding이라 할 수 있다.

 

character set은 정보를 표현하기 위한 글자들의 집합을 정의한것. 한 문자 집합을 여러 문자 인코딩에서도 사용 가능(유니 코드).  내가 이해 하기로 문자나 기호가 (각각 고유 value)가 있으면 그걸 key(우리가 아는 글자)와 매핑하는 방법인 것이다. 즉 유니코드는 전 세계 모든 문자를 다루도록 설계된 표준 문자 전산 처리 방식으로 키와 값(발류)이 1:1로 매칭된 형태의 코드인 것이다.

 

즉 인코딩은 진짜 키에 대한 고유 값의 매핑. 이건 EUC-KR , MSWIN949, UTF-8, UCS-2  UTF-16 등이 있는데. 우리가 많이 아는 ASCII는 EUC-KR, UTF-8은 ASCII 영역 즉 127이하는 동일하게 1byte로 표현한다!! 즉 내가 보기에 인코딩은 값을 몇 바이트로 표현할 것이냐 문제인데. 인터넷 프로그래밍에서는 utf-8로 주로 표현한다. 음 보니까 리눅스랑 맥은 utf-8로 인코딩 된다는데 그럼 문자열도 모두 utf-8로 인코딩 되어 있어야 정상적으로 출력해서 보여 줄 것 같다.? 언어마다 다른건가? 

 

Q ) 음 저장된 값을 printf등으로 c언어가 보여주는건 어떤 인코딩 방식인줄 알고 보여주는 거지?

 

 

3. 이건 hex2bin , bin2hex를 통해서 알게 되었다. 두 문자열의 결과 값이 달랐다.

즉 두 주소를 bin2hex 하면 

이렇게 둘이 앞에 영어 부분만 같고 한글 부분은 달랐다. 그래서 내가 생각하기에 서로 다른 값을 같고 있으니까 두 문자열이 인코딩이 다르다 생각 해서 출력해 보니

 

 

하나는 ASCII 두번째는 UTF-8로 다르게 나왔다. 그래서 ASCII를 UTF-8로 바꾸려고 막 해봤는데 iconv를 사용하니까 utf-8에서 ascii는 바뀌는데 역으로는 안되던데 도대체 왜 그런지 모르겠다. 근데 위에 글 보니까 ASCII는 그냥 character set 방식이고 UTF-8은 encoding 방식이라 몇바이트로 표현하느냐의 문제 아닌가 근데 utf-8도 127이하 값은 한바이트로 표현하는데 바꾸는게 말이 안되는듯...? 그래서 안됬나 뭐가 뭔지 잘 이해가 안된다. 

 

어쨋거나 최종 해결 방법은 url을 넘길때는 urlencoding을 해서 넘겨야 한다. 이 부분은 여기를 참조 했다. 어떻게 알게 됬냐면 주소창에 url을 복붙해 보면 자꾸 %랑 영어 알파벳으로 바뀌어 나타났다.

 

https://www.google.com/search?q=%26%2344592%3B%26%2347896%3B%26%2354620%3B%2B%26%2351060%3B%26%2350556%3B%26%2344592%3B

이런 식으로 그래서 나도 저렇게 해야 하나 싶었다.

 

http://blog.naver.com/PostView.nhn?blogId=awesomedad&logNo=220748168859

 

url encode (url 인코딩) 왜 필요한가.

URL 인코딩은, URL 스트링에 있는 텍스트를, 모든브라우저에서 똑바로 전송하기 위해 존재한다. 인터...

blog.naver.com

그래서 읽어보니 영어 부분은 굳이 url인코딩 할 필요없고 한글쪽은 필수적이라 한글쪽만 해서 concat하니 됬따....