본문 바로가기

카테고리 없음

[나도코딩 파이썬 활용편 웹스크래핑(7)] sibling(형제), parent(부모), 해당 태그와 텍스트를 갖는 코드 출력하기

리스트 다음 항목(sibling)으로 넘어가기

네이버부동산 페이지를 다시 한 번 보면,

첫 번째 이후에 2, 3, 4... 쭉 나열되어있다.

개발자도구에서도 보면,

item_item_1, 2, 3... 이런식으로 되어있다.

 

이렇게 형제끼리 넘나들 수 있다.

근데 원래 예제를 보면...

<li> 바로 아래 <li 2 . 3. 4 ...>가 있는 반면에

네이버 부동산은 형제태그들인

li 하위에 a 태그 클래스로 2, 3, 4 구분이 되어있어서

똑같이 할 수 있을지 모르지만 일단 해본다.

 


강의예시

먼저 강의에 나온 예시를 보면,

첫 번째 next_sibling에서는 공백이 출력되어서

두 번 입력했더니 두 번째 값이 출력되었다.

 

직접 해보기
rank1 = soup.find("a", attrs={"class":"item item_1"})
print(rank1.next_sibling)
print(rank1.next_sibling.next_sibling)

이렇게 해보니?

 

첫 번째 next_sibling에서는 마찬가지로 공백이 출력되었고

두 번 입력해주니 None이 출력된다.

 

그도 그럴게, 해당 li 태그 내에서 a의 형제(sibling)이 없기 때문이다.

 

그러면 li를 먼저 출력하고

순서대로 나오게 하면 어떨까?

 

한 가지 우려되는 점은,

예시에서 네이버웹툰은 li class에 이미 rank 1, 2, 3 구분이 되어있지만

 

네이버부동산에서는 li class = item_area로

1위부터 10위까지 class 명이 전부 같다는 것이다.

 

그래도 일단 가장 우선되는 li부터 출력해줄것이니

일단은 해본다!!

 

rank1 = soup.find("li", attrs={"class":"item_area"})
print(rank1.next_sibling.next_sibling)

이렇게 입력해보니..

 

리스트 두번째인,

sibling을 잘 출력하는 것을 확인할 수 있었다.

 


해당 sibling 의 text 구문 출력해보기

예시에서는 a 태그 내 text가 있지만

네이버 부동산은 하위태그인 span내에 있다.

 

이런 식으로...

가장 첫 번째 span 태그의 text는 2이다.

 

rank1 = soup.find("li", attrs={"class":"item_area"})
rank2 = rank1.next_sibling.next_sibling
rank3 = rank2.next_sibling.next_sibling

print(rank1.span.get_text())
print(rank2.span.get_text())
print(rank3.span.get_text())

아래와 같이 1, 2, 3이 잘 출력된다.

 

클래스명이 "text"인 값을 가져오려면...

# rank1 = soup.find("li", attrs={"class":"item_area"})
# rank2 = rank1.next_sibling.next_sibling.find("span", attrs={"class":"text"})
# rank3 = rank2.next_sibling.next_sibling.find("span", attrs={"class":"text"})
# 이건 안됨. AttributeError 발생함. find 에서!!

일단 이렇게하면 실행은 안된다 ㅎ;

 

첫 번째 태그가 아닌 다음 태그를 가져오는 방법은

뒤에 나오지않을까 해서 일단 패스해본다.

 


previous_sibling ... 앞에 있는 형제 sibling 출력하기
rank1 = soup.find("li", attrs={"class":"item_area"})
rank2 = rank1.next_sibling.next_sibling
rank3 = rank2.next_sibling.next_sibling

print(rank3.span.get_text())
rank2 = rank3.previous_sibling.previous_sibling
print(rank2.span.get_text())

 

rank2 를 rank3 의 앞에 앞에 있는 거라고 정의해주고

해당 rank2 의 span 태그 text를 출력해주면

"2" 라고 잘 출력됨을 확인할 수 있다.

 

 

find_next_sibling("태그명")

next_sibling을 여러번 입력할 필요 없이,

sibling 중 원하는 태그를 가진 부분만 고를 수 있다.

 

예를 들면 우리는 <li>태그를 가진 부분만 원하니

find_next_sibling("li")라고 입력해준다.

rank2= rank1.find_next_sibling("li")
print(rank2.span.get_text())

next_sibling을 여러 번 입력했을 때와 마찬가지로

2 가 출력되는 것을 확인할 수 있다.

 

 

find_next_siblings("태그명") ... 해당 태그의 모든 sibling 출력하기
print(rank1.find_next_siblings("li"))

rank1의 형제들이므로 rank1 값은 출력되지않고 

2위부터 끝까지 값이 출력된다.

 


parent ... 부모태그 
print(rank1.parent)

해당 내용을 출력해보면...

 

해당 부모태그 전체가 출력된다.

 

원하는 텍스트text 찾기

위에서는 태그를 찾고, 그 다음 텍스트를 출력했다면

이번에는 원하는 텍스트의 코드를 찾아온다.

 

예를 들면 아래 네이버부동산 페이지에서,

'전세사기 이슈' 저 부분의 텍스트를 찾는다고 하면

개발자 모드에서 본 코드는 다음과 같다.

 

 

해서 아래 코드로 입력해보니...

realestate = soup.find("a", text = "전세사기 이슈")

 

DeprecationWarning 이라고 표시된다.

Error가 아니라 그냥 Warning이므로 출력은 되는데,

 

Deprecated = 더 이상 사용되지 않는

즉, 더 좋은 기능이 있으니 이건 쓰지말라고 권장하는

그런 내용의 경고인 것 같다.

 

시스템에서는 위에서 쓴 'text' 대신

차라리 'string'을 쓰라고 권장한다.

 

아무튼 난 예시대로

text를 써서 입력했는데,

"None"이 출력되었다.

 

다시 개발자도구를 확인해보면

a 태그가 상위에 있기는 하지만

내가 찾고자하는 "전세사기 이슈"라는

해당 텍스트를 감싸고 있는 것은

<strong> 태그이다.

 

따라서 strong으로 바꿔주었더니..

realestate = soup.find("strong", text = "전세사기 이슈")
print(realestate)

잘 출력됨을 확인할 수 있다.

 

다른 기능으로 가능하겠지만,

soup.find("태그명", text = "찾고자하는 text") 에서는

해당 텍스트를 감싸고 있는 태그만 나오는 듯하다.