2009-03-02 39 views
16

Tôi là người mới sử dụng python và tôi cần trợ giúp về cú pháp để tìm và lặp qua thẻ html bằng cách sử dụng lxml. Dưới đây là các trường hợp sử dụng mà tôi đang xử lý:Cần trợ giúp cú pháp python lxml để phân tích cú pháp html

Tệp HTML được định dạng khá tốt (nhưng không hoàn hảo). Có nhiều bảng trên màn hình, một bảng chứa một tập hợp các kết quả tìm kiếm và một bảng cho đầu trang và chân trang. Mỗi hàng kết quả chứa một liên kết cho chi tiết kết quả tìm kiếm.

  1. tôi cần phải tìm bảng giữa với các hàng kết quả tìm kiếm (cái này tôi đã có thể tìm ra):

    self.mySearchTables = self.mySearchTree.findall(".//table") 
        self.myResultRows = self.mySearchTables[1].findall(".//tr") 
    
  2. tôi cần phải tìm các liên kết chứa trong bảng này (điều này là nơi tôi bị kẹt):

    for searchRow in self.myResultRows: 
         searchLink = patentRow.findall(".//a") 
    

    Nó dường như không thực sự xác định được các yếu tố liên kết.

  3. Tôi cần văn bản thuần túy của liên kết. Tôi tưởng tượng nó sẽ là một cái gì đó như searchLink.text nếu tôi thực sự có các yếu tố liên kết ở nơi đầu tiên.

Cuối cùng, trong tham chiếu API thực tế cho lxml, tôi không thể tìm thấy thông tin về tìm kiếm và cuộc gọi tìm kiếm. Tôi lượm lặt những thứ này từ những mã tôi tìm thấy trên google. Tôi có thiếu một cái gì đó về làm thế nào để có hiệu quả tìm và lặp qua các thẻ HTML bằng cách sử dụng lxml?

Trả lời

27

Được rồi, trước tiên, liên quan đến phân tích cú pháp HTML: nếu bạn làm theo đề xuất của zweiterlinde và S.Lott ít nhất hãy sử dụng phiên bản beautifulsoup included with lxml. Bằng cách đó bạn cũng sẽ gặt hái được lợi ích của giao diện bộ chọn xpath hoặc css đẹp.

Tuy nhiên, cá nhân tôi thích Ian Bicking's HTML parser included in lxml.

Thứ hai, .find().findall() đến từ lxml cố gắng tương thích với ElementTree và hai phương pháp này được mô tả trong XPath Support in ElementTree.

Hai chức năng này khá dễ sử dụng nhưng chúng rất hạn chế XPath. Tôi khuyên bạn nên cố gắng sử dụng toàn bộ lxml xpath() method hoặc nếu bạn đã quen với CSS, sử dụng cssselect() method.

Dưới đây là một số ví dụ, với một chuỗi HTML phân tích như thế này:

from lxml.html import fromstring 
mySearchTree = fromstring(your_input_string) 

Sử dụng lớp css selector chương trình của bạn xấp xỉ sẽ giống như thế này:

# Find all 'a' elements inside 'tr' table rows with css selector 
for a in mySearchTree.cssselect('tr a'): 
    print 'found "%s" link to href "%s"' % (a.text, a.get('href')) 

Tương đương sử dụng phương pháp xpath sẽ là:

# Find all 'a' elements inside 'tr' table rows with xpath 
for a in mySearchTree.xpath('.//tr/*/a'): 
    print 'found "%s" link to href "%s"' % (a.text, a.get('href')) 
+0

Yay! Đúng thứ tôi cần. Tôi giải thích cssselect để thực sự yêu cầu các phần tử để có một lớp css đã khai báo. Logic tìm kiếm lồng nhau chỉ là những gì tôi cần! Cảm ơn bạn Van Gale! –

+0

Trang này khuyên bạn nên sử dụng iterchildren và iterdescendants với tùy chọn thẻ. http://www.ibm.com/developerworks/xml/library/x-hiperfparse/#N10239 – endolith

+1

Câu trả lời hay, nhưng là một câu hỏi nhỏ - tại sao '.// tr/*/a' thay vì' .// tr // a'? Các cựu sẽ không tìm thấy bất cứ điều gì với một thẻ intervening thêm, tức là. '..' –

5

Có lý do nào bạn không sử dụng Beautiful Soup cho dự án này không? Nó sẽ làm cho giao dịch với các tài liệu được hình thành hoàn hảo dễ dàng hơn nhiều.

+0

+1: lxml là dành cho xml. Beautiful Soup là dành cho HTML. –

+2

Tôi bắt đầu với Beautiful Soup, nhưng tôi không có may mắn. Tôi đã đề cập trong câu hỏi của mình rằng tài liệu của tôi khá hợp lý, nhưng nó thiếu khối nội dung kết thúc.Nó chỉ đơn giản là giảm tất cả nội dung khi tôi kéo nó vào trình phân tích cú pháp. Do đó lxml. Ngoài ra, http://tinyurl.com/37u9gu chỉ ra memm mem tốt hơn với lxml –

+7

Tôi đã sử dụng BeautifulSoup lúc đầu, nhưng nó không xử lý HTML xấu cũng như nó tuyên bố. Nó cũng không hỗ trợ các mục có nhiều lớp, vv lxml.html là tốt hơn cho mọi thứ tôi đã làm với nó. – endolith

Các vấn đề liên quan