Post List

레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시

2017년 7월 24일 월요일

[Python 2.7] 파이썬에서 문자열 내에 특정 문자열 찾기! (find(), substring, re.finditer)

파이썬을 통해 웹사이트의 html문서를 받는 경우가 있다. 이때 문서 내에 특정 단어의 위치를 찾아야 한다면 간단한 함수를 이용할 수 있다. 예시로 'hello world!' 라는 문자열에서 'word'라는 특정 문자열을 찾으려 한다.

1. find() 함수

1
2
3
4
str1 = 'hello world!'
str2 = 'world'
= str1.find(str2)
print str1[a]
cs

find 함수를 통해 찾고자 하는 특정 문자열을 입력하면 반환 값으로 그 문자열의 시작위치가 나온다. 따라서 str1[a]의 값은 str2가 나오는 문자열의 시작위치로 'w'가 된다. 만약 찾고자 하는 문자열이 없다면 반환값으로 -1을 보낸다.

그러나 find 함수에는 단점이 있다. 찾고자 하는 특정 문자열이 여러 개인 경우에는 최초 발견 한 녀석의 시작위치만 알려준다. 즉, 그 뒤에 나오는 녀석들의 위치는 알 수가 없다.

2. substring

대체 방법으로는 substring을 이용하는 것이다. substring 이란 문자열의 일부를 잘라버리는 것인데 아래와 같은 방법으로 쓸 수 있다.

1
2
3
4
5
6
7
str1 = 'hello world!'
print str1[2:]
>>> 'llo world!'
print str1[3:5]
>>> 'lo'
print str1[:2]
>>> 'he' 
cs

str1[0:] 은 처음 문자부터 끝까지 모두 해당하는 문자열 (str1[:], str1 과 동등!!)
str1[2:] 은 3번째 문자부터 끝까지 의 의미이고
str1[3:5] 은 4번째부터 5번째까지 문자열이고
str1[:2] 은 처음부터 2번째까지 문자열이다.
(매트랩을 사용한 사람들에겐 친숙할 것이다.)

이를 통해 특정 문자열이 여러개 나오는 경우 나오는 시작위치를 모두 반환할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
str1 = 'hello world! world world'
str2 = 'world'
    
= str1.find(str2)
print a
while str1[a+1:].find(str2) != -1:
    a = str1[a+1:].find(str2) + a + 1
    print a
>>>
6
13
19
cs

위에서 str1[a+1:].find(str2)를 실행하면 a+1의 위치를 0으로 기준을 하여 다음 위치를 반환 하기 때문에 실제 위치는 a+1을 더해줘야 한다. while문을 통해 -1(문자열이 없을 때 반환 되는 값)이 나올 때까지 반복했다.


3. re.finditer() 함수

그러나 substring을 이용한 방법말고 더 깔끔한 방법이 있다. 바로 re 모듈을 사용해 finditer()함수를 이용하는 것이다.

1
2
3
4
5
6
7
8
9
str1 = 'hello world! world world'
str2 = 'world'
    
for a in re.finditer(str2,str1) :
    print a.start()
>>>
6
13
19
cs

위에 처럼 for문을 이용하여 re.finditer(특정 문자열, 원래 문자열)을 돌리면 순차적으로 a에 특정 문자열의 iterator 값이 들어가게 된다.
여기서 a.start()를 하면 특정문자열의 시작위치가 반환되고
a.end()를 하면 특정문자열의 끝위치가 반환된다.

각 방법마다 장단점들이 있으니 다양하게 사용해봐야겠다.

2017년 7월 23일 일요일

[Python 2.7] 파이썬으로 웹 크롤러 만들기 - (멜론 차트 뽑아오기)

이전 포스트에서 파이썬으로 특정 웹사이트의 html 문서를 받는 걸 구현해봤다. (참고 : 파이썬으로 url 접속하기)
이를 바탕으로 웹 크롤러를 만들어 보려한다.

크롤링이란 웹상에 올라온 데이터들 중 원하는 데이터들만 뽑아서 캐가는 기술이다. 해외에서는 crawling 보다는 scrapping이라는 단어를 많이 선택하는 것 같다. 예전에 머신러닝을 위한 데이터들을 모을 때 크롤링을 시도한 적이 있다. 원하는 데이터의 양이 막대하고 찾고자 하는 데이터가 규칙을 가진다면 크롤링은 매우 유용하다.

지금은 멜론 TOP 100 차트의 해당 곡 이름들을 뽑아와 저장하는 코드를 짜봅시다.( 멜론 TOP 100 링크 : http://www.melon.com/chart/index.htm )


1
2
3
4
5
6
7
8
import urllib2
url = "http://www.melon.com/chart/index.htm"
user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
request = urllib2.Request(url, None, {'User-Agent':user_agent})
data = urllib2.urlopen(request).read()
f=open("a.html","w")
f.write(str(data))
f.close()
cs


위의 코드는 멜론 TOP 100 링크로부터 html 문서를 받아오는 코드이다. 여기서 이전 글과 다른 건 user_agent라는 변수를 새로 쓰고 이를 HTTP header에 넣기 위해 urllib2.Request(url,None,{~~~}) 방식으로 값을 넣은 것이 있다.
http header에서 'User-Agent' 값은 client의 웹브라우저에 대한 정보를 담는 공간인데 아무것도 입력하지 않으면 파이썬에서 자동으로 'Python-urllib/2.7' 을 입력하여 http를 보낸다. 문제는 멜론에서 웹브라우저로 접속하지 않은 client들에게 html문서를 보내지 않는다는 것이다. 그래서 실제 크롬 웹브라우저가 가지는 'User-Agent' 값을 넣어 보낸 것이 위와 같다.

 자 이제 본격적으로 크롤링을 해봅시다. 크롤링을 하기 위해선 링크 부분의 html문 특징을 캐치해야한다.!! 위의 코드로 받아온 html 코드를 들여다 보자.


위에서 처럼 차트 순위에 있는 곡 이름 옆에는 <button type="button" class="btn_icon play" title=" 라는 문자열이 공통적으로 있다는 것을 알 수 있다. 그렇다면 data 변수에 저장된 문자열 중에 위 문자열의 위치를 찾고 '재생' 이라는 단어가 나오기 전까지의 문자열을 저장하면 된다.!!! 이 방법으로 코드를 짜보자.

1
2
3
4
5
6
7
8
9
import re
for iterate in re.finditer('<button type="button" class="btn_icon play" title="',data):
    a = iterate.end()
    b = ''
    i = 0
    while data[a+i] != '-':
        b = b+data[a+i]
        i += 1
 
cs

먼저 맨 윗줄에 re 모듈을 import 하자. 이 녀석이 문자열 내에 특정 문자열을 찾아주는 함수를 제공한다. 파이썬 내에 내장함수로 find() 함수가 있는데 이녀석은 특정 문자열이 여러개 있을 경우 최초 발견한 문자열만 찾아주므로 여기선 적합하지 않다.

for 문을 통해 iterate 변수 안에는 re.finditer() 함수의 반환값이 차례로 들어가게 된다. 발견된 특정 문자열의 시작 위치를 알고 싶으면 iterate.start() 로 알 수 있다. 하지만 여기선 특정 문자열의 마지막 위치를 알아야 하므로 iterate.end()를 사용했다.

이제 이를 활용하여 b 변수에 곡이름을 저장하도록 하자. while 문을 통해 a위치(iterate.end()의 반환값)부터 data 를 하나하나 확인하며 b에 저장한다. 그러다가 '-' 라는 문자가 나오면 저장을 끝낸다. 그렇게 되면 b에는 'Ko Ko Bop 재생 '이 저장된다.

우리가 원하는 목표는 b에 'Ko Ko Bop' 이 저장 되는 것이다. 그러므로 '재생'문자열이 나오는 시작위치를 찾아 내고 그 앞까지만 b에 저장하면 된다. 문제는 파이썬이 기본적으로 문자열을 unicode로 인코딩한다는 것이다. 그러므로 한글을 쓸 때 인코딩 문제로 매우 골치아픈 일이 생길 수 밖에 없다. 이를 해결하기 위해 다음과 같이 코드를 짰다.


1
2
3
str1 = unicode(' 재생','euc-kr').encode('utf-8')
= b.find(str1)
= b[0:c]
cs

str1 변수에 ' 재생'이라는 utf-8로 인코딩한 문자열을 저장한다. 이 문자열을 b에서 find() 함수를 통해 시작위치를 c에 저장하고 substring을 통해 b에 0번째 문자부터 c번째 문자까지 저장한다. 그렇게 되면 b에는 'Ko Ko Bop' 저장된다.

완성된 코드 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -*- coding: cp949 -*-
import urllib2
import re
url = "http://www.melon.com/chart/index.htm"
user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
request = urllib2.Request(url, None, {'User-Agent':user_agent})
data = urllib2.urlopen(request).read()
= open("chart.txt","w")
str1 = unicode(' 재생','euc-kr').encode('utf-8')
num = 1
for iterate in re.finditer('<button type="button" class="btn_icon play" title="',data):
    a = iterate.end()
    b = ''
    i = 0
    while data[a+i] != '-':
        b = b+data[a+i]
        i += 1
    f.write(str(num)+'.')
    f.write(b[0:b.find(str1)]+'\n')
    num += 1
f.close()
cs

파이썬코드가 저장된 폴더 내 chart.txt 파일에 멜론 차트가 번호순으로 저장된다.
짜자자자작~~!!!!

[Python 2.7] 파이썬으로 url 접속하기 (python2.7 버전)

c 언어를 이용해 웹 접근을 하려면 소켓 프로그래밍부터 공부해야한다. 소켓이란 프로그램이 네트워크를 통해 데이터를 주고받는 도구라고 볼 수 있다. 이 소켓을 이용해 HTTP 프로토콜을 구현하고 html 문서를 받는 코드까지 모두 짜려면 머리가 아플 것이다.

그래서 웹기반 모듈(c 언어에선 라이브러리와 같은 의미)이 잘 형성 되어 있는 파이썬을 이용하는 것이 효율적이다. 파이썬은 쉬운 언어에 속하므로 c언어나 다른 언어를 할 줄 알면 금방 습득할 수 있으니 웹 접근을 하고 싶으면 파이썬을 적극 추천한다.

먼저 https://www.python.org/downloads/ 이 링크를 타고 python-2.7.13을 받아봅시다.
받은 뒤 시작메뉴/python2.7/IDLE (Python GUI)을 실행시키자.


그 뒤에 File/New File 을 눌러 파이썬 코드를 작성하는 파일을 만든다.

한번 원하는 페이지의 html 파일을 받는 코드를 붙여 넣어 봅시다.
1
2
3
4
5
6
7
import urllib2
url = 'https://www.google.co.kr/'
request = urllib2.Request(url)
data = urllib2.urlopen(request).read()
print data
cs
위를 실행하면(키보드의 F5를 누르면 됩니다) GUI 창에서 코드가 실행되고 해당 html문이 짜르륵 출력된다.
아무리 봐도 코드가 정말 간단하다.

하나씩 봅시다.
1. urllib2란 url을 다루는 함수들을 모아둔 모듈이다. 이 모듈을 사용하려면 위와 같이 
import urllib2라고 작성하면된다.
2. url 변수에 원하는 사이트의 url 문자열을 입력 후
3. urllib2 모듈 내에 정의된 Request함수를 실행. 이때 반환 값을 request에 저장!
4. 여기서 urllib2의 urlopen 함수를 사용하면 해당 url에 접속하여 서버에서 제공하는 데이터를 받을 수 있다. 이 데이터를 읽으려면 read 함수가 필요함
6. data를 출력!!!


그러나 출력문이 매우길고 가독성이 힘들다...
따라서 파일로 저장 후 웹브라우저로 보는 것이 좋으므로 파일 저장 코드를 추가해보자.

1
2
3
= open("response.html","w")
f.write(str(data))
f.close()
cs

1. 파이썬에 내장된 open 함수를 통해 respone.html 파일을 write 모드로 연다.(파일이 없으면 자동 생성됨)
2. f에다 받아온 html문이 저장된 data를 write 함수를 통해 적는다.
3. 다 적었으면 write 모드를 끝낸다.


간단한 코드로 web에 접근 하는 방법을 봤다. 다음엔 이를 좀 더 활용해 크롤러를 만들어 봅시다!!

2017년 7월 10일 월요일

[Python 2.7] 파이썬으로 웹의 이미지 가져오기

import urllib2

url = 'url입력'
cookie = 'cookie입력'

request = urllib2.Request(url, None, {'Host': 'Host 주소 입력', 'Cookie': cookie})
data = urllib2.urlopen(request).read()

f = open("img.jpg","wb")
f.write(str(data))
f.close()

---------------------------------------------------------------

여기서 image 파일을 오픈할 때 "w"가 아닌 binary write 형식인 "wb"를 써야한다!!

[Python 2.7] 파이썬에 cv 추가하기

1. opencv 추가하기


지정한 경로\opencv\build\python\2.7\x86폴더에서 cv2.pyd파일을 복사해서 자신의 파이썬 설치경로\Lib\site-packages(보통 C:\Python27\Lib\site-packages)에 붙여 넣는다.
(64비트를 위한 x64폴더가 있지만 Numpy가 32비트라서 문제가 된다. 그러므로 x86을 쓴다)

2. Numpy 설치하기


Numpy 선택 후 아래 파일 다운로드!
numpy-1.10.2-win32-superpack-python2.7.exe

출처: http://speark.tistory.com/9 [많이해라]


소스코드 실행 :


import cv2
import numpy as np

image = cv2.imread("a.png", cv2.IMREAD_COLOR)
cv2.imshow("image",image)
cv2.waitKey(0)

cv2.destroyAllWindows()