Trong quá trình tự động hóa web với Selenium, có nhiều trường hợp bạn cần tìm các phần tử dựa trên tên thẻ và thuộc tính (attributes) của chúng. Thay vì phải tìm kiếm riêng lẻ từng loại thẻ hoặc thuộc tính, chúng ta có thể xây dựng một hàm linh hoạt để tìm kiếm bất kỳ thẻ HTML nào với các thuộc tính cụ thể. Hàm này giúp chúng ta tối ưu quá trình tìm kiếm và quản lý các phần tử trong DOM một cách dễ dàng hơn.
Dưới đây là hướng dẫn chi tiết về hàm find_elements_by_tag_and_attributes
, sử dụng Selenium:
def find_elements_by_tag_and_attributes(driver, tag_name="*", attributes={}):
# Tạo query XPath với tên thẻ
xpath_query = f"//{tag_name}"
# Nếu có thuộc tính cần tìm, thêm điều kiện vào query
if attributes:
conditions = []
for attr, value in attributes.items():
# Tìm kiếm giá trị gần đúng cho từng thuộc tính
conditions.append(f"contains(@{attr}, '{value}')")
# Kết hợp các điều kiện thành một chuỗi XPath hoàn chỉnh
xpath_query += f"[{' and '.join(conditions)}]"
# Trả về danh sách các phần tử phù hợp với XPath query
return driver.find_elements_by_xpath(xpath_query)
1. Mục đích của hàm
Hàm find_elements_by_tag_and_attributes
được sử dụng để:
- Tìm kiếm các thẻ HTML trong trang web dựa trên tên thẻ và các thuộc tính gần đúng.
- Tăng tính linh hoạt khi có thể áp dụng cho bất kỳ thẻ nào (
a
, div
, span
, v.v.) và bất kỳ thuộc tính nào (class
, id
, href
, v.v.).
- Tiết kiệm thời gian cho người lập trình khi cần tìm kiếm nhiều phần tử phức tạp trong DOM.
2. Các tham số đầu vào
Hàm nhận ba tham số chính:
driver
: Đây là đối tượng trình duyệt đang hoạt động trong Selenium, dùng để tương tác với DOM của trang web.
tag_name
(mặc định là "*"
) : Tên thẻ HTML cần tìm. Mặc định là "*"
, có nghĩa là tìm tất cả các thẻ. Bạn có thể chỉ định bất kỳ thẻ nào như a
, div
, span
, input
, v.v.
attributes
(mặc định là {}
): Là một dictionary chứa các cặp khóa (thuộc tính) và giá trị (giá trị gần đúng của thuộc tính) mà bạn muốn tìm. Ví dụ: { "class": "header", "id": "main" }
.
3. Cấu trúc hoạt động của hàm
Bước 1: Tạo query XPath với tên thẻ
xpath_query = f"//{tag_name}"
: Đây là bước tạo query XPath cơ bản để tìm thẻ HTML dựa trên tên thẻ được truyền vào. Ví dụ, nếu tag_name
là "div"
, query XPath sẽ là "//div"
để tìm tất cả các thẻ div
trong trang web.
Bước 2: Kiểm tra và thêm điều kiện về thuộc tính
Nếu attributes
được truyền vào, hàm sẽ tạo một danh sách các điều kiện dựa trên các cặp thuộc tính và giá trị.
- Duyệt qua các thuộc tính: Với vòng lặp
for attr, value in attributes.items()
, hàm sẽ duyệt qua từng cặp attr
(thuộc tính) và value
(giá trị gần đúng).
- Sử dụng hàm
contains
của XPath: contains(@{attr}, '{value}')
là cách tìm kiếm trong XPath để kiểm tra xem giá trị của thuộc tính có chứa chuỗi con được chỉ định hay không.
- Ví dụ:
contains(@class, 'header')
sẽ tìm tất cả các thẻ có class chứa chuỗi "header"
.
Bước 3: Kết hợp các điều kiện
xpath_query += f"[{' and '.join(conditions)}]"
: Nếu có nhiều điều kiện tìm kiếm (nhiều thuộc tính), hàm sẽ nối các điều kiện này lại bằng từ khóa and
để tìm các phần tử thỏa mãn tất cả các điều kiện.
Bước 4: Trả về danh sách các phần tử
return driver.find_elements_by_xpath(xpath_query)
: Sau khi hoàn thành câu query XPath, hàm sẽ sử dụng Selenium để tìm các phần tử thỏa mãn điều kiện và trả về danh sách các phần tử đó.
4. Ví dụ sử dụng
Giả sử bạn đang làm việc trên một trang web và muốn tìm tất cả các thẻ div
có class chứa "example"
và id chứa "header"
. Bạn có thể sử dụng hàm như sau:
driver = webdriver.Chrome()
driver.get("https://example.com")
# Tìm tất cả các thẻ div có class chứa 'example' và id chứa 'header'
attributes = {
"class": "example",
"id": "header"
}
elements = find_elements_by_tag_and_attributes(driver, "div", attributes)
# In ra các thuộc tính của thẻ đã tìm được
for element in elements:
print(element.get_attribute("class"), element.get_attribute("id"))
Kết quả:
Hàm sẽ trả về các thẻ div
thỏa mãn điều kiện rằng chúng có:
class
chứa chuỗi "example"
.
id
chứa chuỗi "header"
.
5. Lợi ích của hàm
- Tính linh hoạt cao: Bạn có thể tìm bất kỳ thẻ nào với bất kỳ thuộc tính nào bằng cách truyền vào tên thẻ và danh sách thuộc tính.
- Tiết kiệm thời gian: Giảm bớt việc viết nhiều đoạn mã lặp lại để tìm các phần tử dựa trên nhiều thuộc tính khác nhau.
- Dễ dàng mở rộng: Nếu cần thêm các điều kiện phức tạp hơn (như so sánh giá trị chính xác, tìm theo nội dung văn bản), bạn chỉ cần sửa đổi hàm mà không cần viết lại từ đầu.
Kết luận
Hàm find_elements_by_tag_and_attributes
giúp tự động hóa quá trình tìm kiếm các phần tử HTML trong trang web một cách linh hoạt và hiệu quả. Bạn có thể dễ dàng tìm kiếm bất kỳ thẻ nào dựa trên các thuộc tính khác nhau và áp dụng vào nhiều trường hợp khác nhau trong quá trình làm việc với Selenium.