뷰티펄 숲

From Hidden Wiki
Jump to navigation Jump to search
필독 사항 유닠스 계열 저작물, 성인물, 도박 웹 써버 보안 프로그래밍 그래핔 파싱
필독 사항 고스트BSD 표면 웹 싸이트 제작 리눅스 마스터 파이썬 트킨터 뷰티펄 숲
수학 아이투피 마약, 아청물, 해킹 웹 싸이트 보안 웹 프로그래밍 데이터 분석 게임 제작
통계학 뮤와이어 다크넽 싸이트 제작 정보 보안 기사 쟁고우 팬더즈 파이게임

데이터 수집

beautiful의 발음은 [bjúːtəfəl], [|bjuːtɪfl], /ˈbjut̬ɪfəɫ/, byo͞oʹtĭ-fəl, [ˈbjuːtɪfəɫ]이다. 미국식 발음은 뷰러펄, 영국식 발음은 뷰티펄 정도 된다. soup의 발음 [suːp]을 한글로 표기하면 이나 장음이므로 수웊 정도이다. 따라서 Beautiful Soup의 한글 표기는 뷰티펄 숲 정도로 하면 된다.


Beautiful SoupHTMLXML 문서의 파싱 (parsing)을 위한 파이썬 패키지이다.

BeautifulSoup으로 미세 먼지 정보 수집

텍스트 형식으로 된 HTML 파일을 파싱 (parsing)하여 http://aqicn.org/city/seongnam/kr/ 에서 미세 먼지 정보만 읽어올 것이다.


리눅스 민트라면 일단

sudo pip3 install beautifulsoup4

로 BeautifulSoup4를 설치한다.


BeautifulSoup는 파이썬의 표준 라이브러리에 포함된 HTML 파서(parser)를 지원하지만 또한 많은 써드 파티(third-party) 파이썬 파서도 지원한다. 그 중 하나가 lxml 파서다.

다른 대안품은 순수 파이썬 html5lib 파서다. 이 파서는 HTML을 웹 브라우저와 동일한 방식으로 파싱한다.


"html.parser"는 Python의 HTML parser이고, "lxml"은 lxml의 HTML 파서이며, "lxml-xml" 또는 "xml"은 lxml의 XML 파서이다. "html5lib"는 html5lib 파서이다.

lxml의 HTML 파서는 Python의 html.parser보다 빠르고, lxml의 XML 파서는 유일한 XML 파서이다. html5lib 파서는 웹 브라우저와 동일한 방식으로 파싱할 수 있는 대신 느리다.


xml 파서는

apt-get install python-lxml
easy_install lxml
pip install lxml

컴퓨터에 따라 다르지만 위 셋의 명령어 중 하나로 설치할 수 있다.

sudo pip3 install lxml

데비안 계열이라면 앞에 sudo를 붙여 관리자 권한을 줘야 설치된다. 그리고 파이썬 2와 3가 같이 설치돼있는 경우 pip가 아니라 pip3로 설치해야 한다. 윈도우즈라면 "실행"에서 cmd 치고 pip install lxml를 입력해주면 된다.


html5lib 파서도

apt-get install python-html5lib
easy_install html5lib
pip install html5lib

역시 위 셋 중 하나의 명령어로 설치 가능하다.

sudo pip3 install html5lib

리눅스 민트라면 위의 명령어로 설치하면 된다.


Beautiful Soup 4.4.0 documentation (Installing a parser) https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser


from urllib.request import urlopen
from bs4 import BeautifulSoup
if __name__ == "__main__":

 # 크롤링을 하려는 URL
    targetUrl = "http://aqicn.org/city/seongnam/kr/"
 # 성남시의 대기 오염 정보를 웹페이지에서 읽어온다.
    html = urlopen(targetUrl).read()

 # BeautifulSoup 으로 파싱.
    soupData = BeautifulSoup(html, 'html.parser')

 # a 태그의 aqiwgttitle1에서 지역 정보를 읽어 오고
    titleData = soupData.find('a', id='aqiwgttitle1')
    print(titleData.string)

 # span 태그의 aqiwgtutime에서 미세먼지 수집 시간도 읽고
    timeData = soupData.find('span', id='aqiwgtutime')
    print(timeData.string)

 # 마지막으로 div 태그의 aqiwgtvalue에서 미세먼지 수치를 읽는다.
    aqiData = soupData.find('div', id='aqiwgtvalue')
    print(aqiData.string)
    print(aqiData.get('title'))


코드를 실행하면 아래와 같이 뜬다.

성남 AQI
금요일 15시에 업데이트
보통
61

설명을 하자면 크롬 웹 브라우저http://aqicn.org/city/seongnam/kr/ 에 방문한 후 F12 키를 눌러 웹 페이지인 HTML 파일의 소스를 본다. 그리고 Ctrl키와 f 키를 동시에 눌러 aqiwgttitle1을 검색해본다.


<a href="//aqicn.org/city/seongnam/kr/" title="성남 (성남시)" class="aqihreftarget" id="aqiwgttitle1"><b>성남</b> AQI</a>

에서 시작 부분과 끝 부분에 a 태그(tag)가 보일 것이고, id="aqiwgttitle1"도 보일 것이다. 또한 그 속에 성남 AQI가 적힌 것이 보일 것이다.


<span id="aqiwgtutime" val="1523595600">Updated on Friday 15:00</span>

span 태그와 id="aqiwgtutime"이 보이고 그 속에 Updated on Friday 15:00가 보일 것이다.


<div class="aqivalue" id="aqiwgtvalue" style="font-size: 80px; background-color: rgb(255, 222, 51); color: rgb(0, 0, 0); text-shadow: rgb(255, 255, 255) 1px 0px 1px;" title="보통">61</div>

div 태그와 id="aqiwgtvalue"가 보이고 그 속에 61이 보일 것이다. 끝에 .string을 붙임으로써 위 div 태그가 통째로 출력되는 게 아니라 그 속의 내용물인 61만 출력된다. 또한 title="보통"도 보일 것이다. get 함수로 title에 해당하는 '보통'을 출력한다.


BeautifulSoup 을 이용한 크롤링 https://medium.com/@jongseonkim/beautifulsoup-%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%ED%81%AC%EB%A1%A4%EB%A7%81-468fcf3b544f


if __name__ == "__main__":

의 의미는 파이썬 문서를 참조하기 바란다.


BeautifulSoup으로 기온 정보 수집

Beautiful Soup 라이브러리로 기온데이터 수집하기 http://www.analyticsstory.com/71


https://www.wunderground.com/history/airport/RKSS/2017/3/20/DailyHistory.html?req_city=NA&req_state=NA&req_statename=NA

링크의 대기 온도 데이터를 수집할 것이다. 중간에 /2017/3/20/ 이 보일 것이다. 이것을 바꾸면 그 날짜의 기상 데이터가 뜬다.

2017년 3월 데이터만 수집

import urllib.request
from bs4 import BeautifulSoup
 
# 온도 데이터를 저장할 파일을 쓰기 모드로 연다.
f = open('2017년 3월 서울 김포 공항의 평균, 최고, 최저 기온.txt', 'w')
 
for d in range(1, 32):
    if (len(str(d)) == 1):
        timestamp = '2017030' + str(d)
    else:
        timestamp = '201703' + str(d)
        # 뽑아내려는 기온 데이터가 들어있는 페이지를 urllib 라이브러리로 불러온다.

    url = "https://www.wunderground.com/history/airport/RKSS/2017/3/" \
            + str(d) + \
            "/DailyHistory.html?req_city=NA&req_state=NA&req_statename=NA"
    page = urllib.request.urlopen(url)
         
    # Beautiful Soup 라이브러리로 기온 데이터를 추출한다.
 
    soup = BeautifulSoup(page, "lxml")        # "lxml"은 lxml의 HTML parser를 쓰라는 의미이다.
    dayMeanTemp = soup.find_all('span', class_ = 'wx-value')[0].string
    dayMaxTemp = soup.find_all('span', class_ = 'wx-value')[1].string
    dayMinTemp = soup.find_all('span', class_ = 'wx-value')[4].string
 
    print('date: {0},{1},{2},{3}'.format(timestamp, dayMeanTemp, dayMaxTemp, dayMinTemp))
            
    if len(str(d)) < 2:
        dStamp = '0' + str(d)
    else:
        dStamp = str(d)
         
    timestamp = '201703' + dStamp
         
    #읽어온 기온 데이터를 파일에 쓴다. \n은 다음 줄로 바꾸라는 의미이다.
    f.write(timestamp + ',' + dayMeanTemp + ',' + dayMaxTemp + ',' + dayMinTemp + '\n')
 
# 모든 데이터를 읽었으면, 기온 데이터를 저장한 파일을 닫는다.
f.close()


len()은 리스트에 들어있는 원소의 갯수가 몇 개인지 보여주는 함수이다. str()은 문자열(string)로 변환하는 함수이다. if와 else로 일(day)의 자릿수가 1자리일 때와 2자리 일 때로 나눠 201703 뒤에 0을 붙일거나 안 붙이게 나눠놨다.


기온 데이터는 wx-value 클래스에 span 태그로 둘러싸여 있다. 0번째, 1번째, 4번째 데이터를 가져온다.

.string을 붙이지 않으면 <span class="wx-value">-7</span>,<span class="wx-value">-2</span>,<span class="wx-value">-12</span>와 같이 span 태그가 전부 뜬다.

.string을 붙이면 date: 20171217,-8,-3,-13처럼 태그 속의 데이터만 뜬다.


2017년 데이터를 모두 수집

import urllib.request
from bs4 import BeautifulSoup
 
# 온도 데이터를 저장할 파일을 쓰기 모드로 연다.
f = open('서울 김포 공항의 2017년도 평균, 최고, 최저 기온.txt', 'w')
 
# 1월에서 12월까지 각 날짜의 페이지를 순회하면서 기온 정보를 뽑아낸다.
for m in range(1, 13):
    for d in range(1, 32):
        if (m == 2 and d > 28):   #2월이 28일을 넘으면 중단하고 다음 달로 넘어간다.
            break
        elif (m in [4, 6, 9, 11] and d > 30):  #4, 6, 9, 11월이 30일을 넘으면 중단하고 다음 달로 넘어간다.
            break
 
        if (len(str(m)) == 1) and (len(str(d)) == 1):
            timestamp = '20170' + str(m) + '0' + str(d)
        elif (len(str(m)) == 1) and (len(str(d)) == 2):
            timestamp = '20170' + str(m) + str(d)
        elif (len(str(m)) == 2) and (len(str(d)) == 1):
            timestamp = '2017' + str(m) + '0' + str(d)
        else:
            timestamp = '2017' + str(m) + str(d)
             
        # 뽑아내려는 기온 데이터가 들어있는 페이지를 urllib 라이브러리로 불러온다.
 
        url = "https://www.wunderground.com/history/airport/RKSS/2017/" \
                + str(m) + "/" + str(d) + \
                "/DailyHistory.html?req_city=NA&req_state=NA&req_statename=NA"
        page = urllib.request.urlopen(url)
         
    # Beautiful Soup 라이브러리로 기온 데이터를 추출한다.

       # lxml's HTML parser를 쓰라는 의미이다.

        soup = BeautifulSoup(page, "lxml")
        dayMeanTemp = soup.find_all('span', class_ = 'wx-value')[0].string
        dayMaxTemp = soup.find_all('span', class_ = 'wx-value')[1].string
        dayMinTemp = soup.find_all('span', class_ = 'wx-value')[4].string
 
        print('date: {0},{1},{2},{3}'.format(timestamp, dayMeanTemp, dayMaxTemp, dayMinTemp))
 
        if len(str(m)) < 2:
            mStamp = '0' + str(m)
        else:
            mStamp = str(m)
             
        if len(str(d)) < 2:
            dStamp = '0' + str(d)
        else:
            dStamp = str(d)
         
        timestamp = '2017' + mStamp + dStamp
         
    #읽어온 기온 데이터를 파일에 쓴다. \n은 다음 줄로 바꾸라는 의미이다.
        f.write(timestamp + ',' + dayMeanTemp + ',' + dayMaxTemp + ',' + dayMinTemp + '\n')
 
# 모든 데이터를 읽었으면, 기온 데이터를 저장한 파일을 닫는다.
f.close()