Bỏ để qua phần nội dung

Cách sử dụng Bộ chọn XPath để quét web trong Python

  • by
  • Blog
  • Đã đọc 8 phút

Nếu bạn đang tìm cách trích xuất dữ liệu từ các trang web bằng Python, XPath là một công cụ thiết yếu cần có trong bộ công cụ quét web của bạn. XPath cung cấp cách điều hướng qua cấu trúc HTML của trang và xác định chính xác các thành phần và dữ liệu bạn cần.

Trong hướng dẫn này, chúng ta sẽ tìm hiểu những kiến ​​thức cơ bản về XPath và trình bày cách bạn có thể tận dụng sức mạnh của nó để quét web bằng Python. Cuối cùng, bạn sẽ sẵn sàng giải quyết nhiều tác vụ thu thập dữ liệu khác nhau bằng cách sử dụng XPath để trích xuất dữ liệu mà bạn đang theo đuổi một cách triệt để.

XPath là gì?

XPath là viết tắt của Ngôn ngữ đường dẫn XML. Đó là ngôn ngữ truy vấn để chọn các nút từ tài liệu XML hoặc HTML. Với XPath, bạn chỉ định một mẫu phù hợp với cấu trúc tài liệu và nó sẽ trả về tất cả các phần tử khớp với mẫu đó.

Mặc dù ban đầu được thiết kế cho XML, XPath hoạt động tốt với HTML, khiến nó trở nên lý tưởng cho mục đích quét web. Nó cung cấp một giải pháp thay thế mạnh mẽ và linh hoạt hơn cho bộ chọn CSS hoặc biểu thức chính quy.

Cơ bản về cú pháp XPath

Để bắt đầu sử dụng XPath, bạn cần hiểu các khối xây dựng của cú pháp XPath. Dưới đây là những khái niệm chính:

Chọn nút theo tên thẻ

Biểu thức XPath cơ bản nhất chỉ đơn giản là chỉ định tên thẻ. Ví dụ:

  • //h1 chọn tất cả các <h1> thành phần tiêu đề trên trang
  • //p chọn tất cả các <p> yếu tố đoạn văn
  • //img chọn tất cả các <img> yếu tố hình ảnh

Chọn nút theo thuộc tính

Bạn có thể chọn các phần tử có thuộc tính hoặc giá trị thuộc tính cụ thể bằng cách sử dụng @ cú pháp:

  • //*[@class="highlighted"] chọn tất cả các thành phần có lớp "được đánh dấu"
  • //a[@href] chọn tất cả <a> các phần tử neo có thuộc tính href
  • //img[@alt="Logo"] chọn <img> các phần tử có văn bản thay thế là "Logo"

Chọn nút theo vị trí

Bạn có thể chọn các nút dựa trên vị trí của chúng bằng dấu ngoặc vuông [] và một chỉ số số:

  • //ul/li[1] chọn cái đầu tiên <li> mục trong mỗi <ul> danh sách không có thứ tự
  • //table/tr[last()] chọn cái cuối cùng <tr> hàng trong mỗi <table>
  • //ol/li[position() <= 3] chọn ba cái đầu tiên <li> các mục trong mỗi <ol> danh sách được yêu cầu

Chọn nút theo mối quan hệ

XPath cho phép bạn điều hướng lên xuống cây tài liệu để chọn các thành phần dựa trên tổ tiên, con cháu, anh chị em của chúng, v.v.:

  • //div[@class="content"]/* chọn tất cả các phần tử con của <div> các phần tử có lớp "nội dung"
  • //p/.. chọn các phần tử cha của tất cả <p> đoạn văn
  • //h1/following-sibling::p chọn tất cả <p> các phần tử là anh em ruột sau một <h1> phần mở đầu
  • //section//img chọn tất cả <img> các phần tử là hậu duệ của một <section> ở bất kỳ cấp độ nào

Vị ngữ và hàm

XPath hỗ trợ nhiều vị từ và hàm để tinh chỉnh thêm các lựa chọn của bạn:

  • //p[contains(text(),"scrapy")] chọn <p> các phần tử có chứa văn bản "scrapy"
  • //a[starts-with(@href,"https")] chọn <a> các phần tử trong đó href bắt đầu bằng "https"
  • //ul[count(li) > 10] chọn <ul> phần tử chứa nhiều hơn 10 <li> mặt hàng
  • //img[string-length(@alt) > 0] chọn <img> các phần tử có thuộc tính alt không trống

Sử dụng XPath với lxml và BeautifulSoup

Bây giờ bạn đã hiểu những điều cơ bản về cú pháp XPath, hãy xem cách bạn có thể sử dụng nó trong Python với các thư viện lxml và BeautifulSoup phổ biến. Chúng ta sẽ xem qua một ví dụ về việc lấy văn bản tiêu đề chính từ trang chủ ScrapingBee.

Phân tích cú pháp HTML bằng lxml và BeautifulSoup

Trước tiên, chúng ta cần tìm nạp HTML của trang web bằng thư viện yêu cầu và phân tích nó thành cấu trúc cây mà chúng ta có thể truy vấn bằng XPath. Chúng tôi sẽ sử dụng BeautifulSoup để phân tích cú pháp HTML và lxml để đánh giá các biểu thức XPath của chúng tôi:

import requests
from bs4 import BeautifulSoup
from lxml import etree

html = requests.get("https://scrapingbee.com") 
soup = BeautifulSoup(html.text, "html.parser")
dom = etree.HTML(str(soup))

Tại đây chúng tôi:

  1. Tìm nạp HTML bằng cách sử dụng requests.get()
  2. Phân tích chuỗi HTML thành đối tượng BeautifulSoup bằng cách sử dụng html.parser
  3. Chuyển đổi đối tượng BeautifulSoup thành một chuỗi để chúng ta có thể phân tích cú pháp nó bằng lxml etree.HTML() chức năng
  4. Phân tích chuỗi thành lxml Element đối tượng chúng ta có thể truy vấn bằng XPath

Xây dựng và đánh giá các biểu thức XPath

Bây giờ chúng ta đã có một cây HTML được phân tích cú pháp, chúng ta có thể xây dựng một biểu thức XPath để chọn phần chính <h1> tiêu đề trên trang:

heading_xpath = ‘//h1‘

Để đánh giá XPath này dựa trên tài liệu HTML được phân tích cú pháp của chúng tôi, chúng tôi sử dụng xpath() phương pháp:

heading_elements = dom.xpath(heading_xpath)

Sản phẩm dom.xpath() cuộc gọi sẽ trả về danh sách tất cả các phần tử khớp với bộ chọn XPath của chúng tôi. Trong trường hợp này, chỉ nên có một kết quả phù hợp <h1> thành phần.

Trích xuất văn bản và thuộc tính

Khi có tham chiếu đến phần tử, chúng ta có thể dễ dàng trích xuất văn bản của nó và bất kỳ thuộc tính nào bằng cách sử dụng thuộc tính của lxml:

heading_text = heading_elements[0].text
print(heading_text)
# Tired of getting blocked while scraping the web?  

Chúng ta đã trích xuất thành công văn bản tiêu đề chỉ bằng một dòng XPath! Chúng ta cũng có thể truy cập các giá trị thuộc tính của phần tử bằng cách sử dụng get():

heading_id = heading_elements[0].get(‘id‘)  

Sử dụng XPath với Selenium

Một cách tiếp cận khác là sử dụng Selenium để tự động hóa và loại bỏ các trang web động yêu cầu JavaScript. Selenium cung cấp các phương thức riêng để chọn các phần tử bằng chuỗi XPath.

Định cấu hình Selenium WebDriver

Để bắt đầu với Selenium, trước tiên bạn cần cài đặt gói Selenium và trình điều khiển web cho trình duyệt bạn muốn sử dụng. Dưới đây là cách bạn có thể định cấu hình trình điều khiển Chrome:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver_path = "/path/to/chromedriver"  
driver = webdriver.Chrome(driver_path)

Đảm bảo tải xuống phiên bản ChromeDriver thích hợp cho cài đặt Chrome của bạn và cung cấp đường dẫn đến tệp thực thi.

Tìm phần tử bằng XPath

Với trình điều khiển được định cấu hình, chúng ta có thể điều hướng đến một trang web và bắt đầu tìm các phần tử. WebDriver của Selenium cung cấp một find_element phương thức chấp nhận bộ định vị XPath:

driver.get("https://scrapingbee.com")

heading_xpath = "//h1"
heading_element = driver.find_element(By.XPATH, heading_xpath)

Tương tự như ví dụ lxml, điều này sẽ tìm thấy đầu tiên <h1> phần tử trên trang. Nếu bạn muốn tìm tất cả các phần tử khớp với XPath, hãy sử dụng find_elements thay thế:

paragraph_xpath = "//p"
paragraph_elements = driver.find_elements(By.XPATH, paragraph_xpath)  

Trích xuất văn bản và thuộc tính

Khi bạn có tham chiếu đến một thành phần web, bạn có thể truy cập các thuộc tính của nó như nội dung văn bản và thuộc tính:

heading_text = heading_element.text
print(heading_text)  
# Tired of getting blocked while scraping the web?

paragraph_id = paragraph_elements[0].get_attribute("id")

Việc trích xuất dữ liệu bằng Selenium và XPath khá đơn giản, nhưng hãy nhớ rằng Selenium thường chậm hơn so với sử dụng thư viện yêu cầu HTTP đơn giản vì nó chạy một trình duyệt thực tế.

Mẹo và Thực tiễn Tốt nhất

Khi bạn bắt đầu sử dụng XPath để quét web, đây là một số mẹo và thủ thuật cần ghi nhớ:

Sử dụng Chrome DevTools để kiểm tra biểu thức XPath

Khi xây dựng các bộ chọn XPath, sẽ rất hữu ích khi kiểm tra chúng một cách tương tác để đảm bảo chúng khớp với những gì bạn mong đợi. Chrome DevTools cung cấp một cách dễ dàng để thực hiện việc này:

  1. Nhấp chuột phải vào một phần tử và chọn "Kiểm tra" để mở bảng điều khiển DevTools Elements
  2. Nhấn Ctrl+F để mở hộp tìm kiếm
  3. Nhập biểu thức XPath của bạn để đánh dấu các phần tử phù hợp trên trang

Xử lý đánh dấu không nhất quán

Các trang web ngoài tự nhiên thường có đánh dấu HTML không nhất quán hoặc bị hỏng, điều này có thể làm hỏng bộ chọn XPath của bạn. Bạn nên sử dụng thư viện như BeautifulSoup để dọn dẹp và chuẩn hóa HTML trước khi phân tích cú pháp bằng lxml.

Viết XPath mạnh mẽ và có thể bảo trì

Để giảm thiểu khả năng công cụ nạo của bạn bị hỏng do thay đổi bố cục trên trang đích, hãy thử viết các biểu thức XPath càng cụ thể càng tốt nhưng không cụ thể hơn mức cần thiết. Ưu tiên lựa chọn theo các thuộc tính ngữ nghĩa như tên thẻ, ID và thuộc tính dữ liệu hơn là dựa vào cấu trúc cụ thể của đánh dấu.

Bạn cũng nên chia các biểu thức XPath phức tạp thành các biến có tên mô tả để cải thiện khả năng đọc và bảo trì.

Kết quả bộ nhớ đệm để cải thiện hiệu suất

Nếu bạn đang thu thập lượng lớn dữ liệu hoặc truy cập vào cùng một trang nhiều lần, hãy cân nhắc việc lưu vào bộ nhớ đệm các kết quả HTML và XPath được phân tích cú pháp để tránh các yêu cầu mạng không cần thiết và chi phí phân tích cú pháp. Bạn có thể sử dụng một từ điển đơn giản hoặc một giải pháp mạnh mẽ hơn như MongoDB hoặc Redis để lưu vào bộ đệm.

Kết luận

XPath là một công cụ cực kỳ mạnh mẽ để trích xuất chính xác dữ liệu từ các trang HTML. Với hiểu biết cơ bản về cú pháp và khả năng dịch các bộ chọn CSS sang tương đương XPath của chúng, bạn có thể xử lý nhiều tác vụ quét web khác nhau.

Các thư viện Python như lxml, BeautifulSoup và Selenium cung cấp những cách dễ dàng để tích hợp XPath vào quy trình thu thập dữ liệu của bạn. Tùy thuộc vào nhu cầu cụ thể của bạn và đặc điểm của trang web mục tiêu, bạn có thể chọn phương pháp phù hợp nhất.

Khi bạn tiếp tục hành trình quét web của mình bằng Python và XPath, hãy luôn đảm bảo tôn trọng các điều khoản dịch vụ của trang web và các hạn chế về robots.txt. Và hãy nhớ ôn lại các nguyên tắc cơ bản của các hàm và toán tử XPath - bạn sẽ ngạc nhiên về mức độ bạn có thể đạt được chỉ với một vài dòng XPath thông minh!

Tham gia vào cuộc đối thoại

Chúng tôi sẽ không công khai email của bạn. Các ô đánh dấu * là bắt buộc *