따라하는 python 로또 분석 (1)
이 글은 python 초보자들을 대상으로 하는 로또 데이터 분석에 관련된 글입니다.
개인적으로는 c++이 제일 편하지만 python에는 라이브러리가 많아 프로그래밍 초보들도 쉽게 만들 수 있다는 장점이 있습니다.
c++로 구현하려면...어휴;;
자. 그럼 시작해 볼까요?
준비물: python 3.x
python 모듈 : requests
1. 로또 당첨 기록 가져오기
먼저 지난 당첨 기록들을 가져와야 합니다.
로또 당첨 기록들은 로또 공식 홈페이지(http://nlotto.co.kr/)에서 가져오도록 하겠습니다.
로또 공식 홈페이지에 접속해서 각 회차별 데이터를 가져오는 크롤러를 만들어야 합니다.
requests 라는 모듈을 쓰면 쉽게 인터넷에 있는 데이터를 가져올 수 있습니다.
아래는 코드입니다.
# lotto.py
import requests
def main():
main_url = "https://www.nlotto.co.kr/"
response = requests.get(main_url)
print(response)
if __name__ == "__main__":
main()
requests 모듈을 이용해 2줄로 데이터를 가져왔습니다.
참, python3는 기본 인코딩이 utf-8이기 때문에 별도의 utf-8 설정을 할 필요가 없습니다.
위의 코드를 실행하면 아래와 같이 200 response code가 출력됩니다.
http status code 200은 서버가 정상적으로 요청을 처리했음을 뜻하는 값입니다.
가져온 HTML 코드를 보려면 response.text를 출력하면 됩니다.
아래와 같이 코드를 수정해 봅시다.
# lotto.py
import requests
def main():
main_url = "https://www.nlotto.co.kr/"
response = requests.get(main_url)
print(response.text)
if __name__ == "__main__":
main()
위 코드를 실행한 결과는 아래와 같습니다.
이제 웹 사이트에서 HTML을 가져오는 것까지 되었으니 진짜로 지난 당첨기록들을 가져올 차례입니다.
어디가 좋을까 웹 사이트를 둘러보다가 아래와 같은 곳을 발견했습니다.
위 그림의 빨간 박스에서 보이듯이 지난 회차를 하나씩 조회해 볼 수 있는 버튼이 있습니다.
회차를 선택하고 버튼을 누르면 아래와 같이 회차만 변경되는 URL을 확인할 수 있습니다. 숫자만 변경하면 되겠죠?
http://nlotto.co.kr/lotto645Confirm.do?method=byWin&drwNo=707
위 URL에서 HTML을 긁어오는 코드로 변경해 보겠습니다.
# lotto.py
import requests
def main():
basic_url = "https://www.nlotto.co.kr/lotto645Confirm.do?method=byWin&drwNo="
for i in range(1, 707):
resp = requests.get(basic_url + str(i))
print(basic_url + str(i))
print(resp)
if __name__ == "__main__":
main()
1부터 707(현 시점에서 가장 최근 회차)까지 for루프를 돌면서 requests를 보내는 코드입니다.
이 코드를 실행하면 아래와 같이 출력됩니다.
2. HTML 파싱하기
이번에는 HTML을 파싱해서 필요한 데이터를 추출해 볼 차례입니다.
python 모듈 : BeautifulSoup4, lxml
BeautifulSoup4 - 가져온 HTML을 파싱하기 쉽도록 도와주는 라이브러리
lxml - BeautifulSoup에서 파싱할 때 xml 구조를 이용하도록 하기 위해 필요한 라이브러리.
pip3를 이용하여 위의 모듈들을 설치합니다.
먼저 HTML 코드를 파싱하도록 코드를 수정해 볼까요?
수정된 코드는 아래와 같습니다.
# lotto.py
import requests
from bs4 import BeautifulSoup
def main():
basic_url = "https://www.nlotto.co.kr/lotto645Confirm.do?method=byWin&drwNo="
for i in range(1, 707):
resp = requests.get(basic_url + str(i))
soup = BeautifulSoup(resp.text, "lxml")
if __name__ == "__main__":
main()
이전 코드에서 한 줄만 추가하면 됩니다. 참 쉽죠?
xml 형태로 파싱된 response가 soup 변수에 저장됩니다.
지금부터는 soup 변수를 이용해 찾고자 하는 데이터를 쉽게 찾을 수 있습니다.
soup를 이용해서 HTML 소스에서 회차, 당첨 번호, 당첨 금액들을 추출해보도록 하겠습니다.
웹 브라우저의 소스보기를 이용해서 우리가 추출하고자 하는 데이터가 HTML의 소스 내 어디에 위치하는지, 어떻게 추출할 수 있는지 찾아봐야 합니다.
소스를 살펴보다 보니 아래 화면과 같은 곳이 눈에 뜨입니다.
id가 desc, name이 description인 <meta> 태그를 찾아서 content의 내용을 추출하면 될 것 같습니다.
BeautifulSoup를 이용해 해당 라인을 찾는 코드를 추가해 봅니다.
수정된 코드는 아래와 같습니다.
# lotto.py
import requests
from bs4 import BeautifulSoup
def main():
basic_url = "https://www.nlotto.co.kr/lotto645Confirm.do?method=byWin&drwNo="
for i in range(1, 707):
resp = requests.get(basic_url + str(i))
soup = BeautifulSoup(resp.text, "lxml")
line = str(soup.find("meta", {"id" : "desc", "name" : "description"})['content'])
print(line)
break
if __name__ == "__main__":
main()
위의 코드를 실행하면 아래와 같이 우리가 필요로 하는 데이터를 제대로 추출함을 볼 수 있습니다.
위의 라인을 적절히 파싱하면 당첨회차, 당첨 번호, 당첨 인원, 당첨금액으로 분리할 수 있습니다.
아래 코드를 보시죠.
# lotto.py
import requests
from bs4 import BeautifulSoup
def main():
basic_url = "https://www.nlotto.co.kr/lotto645Confirm.do?method=byWin&drwNo="
for i in range(1, 707):
resp = requests.get(basic_url + str(i))
soup = BeautifulSoup(resp.text, "lxml")
line = str(soup.find("meta", {"id" : "desc", "name" : "description"})['content'])
print("당첨회차: " + str(i))
begin = line.find("당첨번호")
begin = line.find(" ", begin) + 1
end = line.find(".", begin)
numbers = line[begin:end]
print("당첨번호: " + numbers)
begin = line.find("총")
begin = line.find(" ", begin) + 1
end = line.find("명", begin)
persons = line[begin:end]
print("당첨인원: " + persons)
begin = line.find("당첨금액")
begin = line.find(" ", begin) + 1
end = line.find("원", begin)
amount = line[begin:end]
print("당첨금액: " + amount)
break
if __name__ == "__main__":
main()
위의 코드를 실행하면 아래의 결과를 얻을 수 있습니다.
제대로 추출했죠?
이번 포스팅은 여기까지 입니다.
다음 포스팅에서는 받아온 이렇게 추출한 데이터를 mysql에 저장해보도록 하겠습니다.
읽어주셔서 감사합니다.