Ở bài viết trước chúng ta đã tìm hiểu về Selenium và bắt đầu đăng nhập vào Facebook. Hôm nay, chúng ta sẽ cũng tìm hiểu về cách lấy các bài đăng ở một địa chỉ Facebook bất kỳ và tự động thực hiện việc nhấn nút Like cho nó nhé.
Xem lại phần 1 tại đây

Lấy thông tin bài đăng
Trước khi bắt đầu chúng ta like một bài viết chúng ta cần phải biết nó like cho bài viết nào. Mỗi một bài đăng đều bao gồm nội dung và những hình ảnh, video trong bài viết đó đồng thời cũng có cả react của chúng ta trong bài viết đó
Chúng ta sẽ tiếp tục tìm hiểu về một số method và thuộc tính mới của Selenium
- text lấy thông tin về đoạn văn bản mà được hiển thị trong WebElement đó
- find_element_by_class_name() tìm phẩn tử đầu tiên có tên class cho sẵn
- get_attribute() lấy ra thông tin của thuộc tính của WebElement
Chúng ta có thể thấy ở mỗi bài đăng nằm trong một thẻ div có tên class là _5pcr userContentWrapper. Tuy nhiên với method find_element_by_class_name chỉ có thể tìm với 1 class đơn lẻ khi ta tìm nhiều class nó sẽ báo lỗiSyntaxError: '.._5pcr.userContentWrapper' is not a valid selector. Tuy nhiên, chúng ta biết rằng việc tìm các phần tử bằng CSS Selector cũng có thể giúp ta tìm được những phần tử có nhiều tên class. Vì vậy ta sẽ dùng method find_elements_by_css_selector thay vì find_elements_by_class_name
| class FBPost(object): | |
| def __init__(self, postElement): | |
| #init post's content | |
| try: | |
| self._content = postElement.find_element_by_css_selector('p').text | |
| except: | |
| self._content = "" | |
| #init link media in this post | |
| try: | |
| self._mediaLinks = postElement.find_element_by_class_name('mtm') | |
| self._mediaLinks = self._mediaLinks.find_elements_by_css_selector('a') | |
| except: | |
| self._mediaLinks = None | |
| self._react = FBReact(postElement) | |
| def get_content(self): | |
| return self._content | |
| def get_media_links(self): | |
| if(self._mediaLinks is None): | |
| return [] | |
| return [media.get_attribute('href') for media in self._mediaLinks] | |
| def get_react(self): | |
| return self._react |
Mình sẽ nói qua một chút về việc lấy nội dung và các hình ảnh, video trong bài viết nhé
trong mỗi một bài đăng trên Facebook, nội dung của bài đăng sẽ được nằm trong thẻ p và các đường link của hình ảnh hay video của bài đăng đó sẽ được nằm trong thẻ div có tên class là mtm và để lấy được những đường link đó ta chỉ việc tìm các thẻ a trong thẻ div đó và lấy ra thuộc tính href của chúng
Lấy thông tin về Reaction mà bạn ở bài đăng đó và nhấn nút like
Phần tiếp theo này, chúng ta sẽ được tìm hiểu thêm 2 method mới của Selenium đó là
- value_of_css_property lấy ra giá trị của thuộc tính của một phần tử CSS của WebElement đó
- execute_script thực hiện lệnh JavaScript trong WebDriver đó
Trước tiên, ta thấy rằng thông tin về Reaction đều được nằm trong một thẻ div có class name là _6a-y _3l2t _18vj vì vậy ta tiếp tục sử dụng method get_element_by_css_selector để tìm ra nó.
Tiếp đến ta sẽ cần phải tìm ra trạng thái Reaction hiện tại của bài đăng để biết liệu chúng ta đã nhấn like hay thả tim,…vào bài viết đó chưa và việc này cũng vô cũng đơn giản bằng cách gọi thuộc tính text của nó ra. Tuy nhiên, có một vấn đề là trong trường hợp chúng ta nhấn like hay chưa để bất kỳ Reaction nào thì thuộc tính text đều trả về giá trị 'Like' điều đó sẽ gây khó khăn khi ta muốn phân biệt chúng với nhau. Ta lại thấy rằng khi chưa thả bất kỳ Reaction nào vào bài đăng thuộc tính color của nó có giá trị là rgb(96, 103, 112) và khi đã like bài viết thuộc tính color sẽ chuyển sang rgb(32, 120, 244) vì vậy ta sẽ sử dụng thuộc tính color để phân biệt giữa trạng thái đã like và chưa có Reaction và gọi trạng trái đó là 'Nothing'
Cuối cùng, để có thể nhấn like cho bài viết, ta sẽ sử dụng câu lệnh driver.execute_script("arguments[0].click();", self._reactElement) để click vào nút like đó và sử dụng hàm sleep(1) để ngừng lại 1 giây đảm bảo rằng nó đã được thực hiện
| class FBReact(object): | |
| def __init__(self, postElement): | |
| self._reactElement = postElement.find_element_by_css_selector("._6a-y._3l2t._18vj") | |
| def get_state(self): | |
| reactText = self._reactElement.text | |
| if(reactText != 'Like'): | |
| return reactText | |
| if(self._reactElement.value_of_css_property('color') == 'rgb(96, 103, 112)'): | |
| return 'Nothing' | |
| else: | |
| return 'Like' | |
| def __has_reacted(self): | |
| return (self.get_state() != 'Nothing') | |
| def __remove_react(self, driver): | |
| if(not self.__has_reacted()): | |
| return | |
| driver.execute_script("arguments[0].click();", self._reactElement) | |
| sleep(1) | |
| def like(self, driver): | |
| if(self.get_state() == 'Like'): | |
| return | |
| self.__remove_react(driver) | |
| driver.execute_script("arguments[0].click();", self._reactElement) | |
| sleep(1) |
Có lẽ đến đây bạn đã có thể tự mình tạo ra được một chương trình auto like Facebook cho chính mình. Mình viết bài viết này để giúp mọi người có thêm hiểu biết về Selenium không khuyến khích các hành động gây rối và làm ảnh hưởng tới người khác. Mình hy vọng sẽ nhận được nhiều hơn ý kiến đóng góp của các bạn và hẹn gặp lại ở những bài viết tiếp theo