전체 스터디
전체 스터디
  • 전체보기
  • 질문
  • 숙제
내 스터디
  • 스터디에 참여해보세요!
다른 스터디
  • 네이버 정복 파이썬 크롤링
    • 전체보기
    • 질문
    • 숙제
    • 잡담
  • 파이썬 기초 스터디
  • 페이스북 만드는 웹개발
  • 데이터사이언스 12시간 입문기
  • 파이썬 구글 Sheet 연동
  • 엑셀서당 - 훈장님의 기초 엑셀 트레이닝
  • 고전게임을 만들며 배우는 코딩의 기초
  • 내 업무를 거의 자동화하는 방법
  • SQL 입문 4시간
  • QR 코드 프로그래밍
  • 비전공자 개발지식 총정리
  • 초고속 퍼포먼스 마케터
  • 왓챠 함께 만들기
  • 퍼블리셔 초고속 입문기
  • 한국형 커뮤니티 만들기
  • airbnb 프론트엔드 카피 프로젝트
  • 워드프레스로 쿠팡 만들기
클래스 일정
9월
건국대
네이버 함께 정복하는 크롤링 스터디
비전공자를 위한 크롤링 핵심 과정
데이터
석민제
9월 17일 10:14 · 석민제의 팀 크롤링

네이버 쇼핑 상품리뷰를 크롤링 하는데 뒤로 갈수록(60페이지 이상?정도부터) 페이지 이동이 이상해서 질문드려요! 코드상 문제가 있는건지 궁금합니다! 

이헌영
9월 17일 14:26

민제님 안녕함세요 :) 올려주신 코드 살펴보았는데요,

기존 코드의 페이지를 클릭하는 부분

page_buttons[page % 11 + 1].click()

에서 한 페이지에서 선택할 수 있는 페이지의 수는 10개인데 %연산자 11을 입력해주셔서 해당하는 문제가 발생한 것 같아요 :) 

page_buttons[page % 10 + 1].click()

와 같이 수정해주시면 문제없이 수집이 되는 것을 확인하실 수 있습니다. 

*기존코드에서도 11페이지부터는 페이지 수집이 섞여서 되었던 것 같아요 :)

좋아요 0

    또 다시 크롤링 질문입니다...

    https://www.une-une.co.kr/outer?productListFilter=120864

    이 페이지를 크롤링하고 있는데요.
    section.section div.productListPage > div.shopProductWrapper div.price > span 이렇게 선택자를 지정해주면 가격 정보를 크롤링해와야하는데 파이썬이 None을 출력합니다.


    웹페이지 소스를 살펴보니 실제 코드에는 가격 정보가 값이 없더라고요. 구글 개발자 도구에서는 가격 정보가 나오는데 말이죠...식스샵의 개발팀에서 뭔가 개발할 때 이런식으로 정보가 노출되도록 개발을 한 것인지 어떤지 잘 모르겠으나...이럴 때는 어떻게 가격정보를 크롤링할 수 있을까요? ㅜㅜ

    자세히 보기
    최도근
    8월 28일 15:42

    보통 그 데이터가 동적으로 출력될 때 생기는 현상입니다..! selenium을 이용해보세요. requests는 정적인 페이지(실제 코드에 가격정보가 있는 경우)에서만 사용가능합니다.

    좋아요 0
      유재원
      8월 29일 12:48

      네 그럴 것 같았습니다. selenium으로 다시 해보겠습니다. 감사합니다. :)

      좋아요 0

        크롤링 관련 질문입니다.

        div.box > div.description > div.price와 같은 형태의 HTML구조에서 가격 정보를 크롤링하고 있는데요. 상품이 품절인 경우에 div.box > div.description > div.price에서 div.price는 사라지고 대신 div.soldout이 생겨서 구조가 div.box > div.description > div.soldout으로 변합니다.

        if price is None: 
         countine

        이런식으로 조건문을 써봤는데 작동하지 않네요. 이번 뿐만 아니라 이런 경우가 꽤 있어서 해결하고 싶습니다.

        질문을 요약하면 beautifulsoup의 select로 특정 class를 찾는데 실패한 경우, 해당 변수에 특정 조건을 걸어주고 싶습니다. continue한다던가 아니면 특정 string을 강제로 넣어준다던가 하고 싶습니다.

        어떻게 해야할까요?

        자세히 보기
        최도근
        8월 17일 10:38

        1. try, except를 사용해볼 수 있습니다.
        기본적으로 존재하지 않는 선택자를 검색하면 exception이 발생됩니다.

        2. price.text를 얻어내셔서 내용물을 print로 살펴보세요. 해당 text 내용물을 기준으로 if를 해보실 수 있습니다.

        if로든 try,except로든 어떻게든 상황을 걸러주어야 하고 그 후에 continue하거나 string을 강제하시면 됩니다.

        좋아요 0
          유재원
          8월 18일 01:05

          try, except로 바로 해결했습니다. :) 늘 감사드립니다!

          좋아요 0
            저도 함께 하게 됐어요~ 열심히 하겠습니다..!
            저도 함께 하게 됐어요~ 잘 부탁드려요:).
            등록했습니다. 끝까지 열심히 하겠습니다~!
            저도 참여합니다! 잘 부탁드립니다!
            석민제
            6월 29일 12:25 · 석민제의 팀 크롤링

            예전에 작성해놓은 정적페이지 크롤링 코드인데 다시 실행해보니 오류가 뜹니다! 다른 컴퓨터에서 같은 코드로 실행했을 때는 문제가 없어서 코드 문제는 아닌 거 같은데 어떤 부분이 잘못 됐을까요?ㅜㅡㅜ (beautifulsoup4 설치 되어있는 상태입니다!)

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

            import requests 

            from bs4 import BeautifulSoup 

            import openpyxl wb = openpyxl.Workbook() 


            sheet = wb.active 

            for page in range (1, 30,10): 

            keyword = '미세먼지' 

            url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=" + keyword + "&start=" + str(page) 

            raw = requests.get(url, headers={'User-Agent' : 'Mozilla/5.0'}) html = BeautifulSoup(raw.text, "html.parser") 

            infos = html.select('ul.type01 > li') 

             for info in infos: 

             title = info.select_one('a._sp_each_title').text 

             press = info.select_one('ul.type01 > li a._sp_each_url').text 

             print(title, press) 

             sheet.append([title, press]) 


             wb.save('네이버기사_크롤링_'+keyword+'.xlsx')

            자세히 보기
            최도근
            7월 2일 10:52

            일단 코드는 저도 실행이 잘 되네요.

            BeautifoulSoup4를 제대로 설치했는지 확인해주세요.
            (BeautifoulSoup과 BeautifoulSoup4 모두 있어서 설치시 헷갈릴 수 있습니다)

            좋아요 0
              안녕하세요~ 잘 부탁드립니다!
              스터디에 참여합니다. 잘 부탁드립니다!
              저도 참여합니다! 잘 부탁드립니다!
              등록했습니다. 잘 부탁드려요:).

              3. 다음 영화 데이터 수집하기


              #영화별 상세페이지 선택자
                  #제목: strong.tit_movie
                  #평점: div.subject_movie > a > em.emph_grade
                  #장르: dd.txt_main:nth-of-type(1)
                  #감독: dd.type_ellipsis:nth-of-type(1)
                  #배우: dd.type_ellipsis:nth-of-type(2)
              
              import requests
              from bs4 import BeautifulSoup
              from urllib.request import urlretrieve
              
              raw = requests.get("http://ticket2.movie.daum.net/Movie/MovieRankList.aspx")
              html = BeautifulSoup(raw.text, "html.parser")
              
              # 컨테이너 div.desc_boxthumb
              movies = html.select("div.desc_boxthumb")
              
              for m in movies:
                  title = m.select_one("strong.tit_join a")
                  url = title.attrs["href"]
                  raw_each = requests.get(url)
                  html_each = BeautifulSoup(raw_each.text, 'html.parser')
              
                  #상세페이지 컨테이너 div.detail_summarize
                  movies2 = html.select("div.detail_summarize")
              
                  for m2 in movies2:
                      title2 = m2.select_one("div.subject_movie strong.tit_movie")
                      stars = m2.select_one("div.subject_movie > a > em.emph_grade")
                      genre = m2.select_one("dd.txt_main:nth-of-type(1)")
                      director = m2.select_one("dd.type_ellipsis")
                      actors = m2.select_one("dd.type_ellipsis")
              
                      print("=" * 50)
                      print("제목:", title2.text)
              
                      print("-" * 50)
                      print("평점:")
                      for s in stars:
                          print(s.text)
              
                      print("-" * 50)
                      print("장르:")
                      for g in genre:
                          print(g.text)
              
                      print("감독:")
                      for d in director:
                          print(d.text)
              
                      print("-" * 50)
                      print("배우:")
                      for a in actors:
                          print(a.text)
              
              


              자세히 보기
              이헌영
              6월 19일 16:04

              1. 상세페이지가 아니라 기존 페이지를 수집하고 있습니다.

              raw_each = requests.get(url)
              html_each = BeautifulSoup(raw_each.text, 'html.parser')
              
              #상세페이지 컨테이너 div.detail_summarize
              movies2 = html.select("div.detail_summarize")

              html을 html_each로 바꿔주셔야합니다.

              raw_each = requests.get(url)
              html_each = BeautifulSoup(raw_each.text, 'html.parser')
              
              #상세페이지 컨테이너 div.detail_summarize
              movies2 = html_each.select("div.detail_summarize")


              좋아요 0
                이헌영
                6월 19일 16:10

                2. select_one은 요소 하나를 수집/ select는 요소를 모두 수집하는 함수입니다(리스트)

                지금 주연님의 코드를 보면 제목, 평점, 장르, 감독, 배우를 모두 select_one을 사용하여 요소 하나를 수집하고 있습니다. 이 때는 for문을 사용할 수 없으므로 아래와 같이 수집하려는 데이터의 모양에 따라 다른 함수를 사용해줍니다.

                **nth-of-type을 사용할 때는 tag이름만을 사용할 수 있습니다.
                각각 5번째, 6번째 dd태그가 감독이름과 장르를 포함하고 있습니다 :)


                    for m2 in movies2:
                        title2 = m2.select_one("div.subject_movie strong.tit_movie")
                        stars = m2.select_one("div.subject_movie > a > em.emph_grade")
                        genre = m2.select_one("dd.txt_main")
                        director = m2.select("dd:nth-of-type(5) a")
                        actors = m2.select("dd:nth-of-type(6) a")
                
                        print("=" * 50)
                        print("제목:", title2.text)
                
                        print("-" * 50)
                        print("평점:")
                        print(stars.text)
                
                        print("-" * 50)
                        print("장르:")
                        print(genre.text)
                
                        print("감독:")
                        for d in director:
                            print(d.text)
                
                        print("-" * 50)
                        print("배우:")
                        for a in actors:
                            print(a.text)


                좋아요 0
                  이헌영
                  6월 19일 16:10

                  전체코드 보기

                  #영화별 상세페이지 선택자
                      #제목: strong.tit_movie
                      #평점: div.subject_movie > a > em.emph_grade
                      #장르: dd.txt_main:nth-of-type(1)
                      #감독: dd.type_ellipsis:nth-of-type(1)
                      #배우: dd.type_ellipsis:nth-of-type(2)
                  
                  import requests
                  from bs4 import BeautifulSoup
                  from urllib.request import urlretrieve
                  
                  raw = requests.get("http://ticket2.movie.daum.net/Movie/MovieRankList.aspx")
                  html = BeautifulSoup(raw.text, "html.parser")
                  
                  # 컨테이너 div.desc_boxthumb
                  movies = html.select("div.desc_boxthumb")
                  
                  for m in movies:
                      title = m.select_one("strong.tit_join a")
                      url = title.attrs["href"]
                      raw_each = requests.get(url)
                      html_each = BeautifulSoup(raw_each.text, 'html.parser')
                  
                      #상세페이지 컨테이너 div.detail_summarize
                      movies2 = html_each.select("div.detail_summarize")
                  
                      for m2 in movies2:
                          title2 = m2.select_one("div.subject_movie strong.tit_movie")
                          stars = m2.select_one("div.subject_movie > a > em.emph_grade")
                          genre = m2.select_one("dd.txt_main")
                          director = m2.select("dd:nth-of-type(5) a")
                          actors = m2.select("dd:nth-of-type(6) a")
                  
                          print("=" * 50)
                          print("제목:", title2.text)
                  
                          print("-" * 50)
                          print("평점:")
                          print(stars.text)
                  
                          print("-" * 50)
                          print("장르:")
                          print(genre.text)
                  
                          print("감독:")
                          for d in director:
                              print(d.text)
                  
                          print("-" * 50)
                          print("배우:")
                          for a in actors:
                              print(a.text)


                  좋아요 0
                    댓글 2개 더보기

                    2. iMDb 영화포스터 수집하기

                    import requests
                    from bs4 import BeautifulSoup
                    from urllib.request import urlretrieve
                    
                    raw = requests.get("https://www.imdb.com/movies-in-theaters/?ref_=nv_mv_inth",
                                       headers={"User-Agent":"Mozilla/5.0"})
                    html = BeautifulSoup(raw.text, "html.parser")
                    
                    # 0. 컨테이너 table.nm-title-overview-widget-layout
                    movies = html.select("table.nm-title-overview-widget-layout")
                    
                    for m in movies:
                        print("="*50)
                        # 1. 영화제목 td h4
                        title = m.select_one("td h4 a")
                        print("제목:", title.text)
                    
                        url = title.attrs["href"]
                        print(url)
                    
                        print("-"*50)
                        full_url = "https://www.imdb.com/" + url
                        raw_each = requests.get(full_url, headers={"User-Agent":"Mozilla/5.0"})
                        html_each = BeautifulSoup(raw_each.text, 'html.parser')
                    
                        # 포스터: div.mv_info_area div.poster img
                        poster = html_each.select_one("div.poster img")
                        poster_src = poster.attrs["src"]
                    
                        urlretrieve(poster_src, "poster/"+title.text[:5]+".jpg")


                    자세히 보기

                    1번과제 IMDb페이지에서 현재 상영중인 영화의 제목/평점(metaccore)/감독/배우 찾기

                    #컨테이너: table.nm-title-overview-widget-layout
                    #제목: td h4
                    #평점: div.rating_txt span
                    #감독: div.txt-block a
                    #배우: div.txt-block a
                    #장르: p.cert-runtime-genre span
                    
                    
                    #2. 코드를 통해서 데이터 수집하기
                    import requests
                    from bs4 import BeautifulSoup
                    
                    raw = requests.get("https://www.imdb.com/movies-in-theaters/?ref_=nv_mv_inth",
                                       headers={'User-Agnet':'Mozilla/5.0'})
                    html = BeautifulSoup(raw.text, 'html.parser')
                    
                    Imovie = html.select("table.nm-title-overview-widget-layout")
                    
                    for m in Imovie:
                        title = m.select_one("td h4")
                        score = m.select_one("div.rating_txt > span")
                        info = m.select("div.txt-block")
                        directors = info[0].select("a")
                        actors = info[1].select("a")
                        genre = m.select("p.cert-runtime-genre span")
                    
                        genre_all = m.select_one("p.cert-runtime-genre").text
                    
                        # 3. (심화) 조건문을 활용하여 Action장르의 영화만 출력하기
                        if "Action" not in genre_all:
                            continue
                    
                        print("="*50)
                        print("제목:", title.text)
                    
                        if score is None:
                            score = "None"
                        else:
                            print("=" * 50)
                            print("평점:", score.text)
                            score = score.text
                    
                        print("-"*50)
                        print("감독:")
                        for d in directors:
                            print(d.text)
                    
                        print("-"*50)
                        print("배우:")
                        for a in actors:
                            print(a.text)
                    
                        print("-"*50)
                        print("장르:")
                        for g in genre:
                            print(g.text.replace("|","").replace(" ",""))
                    


                    자세히 보기
                    이헌영
                    6월 19일 16:00

                    <장르> 부분을 확인해보면  "첫번째" 데이터에 항상 관람 가능 연령이 저장되는 것을 확인할 수 있습니다.

                    이  부분을 해결하는 가장 쉬운 방법은 리스트의 첫번째 값을 빼주는 것인데요. 기존에 배운 슬라이싱을 활용해서 리스트의 첫번째 값을 빼줄  수 있습니다.

                    genre = genre[1:]

                    하지만 연령정보를 가지고있지 않은 경우도 있기때문에  remove함수를 활용해서  특정 값을 제거하는 방법도 있습니다.(심화)

                    remove함수는 list에서 특정 데이터를 제거해주는 함수입니다.

                    사용법)

                    LIST.remove("값")


                    수집코드에서는 span.certRating(관람 가능 연령)이 있는 경우 해당하는 요소를 삭제합니다.

                    genre = m.select("p.cert-runtime-genre span")
                    cert = m.select_one("p.cert-runtime-genre span.certRating")
                    if cert in genre:
                        genre.remove(cert)


                    좋아요 0
                      강주연
                      6월 19일 15:35

                        # Q. 장르 스크랩시 "연령" 삭제방법

                      좋아요 0
                        강주연
                        6월 19일 16:49

                        감사합니다 선생님 :)

                        좋아요 0
                          너무 고민말고 물어보세요!
                          kakao 카카오톡 상담
                          kakao 적성 테스트
                          부담없이 채팅 상담하세요. 친절한 코알라가 대기중입니다:)