파이썬 웹 스크래핑, 크롤링


  • 본문의 내용은 Data Science from scratch(밑바닥부터 시작하는 데이터 과학)을 읽고 작성했습니다.
  • 본문의 소스코드의 일부는 Joel Grus의 Github에서 Unlicensed 라이선스로 배포되고 있습니다.

웹 문서의 구조

<html>
 <head>
   <title>Awesome Webapge</title>
   <!--Do-something-really-important-->
 </head>
 <body>
   <p id="author">nyanye</p>
   <p id="tag">Data Science</p>
 </body>
</html>

HTML의 내용은 요소와 속성으로 이루어져 있다. (모든 웹문서가 이를 잘 지킨다는 것은 아니다.)
- <p id="tag">에서 <p>는 요소이고 id="tag"부분이 속성이다. 만약 위와 같은 웹문서에서 id 항목이 tag인 부분의 텍스트를 찾는다면 원하는 데이터를 얻을 수 있다.

이를 위해 HTML요소를 편리한 구조로 저장해 접근을 용이하게 해주는 Beautifulsoup 라이브러리를 사용할 수 있다.(scrapy 등의 라이브러리도 사용할 수 있다.)

html 요청을 위한 request라이브러리와 파싱을 위한 html5lib을 사용하자.

pip install html5lib
pip install requests
pip install bs4
from bs4 import BeautifulSoup as bs
import requests, html5lib

html = requests.get("http://nyanye.com").text
soup = bs(html, 'html5lib')

postTitle = soup.findAll('h3', class_="post-title")[0].getText()
postSummary = soup.findAll('p', class_="post-summary")[0].getText()
print(postTitle.strip())
print(postSummary.strip())

>>iPython 사용 
>>iPython tips

# 이런 식으로 페이지의 내용을 파싱하면 된다.
def collectPost():
    postTitles = soup.findAll('h3',  class_="post-title")
    postSummaries = soup.findAll('p', class_="post-sumamry")
    for i in range(len(postTitles)):
        postTitle = soup.findAll('h3', class_="post-title")[i].getText()
        postSummary = soup.findAll('p', class_="post-summary")[i].getText()
        with open("blogdata.txt",'a') as f:
            f.write(postTitle.strip())
            f.write('\n')
            f.write(postSummary.strip())
            f.write('\n')

collectPost()

blogdata.txt>>

iPython 사용 
iPython tips
변수 & 함수 이름짓기
다양한 코딩스타일  취향에 맞는 녀석을 사용하자.
Python Probability
일정한 조건 아래에서 어떤 사건이나 사상이 일어날 가능성의 정도. 또는 그런 수치. 수학적으로는 1 넘을  없고 음이  수도 없다. 확률 1 항상 일어남을 의미하고, 확률 0 절대로 일어나지 않음을 의미한다.
Python Hypothesis
통계와 확률 이론을 통해 가설을 검정하고 통계적 추론을   있다. 가설(hypothesis)이란 '데이터 과학자는 MATLAB보다 R이나 Python을 선호한다.' 등과 같은 주장이며, 데이터 통계에 대한 얘기가  수도 있다.

한계와 해결책

하지만 requests 모듈의 웹 문서 접근은 조금 기계적이다. one page web application, javascript 프레임워크를 응용한 client-side rendering으로 페이지를 제공한다면 requests모듈이나 커맨드라인 명령어 wget, curl 등은 필요한 데이터를 추출해내지 못할 것이다. 그럴 때는 scrapy라는 라이브러리를 활용해보도록 하자.