Crawler 실습 - 1

  • Crawler(크롤러) : 웹 페이지에 있는 자료를 자동으로 수집하는 프로그램
  1. 주소를 입력하면 해당 서버로 접근한다.
  2. 웹 서버 프로그램이 해당 주소에 맞는 내용을 전달한다.
    -> requests(urllib의 wrapper 클래스)

  3. 받은 내용을 해석해서 화면을 보여준다.
    3-1. 받은 내용을 해석해서 내가 원하는 데이터를 찾는다.
    -> BeautifulSoup + HTML 코드의 해석 + CSS Selector

  • 모듈 설치

    1
    2
    $ pip install requests
    $ pip install BeautifulSoup4 # pip install bs4도 가능
  • 셀렉터

    • HTML Tag
      1) Container Tag : 맨 앞이 태그 이름

      1
      2
      # ex)
      <div td="adf">내용</div>

      2) Empty Tag : 이미지 태그

      1
      2
      # ex)
      <img src="이미지 주소">
    • 태그는 속성을 갖는다.

    • 원하는 텍스트를 얻고 싶다면 태크를 찾아야 한다.
  1. 단일 셀렉터

    1
    <div id="super" class="test" data-rel="" data-num="">cont</div>
    • tag 이름 : ex) div
    • id : 앞에 ‘#’을 붙인다. id는 한 페이지 내에서 중복될 수 없다. ex) #super
    • class : 앞에 ‘.’을 붙인다.(별명이나 그룹이름이라고 생각하면 된다.) ex) .test
  2. 다중 셀렉터

    • ~안에 있는 무엇
      ex) div li.ah_k : 중간 경로 생략 가능
      ex) div > ul > li.ah_k : 중간 경로 생략 불가능 = 더 빠름
    • 띄워쓰기가 되어있는 것은 여러 별명으로 되어있는 것으로 그 중에 하나만 선택해서 사용하면 된다.

    • ~이고 ~인 것
      ex) span.ah_k.ah_some : span이고 ah_k이고 ah_some인 것

  • naver를 이용하여 실시간 검색어 순위 및 최근 회차 로또 당첨번호 가져오기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    # 웹 페이지에 접근해서 데이터를 가져온다.
    # requests는 ajax로 받아온 데이터를 실시간으로 반영할 수 없다.
    # requests로 받아온 데이터는 소스 보기에서 보는 소스까지만 있다.(정적 페이지)

    # selenium : 웹 브라우저를 원격 조작하는 방식의 크롤러
    # selenium, scrapy
    import requests

    # 가져온 데이터를 HTML로 해석한다.
    from bs4 import BeautifulSoup

    url = "https://www.naver.com/"
    # URL Encoding
    # url : 영문
    # 영문이 아닌 한글은 인코딩된다.
    # 내용을 알고싶으면 URL Decoding을 해야 한다.
    url2 = "https://search.naver.com/search.naver?sm=top_hty&fbm=1&ie=utf8&query=%EB%A1%9C%EB%98%90+%EB%8B%B9%EC%B2%A8%EB%B2%88%ED%98%B8"
    # HTTP Method : Get, Post, Put, Head, Delete
    # Get : 리소스 얻기
    # Post : 데이터 전달 - 로그인, 회원가입, 글쓰기 ------------ 수정
    # Put : 리소스 전달 - 사진 올리기 ------------- 최조 업로드
    # Delete : 리소스 삭제
    # Head : Method 확인
    # Postman 이라는 익스텐션치 or 애플리케이션 설치

    custom_headers = {
    'referer':'https://www.naver.com',
    'user-agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0'
    # user-agent는 사용자마다 다르므로 확인하자.
    }
    req = requests.get(url, headers=custom_headers)
    print(req.status_code)
    print(type(req.status_code))

    # 200이라고 쓰는 것은 명확한 코드가 아니므로 codes의 ok를 사용
    if req.status_code == requests.codes.ok:
    print("접속 성공")
    # 데이터 해석
    req.text
    print(req.text)

    # html parser를 이용해서 해석하라는 의미
    html = BeautifulSoup(req.text, "html.parser")

    keywords = html.select('.ah_list .ah_k')
    items = html.select('.ah_list .ah_item')

    for keyword in keywords:
    print(keyword.text)
    print(keywords)

    # 실시간 검색어 순위 가져오기
    for item in items:
    keyword = item.select_one('.ah_k')
    rank = item.select_one('.ah_r')
    link = item.select_one('.ah_a')
    # print(rank.attrs['class'])

    # print(rank['class'])
    print(rank.text, keyword.text, link['href'])

    # ~ 어떤 요소를 찾고
    # 그 요소 안에 각각의 요소를 다시 찾을 수 있다.

    else:
    print("접속 실패")

    # 최근 회차 로또 당첨번호 가져오기
    req2 = requests.get(url2)

    if req2.status_code == requests.codes.ok:
    print("접속 성공")
    html = BeautifulSoup(req2.text, "html.parser")

    numbers = html.select('.ds div.num_box .num')

    for number in numbers[:6]:
    print(number.text, end = ", ")
    print("보너스 번호: ", numbers[-1].text)
    else:
    print("접속 실패")
  • daum을 이용하여 모든 회차 로또 당첨번호를 가져오기

  • 모든 회차 당첨번호 카운트 세기
  • 엑셀 파일로 저장하기
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    import requests

    from bs4 import BeautifulSoup

    # file - setting - projectname - interpreter에서 현재 설치된 모듈을 확인할 수 있다.
    from openpyxl import Workbook

    # Workbook : 파일
    # Worksheet : 탭
    # 내용을 저장하기 위해 파일 만들기(메모리 상에)
    wb = Workbook()

    ws1 = wb.active # 엑셀 처음 시트 가져오기
    ws2 = wb.create_sheet(title='lotto_list')
    ws1.title = 'lotto_Count'


    #dictionary comprehension
    numbers_count = {x:0 for x in range(1, 46)}

    for num in range(1,856):
    url = "https://search.daum.net/search?w=tot&rtmaxcoll=LOT&DA=LOT&q="+str(num)+"회차 로또"

    req = requests.get(url)

    if req.status_code == requests.codes.ok:
    print("접속 성공")

    print(num,'회차')

    html = BeautifulSoup(req.text, "html.parser")

    numbers = html.select('span.img_lotto')

    ws2.cell(row=num, column=1, value=str(num)+'회차')

    for index, number in enumerate(numbers):

    # print(number.text, end=', ')
    ws2.cell(row=num, column=index+2, value=int(number.text))

    numbers_count[int(number.text)] += 1

    # print('보너스 번호: ', numbers[-1].text)

    else:
    print("접속 실패")

    print(numbers_count)

    # for row in range(1, 46):
    # ws1.cell(row=row, column=1, value=row)
    # ws1.cell(row=row, column=2, value=numbers_count[row])

    for k, v in numbers_count.items():
    ws1.cell(row=k, column=1, value=k)
    ws1.cell(row=k, column=2, value=v)


    wb.save('./lotto_list_text.xlsx')
Share