인프런 커뮤니티 질문&답변

이승민님의 프로필 이미지
이승민

작성한 질문수

실습으로 끝장내는 웹 크롤링과 웹 페이지 자동화 & 실전 활용

Coupang a.["href"] 정보 관련 문의

작성

·

255

0

안녕하세요, 쿠팡 크롤링 영상을 보다가 궁금한 점이 있어서 문의드립니다.

실습을 위하여 아래와 같이 코드를 입력하였습니다.

import requests
from bs4 import BeautifulSoup

base_url = "https://www.coupang.com/np/search?component=&q="
keyword = input("검색할 상품을 입력하세요 : ")

search_url = base_url + keyword

headers = {
  "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

cookie = {"a" : "b"}

res = requests.get(search_url, timeout=5 ,headers=headers, cookies=cookie)

html = res.text

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

items = soup.select("[class=search-product]")

print(items[0])

rank = 1
for item in items:
  badge_rocket = item.select_one(".badge.rocket")
  if not badge_rocket:
    continue

  name = item.select_one(".name")
  price = item.select_one(".price-value")
  thumb = item.select_one(".search-product-wrap-img")
  link = item.select_one("a")["href"] 
  # link = item.a["href"]

  print(f"{rank}")
  print(name.text)
  print(f"{price}원")
  print(thumb)
  print(link)
  print()

  rank += 1

그랬더니 아래와 같은 에러가 뜨더라구요.

Traceback (most recent call last):

File "c:\Users\LG\OneDrive\03. Resources\Python\08_1_coupang.py", line 40, in <module>

link = item.a["href"]

~~~~~~^^^^^^^^

File "C:\Users\LG\AppData\Local\Programs\Python\Python312\Lib\site-packages\bs4\element.py", line 1573, in getitem

return self.attrs[key]

~~~~~~~~~~^^^^^

KeyError: 'href'

 

그래서 이 검색을 하던 도중에 items 리스트의 첫 번째 데이터를 확인하였습니다.

그랬더니, items[0] 내에 'href' 속성이 존재하지 않더라구요.

분명 elements에서 검색했을 때는 아래 캡쳐처럼 존재를 하였습니다..

왜 이런지 궁금합니다..

 

<li
  class="search-product"
  data-coupon-nudge-text=""
  data-coupon-tag-area="true"
  data-freebie-vendor-item-id="null"
  data-handyman-area=""
  data-is-rocket="true"
  data-is-soldout=""
  data-product-id="7410323525"
  data-vendor-item-id="86316217055"
  data-winner-vendor-item-id="86316217055"
  id="7410323525"
>
  <a
    class="search-product-link"
    data-is-soldout=""
    data-item-id="19198810280"
    data-product-id="7410323525"
    data-product-link="/vp/products/7410323525?itemId=19198810280&amp;vendorItemId=86316217055"
    data-srp-log='{"group":"PRODUCT", "itemId":"19198810280", "productId":"7410323525", "vendorItemId":"86316217055", "page":"1", "listSize":"36", "isCcidEligible":false, "displayCcidBadge":false, "wowOnlyInstantDiscountRate": 9, "snsDiscountRate" : -1, "isLoyaltyMember": false, "hasAsHandymanBadge":false }'
    data-vendor-item-id="86316217055"
    target="_blank"
    ><dl class="search-product-wrap adjust-spacing coupon">
      <dt class="image">
        <img
          alt="주연테크 FHD LED 100Hz 모니터, 54.6cm, V22FX(일반)"
          class="search-product-wrap-img"
          data-src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
          height="230"
          onerror="this.src='//img2a.coupangcdn.com/image/coupang/common/no_img_1000_1000.png'"
          onload="logTime(this);logImageLoadTime(this);"
          src="//thumbnail7.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/671217612372165-b6d07ba8-e3fa-4a08-8fba-cb4adbedd0d0.jpg"
          width="230"
        />
      </dt>
      <dd class="descriptions">
        <div class="descriptions-inner">
          <div class="badges"></div>
          <div class="name">
            주연테크 FHD LED 100Hz 모니터, 54.6cm, V22FX(일반)
          </div>
          <div class="price-area">
            <div class="price-wrap">
              <div class="price">
                <span class="price-info">
                  <span class="instant-discount-rate">2%</span>
                  <del class="base-price"> 91,610 </del>
                </span>
                <em class="sale discount isInstantDiscount">
                  <strong class="price-value">89,000</strong>원
                  <span class="badge rocket">
                    <img
                      alt="로켓배송"
                      height="16"
                      src="//image6.coupangcdn.com/image/cmg/icon/ios/logo_rocket_large@3x.png"
                    />
                  </span>
                </em>
              </div>
              <div class="coupon-wot-nudge-row">
                <div class="coupon-wot-nudge-ticket">
                  <div class="coupon-wot-nudge-ticket_left_border">
                    <span class="coupon-wot-nudge-ticket_left_border_amount"
                      >8,900</span
                    >원
                  </div>
                  <div class="coupon-wot-nudge-ticket_right_border"></div>
                </div>
                <div class="coupon-wot-nudge-text">와우회원 추가 쿠폰</div>
              </div>
              <!-- Free Shipping Badge -->
              <div class="delivery">
                <span class="arrival-info">
                  <em style="color: #008c00">내일(화) </em>
                  <em style="color: #008c00">도착 보장 </em>
                </span>
              </div>
            </div>
            <div class="used-product-info">
              <span>새 상품</span><span>, </span><span>반품</span
              ><strong> (9)</strong> <span>최저</span><strong>73,870</strong
              ><span>원</span>
            </div>
          </div>
          <div class="other-info">
            <div class="rating-star">
              <span class="star"
                ><em class="rating" style="width: 90%">4.5</em></span
              >
              <span class="rating-total-count">(1188)</span>
            </div>
          </div>
          <div class="benefit-badges">
            <div class="reward-cash-badge">
              <div class="reward-cash-badge__inr">
                <img
                  alt=""
                  class="reward-cash-ico"
                  src="//image6.coupangcdn.com/image/badges/cashback/web/list-cash-icon@2x.png"
                />
                <span class="reward-cash-txt">최대 3,694원 적립</span>
              </div>
            </div>
          </div>
        </div>
      </dd>
    </dl>
    <span class="number no-1">1 </span>
    <div class="mask"></div
  ></a>
</li>
PS C:\Users\LG\OneDrive\03. Resources\Python>

 

 

답변 1

0

이승민님의 프로필 이미지
이승민
질문자

아래와 같은 방법으로 해결했습니다.

link = item.select_one("a")["data-product-link"]
  1. thumb에서 페이지 소스코드에 들어가서 보니 위와 같은 속성으로 접속이 가능하여 기존 href 대신하여 사용하였습니다.

  2. 위와 같은 방법으로 진행하면 되는지 궁금합니다.

  3. 그렇다면 왜 href는 검색이 되지 않고, 개발자 도구에서만 보여지는지 궁금합니다.

     

 

김플님의 프로필 이미지
김플
지식공유자

답변을 쓰려고 보니 이미 해결하셨군요.
위 방법을 사용하시면 됩니다.
개발자 도구에서 보여지는 소스코드는 자바스크립트가 반영된 지금 현재 화면(지금 눈에 보이는 화면)의 소스코드입니다.
하지만 실제 우리가 requests.get(url)로 접속해서 가져오게 되는 html은 웹브라우저에서 페이지 소스 보기를 했을때 나오는 소스코드입니다. 두개는 다른거죠. 만약 모든 정보를 자바스크립트를 사용해서 보여주는 웹페이지라면 개발자도구에서 봤을때는 정보가 보이지만 페이지 소스 보기에서는 자바스크립트 코드만 볼 수 있습니다.
예를 하나 들자면,
쿠팡 제품 상세페이지에 들어갔을때 제품 후기를 확인하고 개발자 도구에서 보면 후기가 코드에 나옵니다. 하지만 쿠팡 제품 후기는 페이지에 들어갔을때 처음부터 나오는게 아니고 클릭을 하거나 후기 위치까지 이동해서 실제 화면에 보일때 나타나는 것이기 때문에 페이지 소스 보기 했을때는 안나옵니다.
이런경우 웹페이지의 정보를 가져오려면 셀레니움을 사용합니다.
이후 커리큘럼에서 셀레니움을 배우고 나면 좀 더 이해가 되실겁니다.

이승민님의 프로필 이미지
이승민

작성한 질문수

질문하기