본문 바로가기
개발 이야기/Python

Python으로 웹 크롤링(Crawling )

by 농개 2019. 7. 19.

요즘 업무를 자동화 하는것에 꽂혀있어서 그런지.. 웹 크롤링(Web Crawling)에 관심이 생겼습니다.

웹 크롤링(Crawling)이란 다른말로 웹 스크랩핑(Scraping)이라고도 합니다.

말그대로 웹사이트를 스크랩(?)하는 작업으로.. 특정 웹사이트에서 특정정보를 잘라와 모으는 것입니다. 어릴적에 숙제로 신문 스크랩하던게 떠오르네요.

 

크롤링이라고 검색해보면 많은 예제들이 있습니다. 다루는데 있어서 편리한 언어인 Python으로 웹크롤링을 한번 해보도록하겠습니다. 네이버 검색어 Top10을 가져와 보는 예제입니다.

 

사용할 라이브러리는 아래와 같습니다.

- requests : http요청을 간편하게 다룰수 있게 도와주는 라이브러리입니다.
- BeautifulSoup : 웹문서를 쉽게 파싱하고 원하는 정보를 추출할 수 있게 도와줍니다.

 

 

 

01. 라이브러리 설치

먼저 아래와 같은 명령어로 위 라이브러리를 설치해봅시다.

pip install requests
pip install beautifulsoup4

pip list ## 확인

 

 

02. 요청 보내기

아래와 같이 requests모듈을 이용해서 GET요청을 보내는 코드를 작성했습니다.

# Python 3.7.2
# 네이버 top 10 크롤링
# file name : naver-search-top10.py

from bs4 import BeautifulSoup
import requests

def main():
    response = requests.get("https://naver.com")
    print(response.status_code)
    print(response.content)


if __name__ == '__main__':
    main()

 

한번 실행 시켜 보면 아래와 같은 결과가 나옵니다.

PS C:\mynode\auto-script\crawling> python naver-search-top10.py
200
b'<!doctype html>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<html lang="ko">\n<head>\n<meta charset="utf-8">\n<meta name="Referrer" content="origin">\n<meta http-equiv="Content-Script-Type" content="text/javascript">\n<meta http-equiv="Content-Style-Type" content="text/css">\n<meta http-equiv="X-UA-Compatible" content="IE=edge">\n<met
...(생략)

status code 200(OK)로 정상적으로 요청에 대한 응답이 왔고, content에 html 문서가 담겨왔음을 확인 할 수 있습니다.

 

 

 

03. BeautifulSoup 사용법

간단히 beautifulsoup의 사용법을 소개하면 아래와 같습니다.

soup = BeautifulSoup(html, "html-parser")		# html문서를 html-parser로 파싱

a_tags = soup.find_all('a', limit=2) # 문서에서 a태그 모두 가져옴. limit은 2개만 가져온다는 의미

a_tags_class = soup.find_all("a", class_="strange") # class가 strange a태그

a_tags_id = soup.find_all("a", id="strange") # id가 strange a태그

a_tags_string = soup.find_all("a", string=["guess"]) # 태그 하위의 string 문자열로 가져온다.

a_tags_multi = soup.find("a", {
  "class":"strange",
  "data":"kkk"
}) ## 다중조건

 

find_all 또는 find를 사용하면 html문서에서 태그를 중심으로 파싱하여 데이터를 가져올 수 있습니다.

하지만 자신이 html, css에 대해서 지식이 있다면 아래와 같은 select, select_one을 통해 가져오는것을 추천드립니다.(뭐 개인취향 일 수 있습니다만...)

a_id = soup.select_one('a#abc') # id
a_class = soup.select('a.ccc') # class
a_class_one = soup.select_one('a.ccc > p:nth-of-type(2)') # class 내부의 p tag 2번쨰
a_custom_prop = soup.select_one("a[data='aa']") # 속성

위처럼 css선택자로 보다 정확히 원하는 데이터를 찾을 수 있을 것입니다.

 

 

 

04. 네이버에서 문서구조 파악

https://naver.com 창을 띄워서 F12(개발자도구) 누른뒤 element 선택기를 눌러봅시다.

 

그리고 top10검색어 부분을 눌러 html 구조를 보면...

 

 

확인해보면 클래스명이 ah_l인 ul에 담겨있는 것을 확인 할 수 있습니다.

좀더 자세히 확인해보면...

ul[class=ah_l] 의 li[class=ah_item] 의 a태그의 span[class=ah_k]가 검색어들이 표시되는듯합니다.

 

 

 

05. 검색어 text 스크랩

# Python 3.7.2
# BeautifulSoup

from bs4 import BeautifulSoup
import requests

def main():
    response = requests.get("https://naver.com")
    # print(response.status_code)
    # print(response.content)

    soup = BeautifulSoup(response.content, "html.parser")

    search_top = soup.select('ul.ah_l > li.ah_item > a > span.ah_k')
    for i, ins in enumerate(search_top):
        num = i + 1
        search_word = ins.text
        print("{}번째 : {}".format(num, search_word))



if __name__ == "__main__":
    main()

위처럼 select로 css선택자를 

ul.ah_l > li.ah_item > a > span.ah_k

로 주고 해당 ResultSet을 가져옵니다.

그리고 출력을 해보면...

 

PS C:\mynode\auto-script\crawling> python .\naver-search-top10.py
1번째 : 강민희
2번째 : 의사요한
3번째 : 손동표 나이
4번째 : 프로듀스 x 101 강민희
5번째 : 이한결
6번째 : 엑스원
7번째 : 차준호
8번째 : 바우젠 전해수기
9번째 : 멜로망스
10번째 : 남도현
11번째 : 프듀 순위
12번째 : 황하나
13번째 : 노주현카페
14번째 : 송형준
15번째 : 추적60분
16번째 : 아메리칸 메이드
17번째 : 태풍 다나스 경로
18번째 : 조승연
19번째 : 심리상담사
20번째 : 송유빈
21번째 : 강민희
22번째 : 의사요한
23번째 : 손동표 나이
24번째 : 프로듀스 x 101 강민희
25번째 : 이한결
26번째 : 엑스원
27번째 : 차준호
28번째 : 바우젠 전해수기
29번째 : 멜로망스
30번째 : 남도현
31번째 : 프듀 순위
32번째 : 황하나
33번째 : 노주현카페
34번째 : 송형준
35번째 : 추적60분
36번째 : 아메리칸 메이드
37번째 : 태풍 다나스 경로
38번째 : 조승연
39번째 : 심리상담사
40번째 : 송유빈

위처럼 정상출력이 됨을 확인 할 수 있습니다.

(20번째까지만 나올줄 알았는데 상위 40개까지 불러오는군요...ㄷㄷ)