ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 개발공부 13일차 [웹스크래핑(크롤링), DB]
    개인공부 2023. 2. 7. 11:53

    라이브러리

    import requests
    
    r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
    rjson = r.json()
    
    rows = rjson['RealtimeCityAir']['row']
    
    for a in rows:
      gu_name = a['MSRSTE_NM']
      gu_mise = a['IDEX_MVL']
      print(gu_name, gu_mise)

    gu_name, gu_mise값만 추출해서 반복문으로 볼 수 있음

    크롤링 : 웹에 접속해서 데이터를 솎아내어 가지고옴

    오른쪽 하단에 ‘venv’:venv 로 잘 열려있는지 확인

    잘 열려있다면 터미널에 (venv)가 있는지 확인

    없다면 터미널 → 새터미널 눌러주면 생김

    라이브러리를 가져올때 : 터미널에 pip install (가져올 라이브러리 이름) 치기

     

    requests - 요청하다

    beautifulsoup - 솎아내다

    import requests
    from bs4 import BeautifulSoup
    
    headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
    
    soup = BeautifulSoup(data.text, 'html.parser')
    
    #old_content > table > tbody > tr:nth-child(2)
    #old_content > table > tbody > tr:nth-child(3)
    
    #old_content > table > tbody > tr:nth-child(2) > td.title > div > a
    
    trs = soup.select('#old_content > table > tbody > tr')
    for tr in trs:
      a = tr.select_one('td.title > div > a')
      if a is not None:
        print(a.text)

    1. 크롤링 할 페이지에서 가져올 글에 검사로 tr을 먼저 찾아

        #old_content > table > tbody > tr:nth-child(2)

        #old_content > table > tbody > tr:nth-child(3) \

        이중 공통되는 #old_content > table > tbody > tr 공통되는 걸 변수trs에 찾는다.

        (공통되는걸 찾을때는 tr에 우클릭으로 Copy → CopySelector로 가져올 수 있다)

    2. trs를 반복문으로 불러온다.

    3. tr안에서 내가 가져올

        #old_content > table > tbody > tr:nth-child(2) > td.title > div > a

        공통되는 td.title > div > a를 찾는다.

    4. 찾은 td에 ——— 도 포함이 되어있어 None으로 표시되는데

        if a is not None: 을 써서 None이 아닌것만 text로 불러온다.

     

     

    응용하기

    import requests
    from bs4 import BeautifulSoup
    
    headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
    
    soup = BeautifulSoup(data.text, 'html.parser')
    
    #old_content > table > tbody > tr:nth-child(2)
    #old_content > table > tbody > tr:nth-child(3)
    
    #old_content > table > tbody > tr:nth-child(2) > td.title > div > a
    #old_content > table > tbody > tr:nth-child(2) > td:nth-child(1) > img
    #old_content > table > tbody > tr:nth-child(2) > td.point
    
    trs = soup.select('#old_content > table > tbody > tr')
    for tr in trs:
      a = tr.select_one('td.title > div > a')
      if a is not None:
        title = a.text
        rank = tr.select_one('td:nth-child(1) > img')['alt']
        star = tr.select_one('td.point').text
        print(rank, title, star)

    a는 이미 찾았기때문에 title 변수를 만들어 a.text로 넣어준다.

    rank, star도 동일한 방식으로 가져오고 마지막에 원하는 순서로 찍으면 완성

    ⬇️결과값 

     

    ------------------------------------------------------------------------------------------

     

    데이터베이스 - DB

    SQl - 이미 정해진 칸에 넣는거임.

        이미 정해져 있어 사람이 틀릴 리 없음 / 후에 변하지 않는다는 가정으로 / 빨리 가져올 수 있음 (대기업같은 경우)

    NoSQl (Not only SQL) - 정형화된 틀이 아님 / 데이터를 내 마음대로 저장할 수 있음

        (스타트업이 주로 사용) 저장할 틀이 변경될일이 많을 경우

     

    mongoDB Atlas - 클라우드

    from pymongo import MongoClient
    client = MongoClient('mongodb+srv://sparta:test@cluster0.wpply3w.mongodb.net/?retryWrites=true&w=majority')
    db = client.dbsparta
    
    doc = {
      'name':'영수',
      'age':24
    }
    db.users.insert_one(doc)

    db.users.insert_one(doc) ← 여기에 users는 소그룹이름 이라고 생각해도 됨

    pymongo

    # 저장 - 예시
    doc = {'name':'bobby','age':21}
    db.users.insert_one(doc)
    
    # 한 개 찾기 - 예시
    user = db.users.find_one({'name':'bobby'})
    
    # 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
    all_users = list(db.users.find({},{'_id':False}))
    #{'_id':False}를 사용하는 이유는 _id의 값을 출력하지 않기 위해서다.
    
    # 바꾸기 - 예시
    db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
    
    # 지우기 - 예시
    db.users.delete_one({'name':'bobby'})

    mongoDB에 자료 넣는 방법 복습

    from pymongo import MongoClient
    client = MongoClient('mongodb+srv://sparta:test@cluster0.wpply3w.mongodb.net/?retryWrites=true&w=majority')
    db = client.dbsparta
    
    
    trs = soup.select('#old_content > table > tbody > tr')
    for tr in trs:
      a = tr.select_one('td.title > div > a')
      if a is not None:
        title = a.text
        rank = tr.select_one('td:nth-child(1) > img')['alt']
        star = tr.select_one('td.point').text
        doc = {
          'title': title,
          'rank' : rank,
          'star' : star
        }
        db.movies.insert_one(doc)
    1. 기존 영화 목록에 상단에 몽고디비에 연결될 수 있도록 넣어준다.
    2. Dictionary를 만들어서 넣어줘야함 doc = {}
    3. 마지막으로 insert해주기 위해 movies라는 소그룹명을 만들고 넣어줌.

     

    위 내용을 가지고 Quiz풀기

    1. 영화제목’가버나움’의 평점을 가져오기
    movie = db.movies.find_one({'title':'가버나움'})
    print(movie['star'])

     

      2. ‘가버나움’의 평점과 같은 평점의 영화 제목들을 가져오기

    movie = db.movies.find_one({'title':'가버나움'})
    target_star = movie['star']
    
    movies = list(db.movies.find({'star':target_star},{'_id':False}))
    for a in movies:
      print(a['title'])
    1. 변수 movie에서 가버나움의 star값을 target_star라는 변수라고 해놓는다.
    2. 변수 movies로 소그룹movies에 star값이 target_star이 동일한 것만 가지고 온다.
    3. 마지막으로 반복문으로 타이틀만 가지고온다.

     

    3. ‘가버나움’의 영화의 평점을 0으로 만들기 

    db.movies.update_one({'title':'가버나움'},{'$set':{'star':0}})

     

    숙제

    import requests
    from bs4 import BeautifulSoup
    
    headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)
    
    soup = BeautifulSoup(data.text, 'html.parser')
    
    #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.title.ellipsis
    #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.number
    #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.artist.ellipsis
    trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
    for tr in trs:
      a = tr.select_one('td.info > a.title.ellipsis')
      title = a.text.strip()
      rank = tr.select_one('td.number').text[0:2].strip()
      artist = tr.select_one('a.artist.ellipsis').text.strip()
      print(rank,title,artist)

    text[0:2]는 텍스트에 2번째 글자 까지만 나오게 한다.

    strip()은 글자의 공백이 없게 나오게 한다.

     

    크롤링 강의를 처음봤을땐 어..?싶었고 일단 다 보고서 강의를 다시 멈추면서 하나하나 적어가면서 다시 보니깐 이해가 갔고 생각보다 재밌었다. 

    마지막 숙제에서는 진짜 구글링을 아직 할 줄 모르니까 제대로된 답도 안나오고 '그냥 강의에 답을 볼까..?' 싶었다가 꾹참았다.

    시간은 좀 걸렸지만 스스로 하고 맞은걸 보니 넘나 뿌듯...하다..

Designed by Tistory.