앞선 코드를 고쳐보자.
우선
for book in books:
# price = book.find_all("a", {"class":"bo_used"}).find_all 판매분류와 가격이 한번에 뽑힌다.
price = book.select("div > tbody > tr")
print(price)
로 바꿔준다.
그리고 실행하면,
[]
[]
[]
이런 당황스러운 결과를 보게된다. 그렇게 어려운 코드가 아닌데, 왜 이런걸까?
알고보니, 크롬에서는 자체적으로 소스코드에 없는 tbody라는 요소를 추가한다.
그래서, css 선택자를 약간 변경해야한다.
기나긴 소스코드 분석을 통해서 다음과 같이 바꾸면 된다는 결론에 이른다. css 선택자를 select로 입력해서 나온 결과값은 type이 list이다. 이때, list에는 select메소드가 작동하지 않는다.(이걸 알아차리지 못하고 계속 삽질하면 엄청난 오류를 맞닥뜨린다.) >> 리스트가 아니라 select 메소드가 작동할 수 있는 bs4.element로 대상을 변경해줘야 한다.
그래서, 네번째 줄에 book.select("table > tr > td")에서 끝나지 않았고, book이라는 bs4.element 타입 객체안에 총 세개의 table > tr > td 요소가 있다. [첫번째 td, 두번째 td, 세번째 td] 이 중 세번째 요소 안에 가격이 있다.
그래서 이것을 price 변수로 받아내 기본적인 리스트 인덱싱을 해준다.
여기서 재밌는 점은, 리스트 인덱싱 결과 나온 세번째 요소는 사실 타입이 bs4.element이다. 그래서, 또다시 [2].select(".....") 을 할 수가 있는거다.
books = soup.find_all("div",{"class":"ss_book_box"})
for book in books:
# price = book.find_all("a", {"class":"bo_used"}).find_all 판매분류와 가격이 한번에 뽑힌다.
price = book.select("table > tr > td")[2].select("table.usedtable01 > tr > td")
print(price)
>>>><class 'bs4.element.Tag'>
>>>>[<td><a class="bo_used" href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=193931483"><b>16,200원</b></a></td>, <td><a class="bo_used" href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=277382846"><b> 14,400원</b></a></td>, <td><a class="bo_used" href="/shop/UsedShop/wuseditemall.aspx?ItemId=193931483&TabType=2"><b>11,400원</b></a></td>, <td><a class="bo_used" href="/shop/UsedShop/wuseditemall.aspx?ItemId=193931483&TabType=3"><b>12,000원</b></a></td>, <td><a class="bo_used" href="/shop/UsedShop/wuseditemall.aspx?ItemId=193931483&TabType=1"><b>13,000원</b></a></td>]
타입은 bs4.element.Tab, 결과 리스트는 [첫번째 td 16200원, 두번째 td 14400원, ...., 다섯번째 td 13000원]으로 나온다.
여기서 첫번째로 중요한건 내가 받아오는 결과가 list인지, bs4.element.Tab인지 알아차리고, 내가 원하는 코드를 짤 때에 필요한 자료형으로 바꿔주는 거다.
그리고 두번째로 중요한거는, "table.usedtable01 > tr > td"로 하면, 모든 td들을 모아 리스트로 만들어준다는 부분이다.
이 때에, 무슨이유에서든 이 select 함수는 마지막에 나온 선택자 요소들만 모아서 ,로 리스트 내에서 구분해준다.
그리고, 이 특징을 최대한 이용하기 위해서 우리가 원하는 가격이 td로 구분되어 있다면, td까지 써주는게 유리하다.
만약에 안그런다면, 어떻게 되는지 보자.
books = soup.find_all("div",{"class":"ss_book_box"})
for book in books:
# price = book.find_all("a", {"class":"bo_used"}).find_all 판매분류와 가격이 한번에 뽑힌다.
price = book.select("table > tr > td")[2].select("table.usedtable01 > tr ")[1]
print(price)
'파이썬 공부 > 기초' 카테고리의 다른 글
파이썬 이중콜론 :: 의미 (0) | 2022.06.02 |
---|---|
The current PyTorch install supports CUDA capabilities sm_37 sm_50 sm_60 sm_61 sm_70 sm_75 compute_37 에러 (0) | 2022.03.01 |
[python] 알라딘 중고서점 스크래핑-3 (0) | 2021.12.21 |
알라딘 중고서점 가격 스크래핑(파이썬) (0) | 2021.12.21 |
리스트 옮기기(파이썬) (0) | 2021.01.20 |