본문 바로가기
파이썬

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로

by fecu 2022. 6. 5.
728x90

파이썬 셀레니움으로 인스타그램의 좋아요 버튼을 계속 누르고 있었는데, 인스타그램이 업데이트 될 때 마다 경로를 계속 변경해주어야 한다는 번거로움이 있었다. 그래서 이를 해소하기 위해 XPath를 어떻게 상대경로로 지정해 줄 수 있는지, 그리고 상대경로를 지정할 때의 장점에 대해 글을 써보려고 한다.

1. XPath 절대경로 형식, 그리고 문제점

이때까지 쓴 좋아요 봇의 글들은 모두 XPath를 절대경로로 지정했었다. XPath의 절대 경로의 형식은 아래와 같다.

xpath = /html/body/div[6]/div[3]/div/article/div/div[2]/div/div/div[2]/section[1]/span[1]

위의 경로는 좋아요 버튼의 부모 XPath이다. 문제는 최근 인스타그램의 업데이트가 잦아지면서 XPath가 계속 변한다는 것. 지난번 첫 글을 쓴 후에 2022년 2월, 5월 업데이트를 하였으나, 이번에 6월 업데이트에 또 다시 버튼들의 XPath가 모조리 바뀌면서 한달만에 또 업데이트를 해야하는 상황이 되었다. 이제 이런 상황을 방지하기 위해 XPath를 모두 상대경로로 변경하여 보기로 했다.

2. XPath 상대 경로

XPath의 상대 경로는 아래와 같은 형식을 지닌다.

XPath = //tagname[@atrribute='value']

 

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-2

상대 경로를 이용하면 태그명과 속성, 그리고 속성 이름과 속성 값을 알고 있다면 절대 경로가 변경되어도 값을 쉽게 찾을 수 있다.

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-3

예를들어 인스타그램의 좋아요 버튼의 절대 경로는 계속 변경되지만, 버튼 내부의 svg 태그 속성 중 aria-label의 속성 값이 '좋아요'라는 속성 값을 가지고 있다는 것은 몇번의 업데이트를 지나도 변하지 않았다. 하지만 '좋아요'의 속성 값을 가진 svg 태그가 클릭을 받아줄 수 없기 때문에, 해당 태그의 부모 태그를 찾고 좋아요 버튼, 버튼의 상태 등을 받아내는 것으로 XPath를 수정해보려고 한다. 

3. XPath 상대 경로의 형식(매서드)

1) 기본 형식

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-4

아래와 같이 다음 버튼의 XPath를 상대 경로로 지정해보기로 하자. 다음 버튼의 태그네임은 button, 속성 이름은 aria-label이며 속성 값은 '다음'이다. 이를 상대경로로 지정하면 아래와 같다.

XPath = //button[@aria-label='다음']
XPath = //*[@aria-label='다음']

XPath에서 태그네임에 *을 넣어준다면, 이는 모든 태그 네임을 검색하는 것을 뜻한다. 만일 이 버튼을 셀레니움을 이용하여 클릭하고 싶다면, 아래와 같이 코드를 작성할 수 있을 것이다.

driver.find_element_by_xpath('//button[@aria-label="다음"]').click()

 

2) contains(@attribute, 'value 중 일부')

contains()는 속성명 중 값에 해당하는 요소들을 찾아주는 메서드이다. 값의 전체를 넣지 않고 일부만 넣어도 찾아줄 수 있다. 

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-5

예를들어 네이버 홈페이지에 모바일 버젼으로 접속했을 때, 속성이 media이고 속성 값이 false인 것을 찾아보기로 하자. 그러면 속성값이 media이고, 값이 false인 요소를 찾아준다. find_element_by_xpath는 찾은 요소 중 제일 첫번째 것을 보여주므로, elements를 이용하면 여러개의 요소를 찾을 수도 있다. find_elements_by_xpath를 이용하면 여러개의 요소들을 찾는 것이 가능하고, 리스트 형식으로 선택하는 것도 가능하다.

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-6

contains(text(),'찾고자 하는 텍스트')를 활용하면 원하는 텍스트를 포함한 요소를 찾는 것도 가능하다. 

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-7

3) and, or 

and와 or은 기본 프로그램 명령어와 같다. 원하는 요소를 모두 포함하려면 and, 둘중 하나만 포함하려면 or을 쓰면 된다. 

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-8

예를들어 xpath를 이용하여 '다음' 버튼을 찾으려는데, 내부 속성값에 '다음'을 가진 버튼이 총 3개가 있을 때 and를 이용할 수 있다. 내가 누르고자 하는 버튼의 내부 속성에만 height = "16"이라는 값이 있을 경우, 이 버튼의 xpath를 찾고 누르는 코드를 만들어본다면 아래와 같을 것이다.

driver.find_element_by_xpath('//*[@aria-label="다음" and @height="16"]').click()

위와 같이 코딩할 경우, 셀레니움은 aria-label의 값이 '다음'이고 height 값이 '16'인 것을 클릭하게 될 것이다.

4) starts-with(@attribute, 'value')

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-9

starts-with(@attribute, "value") 메서드는 속성 값 중 같은 값으로 시작하는 요소들을 찾아준다. 위와 같이 input 태그 중 aria-label이 '전화번호'의 값을 가진 태그를 클릭하자 아이디 입력칸에서 커서가 깜박인다. 패스워드 칸을 상대 경로로 인식해주고 싶다면, aria-label 값을 '비밀번호'로 입력해주면 될 것이다.

5) text() = 'value'

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-10

text()메서드는 원하는 값이 있는 텍스트 요소를 찾아준다. xpath에서 '비밀번호를 잊으셨나요?' 라는 텍스트를 찾아 클릭하도록 하니 새롭게 로그인을 할 수 있는 페이지로 들어왔다. 

728x90

6) 계층 메서드

웹의 구조에서 div, span 등 계층적 구조의 내부나 외부에서 찾고자 하는 요소들을 찾아주는 기능이다.

(1) 자손 선택자

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-11

찾고자 하는 태그 내에서의 태그네임을 찾을수 있다. 위의 식에선 h1태그 중 class 네임이 "sch_logo"인 것을 찾고, 그 안에서도 input을 받는 태그를 클릭하도록 구현해 보았다. 자손의 xpath를 찾기 위한 정규식은 아래와 같다.

XPATH = //tagname[@attribute='value'] // following::tagname

(2) 조상 선택자

인스타그램 좋아요 봇 만들기 5 : XPath 상대경로-12

인스타그램의 좋아요 버튼을 누를 때, aria-label이 '좋아요' 혹은 '좋아요 취소'인 태그의 상위 태그를 찾아야 했다. 이를 구현하기 위한 코드는 아래와 같다.

div = driver.find_element_by_xpath('//*[@aria-label="좋아요" or @aria-label="좋아요 취소"]//ancestor :: span[2]')

자손 선택자에선 following을, 조상 선택자에선 ancestor을 넣어주면 된다. 맨 마지막에 리스트에서의 순서와 같이 [숫자]를 넣으면 자손 혹은 조상 선택자를 순차적으로 선택할 수 있다.

4. 결론 : 상대 경로를 이용해야 하는 이유

위의 내용과 같이 절대 경로를 이용하여 셀레니움을 운영하는 경우, 웹 사이트의 변경사항에 따라 매번 코드를 바꿔주어야 한다. 하지만 상대 경로의 경우 웹 사이트의 전체적인 구조가 변하지 않는 이상, 몇 가지의 포인트를 가지고 원하는 태그의 XPath를 찾아낼 수 있다. 따라서 업데이트를 해 주어야 할 주기도 줄어들게 된다. 이제 앞으로의 좋아요 봇의 글은 모두 상대 경로를 이용해 주려고 한다. 다음 글에서는 상대경로를 이용하여 이때까지 쓴 글들을 모두 한꺼번에 정리해볼 것이다.

728x90