XPath so với Bộ chọn CSS: Ngữ cảnh, Hỗ trợ và Bảo trì

XPath so với Bộ chọn CSS: Bạn Nên Dùng Cái Nào?

Scrapeless Agent Browser cung cấp một môi trường thực thi trình duyệt trong đó logic trích xuất có thể kiểm tra DOM của trang sau khi JavaScript chạy.

Tóm tắt nhanh

  • CSS ngắn gọn cho các quan hệ phần tử và thuộc tính phổ biến. Dùng các thuộc tính ổn định và phạm vi hẹp thay vì sao chép toàn bộ đường dẫn trực quan.
  • XPath thể hiện rõ các trục (axis), mệnh đề (predicate) và thao tác trên văn bản. Nó có thể rõ ràng hơn khi việc trích xuất phụ thuộc vào quan hệ trong cây hoặc ngữ cảnh XML.
  • CSS :has() có thể chọn một phần tử theo nội dung liên quan. Khẳng định cũ rằng CSS không bao giờ có thể chọn một vùng chứa giống “parent” là quá chung chung.
  • Tính di động của bộ chọn phụ thuộc vào engine. API trình duyệt và thư viện phân tích cú pháp có thể hỗ trợ các phiên bản và phần mở rộng khác nhau.

Bạn Nên Bắt Đầu Với Ngôn Ngữ Bộ Chọn Nào?

Bắt đầu với CSS cho các truy vấn phần tử, class và thuộc tính đơn giản, và dùng XPath khi các trục hoặc mệnh đề của nó làm cho quan hệ trở nên rõ ràng hơn. Lựa chọn XPath vs bộ chọn CSS tốt nhất là quy tắc đơn giản nhất chọn đúng các nút trong engine nơi quy tắc sẽ chạy.

Không ngôn ngữ nào tự sửa chữa nội dung nguồn bị thiếu. Nếu trang dựng danh sách sản phẩm sau khi JavaScript thực thi, một bộ chọn áp dụng lên phản hồi gốc có thể không trả về gì ngay cả khi cú pháp đúng. Hãy đảm bảo rằng cây cần thiết tồn tại trước khi so sánh các kiểu truy vấn.

The Đặc tả CSS Selectors xác định cách khớp phần tử, trong khi XPath 1.0 định nghĩa một ngôn ngữ biểu thức để điều hướng cây tài liệu. Chúng trùng lặp trong nhiều tác vụ trích xuất nhưng cung cấp các thao tác và mô hình kết quả khác nhau.

Yêu cầuCách tiếp cận bằng CSSCách tiếp cận bằng XPath
Phần tử theo thẻBộ chọn kiểu ngắnKiểm tra nút phần tử
Thuộc tính ổn địnhBộ chọn thuộc tínhMệnh đề thuộc tính
Quan hệ hậu duệToán tử kết hợp hậu duệĐường dẫn hậu duệ
Con trực tiếpToán tử kết hợp conĐường dẫn con
Quan hệ tổ tiênKhớp quan hệ có thể đáp ứng một số nhu cầuTrục tổ tiên rõ ràng
Điều kiện dựa trên văn bảnKhông có bộ chọn contains-text tổng quát trong chuẩnHàm chuỗi và mệnh đề
Giá trị thuộc tính hoặc văn bảnĐọc giá trị sau khi khớp phần tửBiểu thức có thể chọn nút thuộc tính hoặc văn bản

Ngữ Cảnh Là Một Phần Của Mọi Bộ Chọn

Ngữ cảnh của bộ chọn quyết định cây hoặc cây con mà nó được đánh giá trên đó. Cùng một biểu thức có thể trả về các kết quả khác nhau khi được đánh giá từ toàn bộ tài liệu, một thẻ sản phẩm hoặc một frame nhúng. Hãy lưu lại giả định đó cùng với quy tắc trích xuất.

XPath làm cho nút ngữ cảnh trở nên rõ ràng trong mô hình đánh giá của nó. Một đường dẫn bắt đầu từ gốc tài liệu sẽ hoạt động khác với một đường dẫn tương đối được đánh giá bên trong một mục đã chọn. Trong một vòng lặp thẻ, một truy vấn hậu duệ tương đối có thể giữ mỗi giá gắn với đúng sản phẩm, trong khi một truy vấn trên toàn tài liệu có thể vô tình chọn trường của thẻ khác.

CSS cũng cần phạm vi rõ ràng. Một bộ chọn ngắn áp dụng cho toàn bộ trang có thể khớp cả thành phần điều hướng hoặc quảng cáo cũng như các bản ghi mong muốn. Chọn phần tử chứa bản ghi trước có thể làm cho bộ chọn trường dễ đọc hơn và giảm các kết quả khớp nhầm.

The Mô hình giao diện truy vấn DOM xác định cách các truy vấn phần tử dựa trên selector hoạt động trên cấu trúc tài liệu. Đánh giá ngữ cảnh truy vấn thực tế thay vì giả định rằng một chuỗi từng hoạt động trong bảng điều khiển trình duyệt sẽ có ý nghĩa giống hệt bên trong một callback của bộ phân tích.

Khớp văn bản và Điều hướng cấu trúc

XPath thường hữu ích khi một trường được nhận diện bởi văn bản lân cận hoặc bởi một quan hệ khó diễn đạt chỉ bằng thuộc tính phần tử. Nó có thể điều hướng tổ tiên và anh chị em và áp dụng các điều kiện chuỗi. Những khả năng này có thể giúp xử lý bố cục nhãn–giá trị và tài liệu XML.

Các điều kiện văn bản vẫn cần được xử lý cẩn thận. Một nhãn có thể chứa các span lồng nhau, khoảng trắng không ngắt dòng, câu chữ được bản địa hóa hoặc văn bản bị ẩn về mặt hiển thị. So sánh chính xác với một nút văn bản có thể thất bại khi cụm từ hiển thị được ghép từ nhiều phần tử con. Hãy xác định rõ giá trị cần tìm là một nút văn bản trực tiếp, một chuỗi kết hợp, hay một nhãn hiển thị đã được render.

CSS không định nghĩa một pseudo-class chứa-văn-bản tổng quát cho truy vấn phần tử trong trình duyệt. Một số thư viện cung cấp các phần mở rộng với cú pháp trông quen thuộc, nhưng những biểu thức đó không phải là CSS chuẩn có thể dùng chung. Hãy coi các phần mở rộng của thư viện là một phần của hợp đồng với engine thay vì truyền nguyên xi chúng sang một môi trường khác.

Các phiên bản XPath cũng khác nhau. Một biểu thức dùng hàm từ phiên bản ngôn ngữ mới hơn có thể không chạy được trong giao diện XPath của trình duyệt hoặc một bộ phân tích chỉ hỗ trợ phiên bản cũ hơn. Hãy kiểm tra các phiên bản được hỗ trợ trước khi chọn một hàm chỉ vì nó xuất hiện trong một tài liệu tham khảo tổng quát.

Một Ví dụ Selector Nhỏ

Trong phần đánh dấu minh họa mà bạn kiểm soát, giả sử mỗi bản ghi là một article với thuộc tính data-record và chứa một thẻ neo với data-role="title". Biểu thức CSS article[data-record] a[data-role="title"] và biểu thức XPath //article[@data-record]//a[@data-role='title'] mô tả các thẻ neo con tương ứng. Hãy đọc giá trị liên kết từ phần tử được khớp, hoặc chọn thuộc tính của nó một cách tường minh trong XPath.

Với một điều kiện quan hệ, article[data-record]:has(a[data-role="title"]) chọn các article bao ngoài trong một engine hỗ trợ :has(). Mệnh đề XPath //article[@data-record][.//a[@data-role='title']] biểu đạt cùng điều kiện cho cây đơn giản này. Đây là các biểu thức minh họa chứ không phải selector cho một website đang hoạt động có tên cụ thể.

CSS :has() Thay Đổi Điều Gì

CSS :has() cho phép một phần tử được khớp dựa trên các phần tử có liên quan được mô tả bởi một selector tương đối. Nó có thể biểu đạt các điều kiện chọn container rất hữu ích, vì vậy phát biểu chung chung rằng CSS chỉ có thể nhìn xuống dưới là gây hiểu nhầm đối với các engine selector hiện đại.

Ví dụ, một thẻ card có thể được chọn vì nó chứa một phần tử giá được chỉ định. Kết quả được khớp chính là thẻ card được nêu làm chủ thể của selector. XPath có thể biểu đạt các yêu cầu liên quan thông qua predicate và trục (axes), nhưng kiểu trả về và ngữ cảnh chính xác vẫn phụ thuộc vào biểu thức.

Đừng suy diễn rằng chỉ cần có trong chuẩn là sẽ được hỗ trợ ở mọi nơi. Một trình duyệt, một bộ chuyển đổi CSS-to-XPath phía server, và một engine nhúng cũ hơn có thể triển khai các tính năng khác nhau. Nếu một selector phải được dùng chung giữa các môi trường đó, hãy chọn tập con được hỗ trợ hoặc ghi lại các quy tắc tương đương riêng biệt.

Khớp quan hệ cũng không thay thế được thiết kế field mang tính ngữ nghĩa. Một container có bất kỳ phần tử con giống giá nào vẫn có thể là thẻ sản phẩm sai. Hãy xác thực bộ định danh và quan hệ của nó với giá trị được trích xuất thay vì chấp nhận selector chỉ vì nó trả về một node.

Tính Di Động Bao Gồm Cả Mô Hình Tài Liệu

Tính di động của selector phụ thuộc cả vào hỗ trợ cú pháp lẫn cây được cung cấp cho engine. Phân tích HTML của trình duyệt, một bộ phân tích XML và một bộ phân tích HTML phía server có tính dung sai cao có thể tạo ra các cấu trúc khác nhau từ đầu vào tương tự. Namespace bổ sung thêm một nguồn khác gây khác biệt đối với XML.

Công cụ inspector của trình duyệt có thể hiển thị các node được chèn bởi script hoặc do trình phân tích tự sửa. Bộ phân tích phản hồi chỉ thấy đầu vào của nó và các quy tắc phân tích của chính nó. Hãy so sánh một cây con nhỏ có liên quan khi kết quả khác nhau; việc thay CSS bằng XPath không giải quyết được sự khác biệt trong cây nguồn.

Frame và shadow tree tạo ra các ranh giới truy vấn bổ sung. Một truy vấn thông thường trên tài liệu cấp cao nhất không nên được cho là sẽ tự động đi xuyên mọi tài liệu nhúng hoặc được bao đóng. Hãy dùng mô hình truy cập được hỗ trợ cho từng cây và tôn trọng các ranh giới bảo mật của nó.

Scrapeless Agent Browser có thể cung cấp lớp thực thi trình duyệt khi nội dung cần script. Logic trích xuất của bạn vẫn quyết định tài liệu và trạng thái nào sẽ được kiểm tra. Phần so sánh XPath và CSS cung cấp thêm các ví dụ để đối chiếu với chuẩn và hỗ trợ engine hiện tại.

Tính Dễ Bảo Trì Quan Trọng Hơn Một Tuyên Bố Tốc Độ Chung Chung

Hãy chọn một selector thể hiện một quan hệ ổn định và người bảo trì có thể hiểu. Các đường dẫn tuyệt đối dài và quy tắc phụ thuộc nhiều vào vị trí rất nhạy cảm với thay đổi bố cục. Ưu tiên thuộc tính có ý nghĩa, ngữ cảnh bản ghi rõ ràng và việc xác thực định danh đã trích xuất.

Cả CSS lẫn XPath đều không luôn luôn nhanh hơn. Cách triển khai engine, quá trình biên dịch, kích thước tài liệu và cấu trúc truy vấn đều ảnh hưởng đến việc thực thi. Hãy đo lường một khối lượng công việc đại diện tại chỗ nếu hiệu năng truy vấn là quan trọng, và tách riêng thời gian mạng và render khỏi thời gian đánh giá selector.

  1. Xác nhận các node cần thiết tồn tại trong cây đã chọn.
  2. Giới hạn phạm vi truy vấn vào đúng bản ghi hoặc tài liệu.
  3. Dùng một thuộc tính ổn định hoặc quan hệ rõ ràng.
  4. Kiểm tra số lượng kết quả khớp mong đợi và các giá trị field bắt buộc.
  5. Kiểm tra field vắng mặt, nhãn trùng lặp và biến thể bố cục.
  6. Ghi lại các giả định về engine và ngôn ngữ để phục vụ bảo trì.

Với các thẻ card lặp lại, hãy xác thực việc ghép cặp bản ghi cũng như từng giá trị riêng lẻ. Một selector tiêu đề và một selector giá mỗi cái đều có thể trả về kết quả có vẻ hợp lý trong khi vị trí của chúng không còn tương ứng nữa. Hãy trích xuất trong từng card và giữ một định danh ổn định cùng bản ghi để làm cho lỗi đó có thể quan sát được.

Khi cần thực thi trong trình duyệt, hãy dự trù chi phí đó trong các gói Scrapeless hiện tại. Đừng chọn một ngôn ngữ truy vấn với kỳ vọng rằng nó có thể tránh hiển thị nội dung không tồn tại trong phản hồi gốc.

Xem lại thay đổi bộ chọn với một phản ví dụ

Việc xem xét bộ chọn nên bao gồm một biến thể trang nơi mục tiêu bị thiếu hoặc bị lặp lại. Nếu một thẻ sản phẩm không có giá giảm, quy tắc không được âm thầm chọn giá từ thẻ tiếp theo. Nếu cùng một nhãn xuất hiện trong điều hướng và trong bài viết, ngữ cảnh phải giữ cho kết quả gắn với phần dự định.

Giữ một cây con ví dụ nhỏ, đã được cho phép cho mỗi biến thể bố cục có ý nghĩa và so sánh cả định danh bản ghi mong đợi lẫn giá trị. Một truy vấn trả về một chuỗi có vẻ hợp lý là bằng chứng không đủ khi tập dữ liệu phụ thuộc vào việc ghép cặp chuỗi đó với một mục cụ thể. Các phản ví dụ bộc lộ lỗi ghép cặp đó rõ ràng hơn so với một lần khớp thành công trên một trang đơn giản.

Kết luận

Dùng CSS cho việc khớp phần tử rõ ràng và dùng XPath cho các mối quan hệ hoặc biểu thức giá trị mà nó mô tả trực tiếp hơn. Xác minh ngữ cảnh, trạng thái tài liệu và hỗ trợ của engine trước khi so sánh kết quả. Lựa chọn bền vững là bộ chọn có ý nghĩa vẫn rõ ràng khi trang hoặc môi trường trích xuất thay đổi.

Xác thực bộ chọn so với DOM yêu cầu

Dùng Scrapeless Agent Browser khi các node bạn cần chỉ xuất hiện sau khi thực thi hoặc tương tác.

Đăng ký hôm nay và nhận $5 tín dụng miễn phí — không cần thẻ tín dụng.

Nhận $5 tín dụng của bạn →

Câu hỏi thường gặp

H: CSS có thể chọn một container dựa trên các phần tử con của nó không?

CSS có thể chọn một container dựa trên các phần tử liên quan với :has() khi engine hỗ trợ nó. Điều này bao phủ các nhu cầu khớp kiểu cha hữu ích, mặc dù nó không giống hệt mọi trục hoặc biểu thức XPath.

H: XPath luôn chậm hơn CSS sao?

XPath không phải lúc nào cũng chậm hơn CSS. Hiệu năng phụ thuộc vào engine và truy vấn. Một số công cụ phía server dịch CSS sang XPath ở bên trong, vì vậy hãy so sánh các thao tác tương đương trong môi trường thực tế khi thời gian đánh giá là quan trọng.

H: Tại sao một bộ chọn hoạt động trong inspector nhưng lại lỗi trong parser?

Một bộ chọn có thể lỗi trong parser vì cây đầu vào khác với DOM của trình duyệt hoặc vì các engine hỗ trợ cú pháp khác nhau. Kiểm tra nội dung được xây dựng bằng JavaScript, khác biệt trong quá trình phân tích, ngữ cảnh truy vấn và các phần mở rộng đặc thù thư viện trước khi viết lại quy tắc.

H: Một dự án có nên chỉ dùng một ngôn ngữ bộ chọn không?

Một dự án không cần chỉ dùng một ngôn ngữ bộ chọn. Hãy dùng một phong cách nhất quán cho các trường hợp phổ biến và chọn biểu thức được hỗ trợ, rõ ràng hơn cho các trường hợp ngoại lệ. Ghi lại ngữ cảnh và kỳ vọng về giá trị trả về để các quy tắc pha trộn vẫn dễ bảo trì.

Tài liệu tham khảo