리스트 다음 항목(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") 에서는
해당 텍스트를 감싸고 있는 태그만 나오는 듯하다.