Làm cách nào để phân tích HTML / XML và trích xuất thông tin từ nó?
Làm cách nào để phân tích HTML / XML và trích xuất thông tin từ nó?
Câu trả lời:
Tôi thích sử dụng một trong các phần mở rộng XML nguyên gốc vì chúng đi kèm với PHP, thường nhanh hơn tất cả các lib của bên thứ 3 và cung cấp cho tôi tất cả quyền kiểm soát tôi cần khi đánh dấu.
Tiện ích mở rộng DOM cho phép bạn vận hành trên các tài liệu XML thông qua API DOM với PHP 5. Đây là một triển khai của Mô hình đối tượng tài liệu cấp 3 của W3C, giao diện trung lập về ngôn ngữ và nền tảng cho phép các chương trình và tập lệnh tự động truy cập và cập nhật nội dung, cấu trúc và phong cách của tài liệu.
DOM có khả năng phân tích cú pháp và sửa đổi HTML thế giới thực (bị hỏng) và nó có thể thực hiện các truy vấn XPath . Nó dựa trên libxml .
Phải mất một thời gian để làm việc hiệu quả với DOM, nhưng thời gian đó rất đáng để IMO. Vì DOM là giao diện không biết ngôn ngữ, bạn sẽ tìm thấy các triển khai bằng nhiều ngôn ngữ, vì vậy nếu bạn cần thay đổi ngôn ngữ lập trình của mình, rất có thể bạn sẽ biết cách sử dụng API DOM của ngôn ngữ đó.
Có thể tìm thấy một ví dụ sử dụng cơ bản trong Lấy thuộc tính href của phần tử A và tổng quan về khái niệm chung có thể được tìm thấy tại DOMDocument trong php
Cách sử dụng tiện ích mở rộng DOM đã được trình bày rộng rãi trên StackOverflow , vì vậy nếu bạn chọn sử dụng nó, bạn có thể chắc chắn rằng hầu hết các vấn đề bạn gặp phải có thể được giải quyết bằng cách tìm kiếm / duyệt Stack Overflow.
Phần mở rộng XMLReader là một trình phân tích cú pháp kéo XML. Trình đọc hoạt động như một con trỏ đi về phía trước trên luồng tài liệu và dừng lại ở mỗi nút trên đường đi.
XMLReader, như DOM, dựa trên libxml. Tôi không biết làm thế nào để kích hoạt Mô-đun phân tích cú pháp HTML, do đó, rất có thể việc sử dụng XMLReader để phân tích cú pháp HTML bị hỏng có thể kém mạnh mẽ hơn so với sử dụng DOM nơi bạn có thể nói rõ ràng để sử dụng Mô-đun phân tích HTML của libxml.
Một ví dụ sử dụng cơ bản có thể được tìm thấy khi nhận tất cả các giá trị từ các thẻ h1 bằng cách sử dụng php
Tiện ích mở rộng này cho phép bạn tạo các trình phân tích cú pháp XML và sau đó xác định các trình xử lý cho các sự kiện XML khác nhau. Mỗi trình phân tích cú pháp XML cũng có một vài tham số bạn có thể điều chỉnh.
Thư viện XML Parser cũng dựa trên libxml và triển khai trình phân tích cú pháp đẩy XML kiểu SAX . Nó có thể là một lựa chọn tốt hơn để quản lý bộ nhớ so với DOM hoặc SimpleXML, nhưng sẽ khó làm việc hơn so với trình phân tích cú pháp kéo do XMLReader triển khai.
Phần mở rộng SimpleXML cung cấp một bộ công cụ rất đơn giản và dễ sử dụng để chuyển đổi XML thành một đối tượng có thể được xử lý bằng các bộ chọn thuộc tính thông thường và các trình vòng lặp mảng.
SimpleXML là một tùy chọn khi bạn biết HTML là XHTML hợp lệ. Nếu bạn cần phân tích HTML bị hỏng, thậm chí đừng xem xét SimpleXml vì nó sẽ bị sặc.
Một ví dụ sử dụng cơ bản có thể được tìm thấy tại Một chương trình đơn giản cho nút CRUD và các giá trị nút của tệp xml và có rất nhiều ví dụ bổ sung trong Hướng dẫn PHP .
Nếu bạn thích sử dụng lib của bên thứ 3, tôi khuyên bạn nên sử dụng lib thực sự sử dụng DOM / libxml bên dưới thay vì phân tích chuỗi.
FluentDOM cung cấp giao diện XML thông thạo giống như jQuery cho DOMDocument trong PHP. Các bộ chọn được viết bằng XPath hoặc CSS (sử dụng trình chuyển đổi CSS sang XPath). Các phiên bản hiện tại mở rộng DOM thực hiện các giao diện tiêu chuẩn và thêm các tính năng từ DOM Living Standard. FluentDOM có thể tải các định dạng như JSON, CSV, JsonML, RabbitFish và các định dạng khác. Có thể được cài đặt thông qua Trình soạn thảo.
Wa72 \ HtmlPageDom` là một thư viện PHP để dễ dàng thao tác các tài liệu HTML bằng cách sử dụng Nó yêu cầu DomCrawler từ các thành phần Symfony2 để duyệt qua cây DOM và mở rộng nó bằng cách thêm các phương thức để xử lý cây DOM của tài liệu HTML.
phpQuery là API Mô hình đối tượng tài liệu (DOM) được điều khiển bởi bộ chọn CSS3 phía máy chủ, dựa trên thư viện jQuery JavaScript được viết bằng PHP5 và cung cấp thêm Giao diện dòng lệnh (CLI).
Xem thêm: https://github.com/electrolinux/phpquery
Zend_Dom cung cấp các công cụ để làm việc với các tài liệu và cấu trúc DOM. Hiện tại, chúng tôi cung cấp Zend_Dom_Query, cung cấp giao diện hợp nhất để truy vấn các tài liệu DOM sử dụng cả bộ chọn XPath và CSS.
QueryPath là một thư viện PHP để thao tác XML và HTML. Nó được thiết kế để hoạt động không chỉ với các tệp cục bộ mà còn với các dịch vụ web và tài nguyên cơ sở dữ liệu. Nó thực hiện phần lớn giao diện jQuery (bao gồm các bộ chọn kiểu CSS), nhưng nó được điều chỉnh nhiều để sử dụng phía máy chủ. Có thể được cài đặt thông qua Trình soạn thảo.
fDOMDocument mở rộng DOM tiêu chuẩn để sử dụng các ngoại lệ tại mọi trường hợp xảy ra lỗi thay vì cảnh báo hoặc thông báo PHP. Họ cũng thêm các phương thức và lối tắt tùy chỉnh khác nhau để thuận tiện và để đơn giản hóa việc sử dụng DOM.
saber / xml là một thư viện bao bọc và mở rộng các lớp XMLReader và XMLWriter để tạo ra một hệ thống ánh xạ và mẫu thiết kế "xml to object / Array" đơn giản. Viết và đọc XML là một lần và do đó có thể nhanh và yêu cầu bộ nhớ thấp trên các tệp xml lớn.
FluidXML là một thư viện PHP để thao tác XML với API ngắn gọn và trôi chảy. Nó thúc đẩy XPath và mô hình lập trình trôi chảy trở nên thú vị và hiệu quả.
Lợi ích của việc xây dựng dựa trên DOM / libxml là bạn có được hiệu suất tốt do bạn dựa trên tiện ích mở rộng riêng. Tuy nhiên, không phải tất cả các lib của bên thứ 3 đều đi theo tuyến đường này. Một số trong số họ được liệt kê dưới đây
- Trình phân tích cú pháp DOM DOM được viết bằng PHP5 + cho phép bạn thao tác HTML một cách rất dễ dàng!
- Yêu cầu PHP 5+.
- Hỗ trợ HTML không hợp lệ.
- Tìm thẻ trên trang HTML với các bộ chọn giống như jQuery.
- Trích xuất nội dung từ HTML trong một dòng duy nhất.
Tôi thường không đề xuất trình phân tích cú pháp này. Codebase là khủng khiếp và bản thân trình phân tích cú pháp khá chậm và đói bộ nhớ. Không phải tất cả các Bộ chọn jQuery (như bộ chọn con ) đều có thể. Bất kỳ thư viện dựa trên libxml nên dễ dàng vượt qua điều này.
PHPHtmlParser là một trình phân tích cú pháp html đơn giản, linh hoạt, cho phép bạn chọn các thẻ bằng bất kỳ bộ chọn css nào, như jQuery. Mục tiêu là hỗ trợ phát triển các công cụ đòi hỏi một cách nhanh chóng, dễ dàng để loại bỏ html, cho dù nó có hợp lệ hay không! Dự án này ban đầu được hỗ trợ bởi sunra / php-simple-html-dom-Parser nhưng sự hỗ trợ dường như đã dừng lại vì vậy dự án này là sự điều chỉnh của tôi cho công việc trước đây của anh ấy.
Một lần nữa, tôi sẽ không đề xuất trình phân tích cú pháp này. Nó khá chậm với việc sử dụng CPU cao. Cũng không có chức năng xóa bộ nhớ của các đối tượng DOM đã tạo. Những vấn đề quy mô đặc biệt với các vòng lặp lồng nhau. Bản thân tài liệu này không chính xác và sai chính tả, không có phản hồi cho các bản sửa lỗi kể từ ngày 14 tháng 4.
- Trình mã thông báo phổ biến và Trình phân tích cú pháp HTML / XML / RSS DOM
- Khả năng thao tác các yếu tố và thuộc tính của chúng
- Hỗ trợ HTML và UTF8 không hợp lệ
- Có thể thực hiện các truy vấn giống CSS3 nâng cao trên các phần tử (như jQuery - không gian tên được hỗ trợ)
- Trình làm đẹp HTML (như HTML Tidy)
- Giảm thiểu CSS và Javascript
- Sắp xếp các thuộc tính, thay đổi trường hợp ký tự, thụt lề chính xác, v.v.
- Mở rộng
- Phân tích tài liệu bằng cách sử dụng các cuộc gọi lại dựa trên ký tự / mã thông báo hiện tại
- Các hoạt động được phân tách trong các chức năng nhỏ hơn để dễ dàng ghi đè
- Nhanh và dễ
Không bao giờ sử dụng nó. Không thể biết nó có tốt không.
Bạn có thể sử dụng cách trên để phân tích cú pháp HTML5, nhưng có thể có những điều kỳ quặc do đánh dấu mà HTML5 cho phép. Vì vậy, đối với HTML5, bạn muốn xem xét sử dụng trình phân tích cú pháp chuyên dụng, như
Một triển khai Python và PHP của trình phân tích cú pháp HTML dựa trên đặc tả HTML5 của WHATWG để tương thích tối đa với các trình duyệt web trên máy tính để bàn chính.
Chúng ta có thể thấy các trình phân tích cú pháp chuyên dụng hơn sau khi HTML5 được hoàn thành. Ngoài ra còn có một blogpost bởi W3 có tiêu đề Cách phân tích cú pháp html 5 đáng để kiểm tra.
Nếu bạn không thích lập trình PHP, bạn cũng có thể sử dụng các dịch vụ Web. Nói chung, tôi tìm thấy rất ít tiện ích cho những thứ này, nhưng đó chỉ là tôi và các trường hợp sử dụng của tôi.
Giao diện bên ngoài của ScraperWiki cho phép bạn trích xuất dữ liệu ở dạng bạn muốn sử dụng trên web hoặc trong các ứng dụng của riêng bạn. Bạn cũng có thể trích xuất thông tin về trạng thái của bất kỳ dụng cụ cạo nào.
Cuối cùng và ít nhất được đề xuất , bạn có thể trích xuất dữ liệu từ HTML bằng các biểu thức thông thường . Nói chung, việc sử dụng Biểu thức chính quy trên HTML không được khuyến khích.
Hầu hết các đoạn bạn sẽ tìm thấy trên web để khớp với đánh dấu là dễ vỡ. Trong hầu hết các trường hợp, họ chỉ làm việc cho một đoạn HTML rất đặc biệt. Thay đổi đánh dấu nhỏ, như thêm khoảng trắng ở đâu đó hoặc thêm hoặc thay đổi thuộc tính trong thẻ, có thể khiến RegEx không thành công khi không được viết đúng. Bạn nên biết những gì bạn đang làm trước khi sử dụng RegEx trên HTML.
Các trình phân tích cú pháp HTML đã biết các quy tắc cú pháp của HTML. Các biểu thức thông thường phải được dạy cho mỗi RegEx mới mà bạn viết. RegEx vẫn ổn trong một số trường hợp, nhưng nó thực sự phụ thuộc vào trường hợp sử dụng của bạn.
Bạn có thể viết các trình phân tích cú pháp đáng tin cậy hơn , nhưng viết một trình phân tích cú pháp tùy chỉnh đầy đủ và đáng tin cậy với các biểu thức thông thường là một sự lãng phí thời gian khi các thư viện nói trên đã tồn tại và thực hiện công việc này tốt hơn nhiều.
Cũng xem Phân tích cú pháp Html Cách Cthulhu
Nếu bạn muốn chi tiêu một số tiền, hãy xem
Tôi không liên kết với Kiến trúc sư PHP hoặc các tác giả.
Hãy thử Trình phân tích cú pháp DOM HTML đơn giản
// Create DOM from URL or file
$html = file_get_html('http://www.example.com/');
// Find all images
foreach($html->find('img') as $element)
echo $element->src . '<br>';
// Find all links
foreach($html->find('a') as $element)
echo $element->href . '<br>';
// Create DOM from string
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');
$html->find('div', 1)->class = 'bar';
$html->find('div[id=hello]', 0)->innertext = 'foo';
echo $html;
// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;
// Create DOM from URL
$html = file_get_html('http://slashdot.org/');
// Find all article blocks
foreach($html->find('div.article') as $article) {
$item['title'] = $article->find('div.title', 0)->plaintext;
$item['intro'] = $article->find('div.intro', 0)->plaintext;
$item['details'] = $article->find('div.details', 0)->plaintext;
$articles[] = $item;
}
print_r($articles);
Chỉ cần sử dụng DOMDocument-> loadHTML () và được thực hiện với nó. Thuật toán phân tích HTML của libxml khá tốt và nhanh, và trái với niềm tin phổ biến, không gây nghẹt thở cho HTML không đúng định dạng.
Tại sao bạn không nên và khi nào bạn nên sử dụng biểu thức thông thường?
Trước hết, một cách hiểu sai phổ biến: Regexps không dành cho " phân tích cú pháp " HTML. Regexes tuy nhiên có thể " trích xuất " dữ liệu. Trích xuất là những gì họ làm cho. Hạn chế chính của việc trích xuất HTML regex so với các bộ công cụ SGML hoặc trình phân tích cú pháp XML cơ bản là nỗ lực cú pháp của chúng và độ tin cậy khác nhau.
Hãy xem xét việc tạo một biểu thức trích xuất HTML có phần đáng tin cậy:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
là cách dễ đọc hơn so với tương đương phpQuery hoặc QueryPath đơn giản:
$div->find(".stationcool a")->attr("title");
Tuy nhiên, có những trường hợp sử dụng cụ thể mà họ có thể giúp đỡ.
<!--
, đôi khi là các neo hữu ích hơn để trích xuất. Trong các biến thể giả HTML cụ thể <$var>
hoặc dư lượng SGML rất dễ thuần hóa bằng biểu thức chính quy.Đôi khi, thậm chí nên trích xuất trước một đoạn mã HTML bằng cách sử dụng các biểu thức thông thường /<!--CONTENT-->(.+?)<!--END-->/
và xử lý phần còn lại bằng cách sử dụng trình phân tích cú pháp HTML đơn giản hơn.
Lưu ý: Tôi thực sự có ứng dụng này , nơi tôi sử dụng phân tích cú pháp XML và các biểu thức thông thường thay thế. Mới tuần trước, phân tích cú pháp PyQuery đã bị hỏng và regex vẫn hoạt động. Vâng, và tôi không thể tự giải thích nó. Nhưng nó đã xảy ra.
Vì vậy, vui lòng không bỏ phiếu cân nhắc trong thế giới thực, chỉ vì nó không phù hợp với regex = meme ác. Nhưng chúng ta cũng đừng bỏ phiếu này quá nhiều. Nó chỉ là một sidenote cho chủ đề này.
DOMComment
có thể đọc bình luận, vì vậy không có lý do để sử dụng Regex cho điều đó.
DOM
sử dụng libxml và libxml có một mô-đun trình phân tích cú pháp HTML riêng biệt sẽ được sử dụng khi tải HTML loadHTML()
để có thể tải HTML "thế giới thực" (đọc bị hỏng) rất nhiều.
phpQuery và QueryPath cực kỳ giống nhau trong việc sao chép API jQuery trôi chảy. Đó cũng là lý do tại sao chúng là hai trong những cách tiếp cận dễ nhất để phân tích HTML đúng trong PHP.
Ví dụ cho QueryPath
Về cơ bản, trước tiên bạn tạo một cây DOM có thể truy vấn từ một chuỗi HTML:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
Đối tượng kết quả chứa một biểu diễn cây hoàn chỉnh của tài liệu HTML. Nó có thể được duyệt qua các phương thức DOM. Nhưng cách tiếp cận phổ biến là sử dụng các bộ chọn CSS như trong jQuery:
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
Chủ yếu là bạn muốn sử dụng đơn giản #id
và .class
hoặc DIV
bộ chọn thẻ cho ->find()
. Nhưng bạn cũng có thể sử dụng các câu lệnh XPath , đôi khi nhanh hơn. Ngoài ra phương pháp jQuery điển hình như ->children()
và ->text()
và đặc biệt là ->attr()
đơn giản hóa việc giải nén các đoạn mã HTML ngay. (Và đã giải mã các thực thể SGML của chúng.)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath cũng cho phép chèn các thẻ mới vào luồng ( ->append
) và sau đó xuất ra và sắp xếp lại một tài liệu cập nhật ( ->writeHTML
). Nó không chỉ có thể phân tích cú pháp HTML không đúng định dạng mà còn cả các phương ngữ XML khác nhau (có không gian tên) và thậm chí trích xuất dữ liệu từ các vi định dạng HTML (XFN, vCard).
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
.
phpQuery hay QueryPath?
Nói chung QueryPath phù hợp hơn cho việc thao tác với các tài liệu. Trong khi phpQuery cũng triển khai một số phương thức AJAX giả (chỉ yêu cầu HTTP) để gần giống với jQuery hơn. Người ta nói rằng phpQuery thường nhanh hơn QueryPath (vì ít tính năng tổng thể hơn).
Để biết thêm thông tin về sự khác biệt, hãy xem so sánh này trên máy wayback từ tagbyte.org . (Nguồn gốc bị mất, vì vậy đây là một liên kết lưu trữ internet. Có, bạn vẫn có thể xác định vị trí các trang bị thiếu, mọi người.)
Và đây là phần giới thiệu QueryPath toàn diện .
Ưu điểm
->find("a img, a object, div a")
DOM HTML đơn giản là một trình phân tích cú pháp nguồn mở tuyệt vời:
Nó xử lý các phần tử DOM theo cách hướng đối tượng và phép lặp mới có nhiều phạm vi bảo hiểm cho mã không tuân thủ. Ngoài ra còn có một số chức năng tuyệt vời như bạn thấy trong JavaScript, chẳng hạn như chức năng "tìm", sẽ trả về tất cả các phiên bản của các thành phần của tên thẻ đó.
Tôi đã sử dụng công cụ này trong một số công cụ, thử nghiệm nó trên nhiều loại trang web khác nhau và tôi nghĩ rằng nó hoạt động rất tốt.
Một cách tiếp cận chung mà tôi chưa thấy được đề cập ở đây là chạy HTML thông qua Tidy , có thể được thiết lập để nhổ XHTML có hiệu lực được bảo đảm. Sau đó, bạn có thể sử dụng bất kỳ thư viện XML cũ nào trên đó.
Nhưng đối với vấn đề cụ thể của bạn, bạn nên xem dự án này: http://fivefilters.org/content-only/ - đây là phiên bản sửa đổi của thuật toán Readability , được thiết kế để chỉ trích xuất nội dung văn bản (không phải tiêu đề và chân trang) từ một trang.
Trong 1a và 2: Tôi sẽ bỏ phiếu cho lớp Symfony WIFIet mới DOMCrawler ( DomCrawler ). Lớp này cho phép các truy vấn tương tự như Bộ chọn CSS. Hãy xem bài trình bày này để biết các ví dụ trong thế giới thực: news-of-the-symfony2-world .
Thành phần này được thiết kế để hoạt động độc lập và có thể được sử dụng mà không cần Symfony.
Hạn chế duy nhất là nó sẽ chỉ hoạt động với PHP 5.3 hoặc mới hơn.
Nhân tiện, điều này thường được gọi là cào màn hình . Thư viện tôi đã sử dụng cho việc này là Simple HTML Dom Parser .
Chúng tôi đã tạo ra một vài trình thu thập thông tin cho nhu cầu của chúng tôi trước đây. Vào cuối ngày, thường là các biểu thức chính quy đơn giản làm điều tốt nhất. Mặc dù các thư viện được liệt kê ở trên tốt cho lý do chúng được tạo, nhưng nếu bạn biết bạn đang tìm kiếm gì, các biểu thức chính quy là cách an toàn hơn, vì bạn có thể xử lý cả các cấu trúc HTML / XHTML không hợp lệ , nếu bị tải thông qua hầu hết các trình phân tích cú pháp.
Tôi khuyên dùng PHP Pars HTML DOM Parser .
Nó thực sự có các tính năng tốt, như:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
Điều này nghe có vẻ như là một mô tả nhiệm vụ tốt của công nghệ W3C XPath . Thật dễ dàng để thể hiện các truy vấn như "trả lại tất cả các href
thuộc tính trong img
các thẻ được lồng vào <foo><bar><baz> elements
." Không phải là một người dùng PHP, tôi không thể nói cho bạn biết XPath ở dạng nào có thể có sẵn. Nếu bạn có thể gọi một chương trình bên ngoài để xử lý tệp HTML, bạn sẽ có thể sử dụng phiên bản dòng lệnh của XPath. Để có phần giới thiệu nhanh, hãy xem http://en.wikipedia.org/wiki/XPath .
Có, bạn có thể sử dụng Simple_html_dom cho mục đích này. Tuy nhiên, tôi đã làm việc khá nhiều với Simple_html_dom, đặc biệt đối với việc loại bỏ web và nhận thấy nó quá dễ bị tấn công. Nó làm công việc cơ bản nhưng tôi sẽ không đề xuất dù sao đi nữa.
Tôi chưa bao giờ sử dụng curl cho mục đích nhưng những gì tôi đã học được là curl có thể thực hiện công việc hiệu quả hơn và vững chắc hơn nhiều.
Vui lòng kiểm tra liên kết này: scraping-website-with-curl
QueryPath là tốt, nhưng hãy cẩn thận với "trạng thái theo dõi" nếu bạn không nhận ra ý nghĩa của nó, điều đó có nghĩa là bạn lãng phí rất nhiều thời gian gỡ lỗi để cố gắng tìm hiểu điều gì đã xảy ra và tại sao mã không hoạt động.
Điều đó có nghĩa là mỗi cuộc gọi trên tập kết quả sẽ sửa đổi tập kết quả trong đối tượng, nó không thể kết nối được như trong jquery trong đó mỗi liên kết là một tập hợp mới, bạn có một tập hợp là kết quả từ truy vấn của bạn và mỗi lệnh gọi hàm sẽ sửa đổi bộ đơn đó.
để có được hành vi giống như jquery, bạn cần phân nhánh trước khi thực hiện bộ lọc / sửa đổi như thao tác, điều đó có nghĩa là nó sẽ phản ánh những gì xảy ra trong jquery chặt chẽ hơn nhiều.
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
bây giờ chứa kết quả được đặt cho input[name='forename']
KHÔNG phải truy vấn ban đầu, "div p"
điều này làm tôi vấp ngã rất nhiều, điều tôi tìm thấy là QueryPath theo dõi các bộ lọc và tìm và mọi thứ điều chỉnh kết quả của bạn và lưu trữ chúng trong đối tượng. bạn cần phải làm điều này thay vào đó
$forename = $results->branch()->find("input[name='forname']")
sau đó $results
sẽ không được sửa đổi và bạn có thể sử dụng lại kết quả được đặt lại, có lẽ ai đó có nhiều kiến thức hơn có thể làm rõ điều này một chút, nhưng về cơ bản nó giống như thế này từ những gì tôi đã tìm thấy.
Advanced Html Dom là một thay thế DOM HTML đơn giản cung cấp cùng một giao diện, nhưng nó dựa trên DOM, điều đó có nghĩa là không có vấn đề bộ nhớ liên quan nào xảy ra.
Nó cũng có hỗ trợ CSS đầy đủ, bao gồm các phần mở rộng jQuery .
Tôi đã viết một trình phân tích cú pháp XML có mục đích chung có thể dễ dàng xử lý các tệp GB. Nó dựa trên XMLReader và nó rất dễ sử dụng:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
Đây là repo github: XmlExtractor
Tôi đã tạo một thư viện có tên PHPPowertools / DOM-Query , cho phép bạn thu thập dữ liệu các tài liệu HTML5 và XML giống như bạn làm với jQuery.
Trong phần mềm này, nó sử dụng symfony / DomCrawler để chuyển đổi các bộ chọn CSS sang bộ chọn XPath . Nó luôn sử dụng cùng một DomDocument, ngay cả khi truyền một đối tượng này sang đối tượng khác, để đảm bảo hiệu suất tốt.
namespace PowerTools;
// Get file content
$htmlcode = file_get_contents('https://github.com');
// Define your DOMCrawler based on file string
$H = new DOM_Query($htmlcode);
// Define your DOMCrawler based on an existing DOM_Query instance
$H = new DOM_Query($H->select('body'));
// Passing a string (CSS selector)
$s = $H->select('div.foo');
// Passing an element object (DOM Element)
$s = $H->select($documentBody);
// Passing a DOM Query object
$s = $H->select( $H->select('p + p'));
// Select the body tag
$body = $H->select('body');
// Combine different classes as one selector to get all site blocks
$siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer');
// Nest your methods just like you would with jQuery
$siteblocks->select('button')->add('span')->addClass('icon icon-printer');
// Use a lambda function to set the text of all site blocks
$siteblocks->text(function( $i, $val) {
return $i . " - " . $val->attr('class');
});
// Append the following HTML to all site blocks
$siteblocks->append('<div class="site-center"></div>');
// Use a descendant selector to select the site's footer
$sitefooter = $body->select('.site-footer > .site-center');
// Set some attributes for the site's footer
$sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see'));
// Use a lambda function to set the attributes of all site blocks
$siteblocks->attr('data-val', function( $i, $val) {
return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
});
// Select the parent of the site's footer
$sitefooterparent = $sitefooter->parent();
// Remove the class of all i-tags within the site's footer's parent
$sitefooterparent->select('i')->removeAttr('class');
// Wrap the site's footer within two nex selectors
$sitefooter->wrap('<section><div class="footer-wrapper"></div></section>');
[...]
Thư viện cũng bao gồm trình tải tự động cấu hình không của riêng nó cho các thư viện tương thích PSR-0. Ví dụ bao gồm sẽ hoạt động ngoài hộp mà không có bất kỳ cấu hình bổ sung. Ngoài ra, bạn có thể sử dụng nó với nhà soạn nhạc.
XML_HTMLSax
là khá ổn định - ngay cả khi nó không được duy trì nữa. Một tùy chọn khác có thể dẫn bạn HTML qua Html Tidy và sau đó phân tích nó bằng các công cụ XML tiêu chuẩn.
Có nhiều cách để xử lý HTML / XML DOM mà hầu hết đã được đề cập. Do đó, tôi sẽ không thực hiện bất kỳ nỗ lực nào để liệt kê những bản thân mình.
Tôi chỉ muốn thêm rằng cá nhân tôi thích sử dụng tiện ích mở rộng DOM và tại sao:
Và trong khi tôi bỏ lỡ khả năng sử dụng các bộ chọn CSS DOMDocument
, thì có một cách khá đơn giản và thuận tiện để thêm tính năng này: phân lớp DOMDocument
và thêm giống như JS querySelectorAll
vàquerySelector
phương thức vào lớp con của bạn.
Để phân tích cú pháp các bộ chọn, tôi khuyên bạn nên sử dụng thành phần CssSelector rất tối giản từ khung Symfony . Thành phần này chỉ dịch các bộ chọn CSS sang bộ chọn XPath, sau đó có thể được đưa vào mộtDOMXpath
để lấy Nodelist tương ứng.
Sau đó, bạn có thể sử dụng lớp con này (vẫn ở mức rất thấp) làm nền tảng cho các lớp cấp cao hơn, dự định là ví dụ. phân tích các loại XML rất cụ thể hoặc thêm nhiều hành vi giống jQuery.
Mã dưới đây đi thẳng ra thư viện DOM-Query của tôi và sử dụng kỹ thuật tôi đã mô tả.
Để phân tích cú pháp HTML:
namespace PowerTools;
use \Symfony\Component\CssSelector\CssSelector as CssSelector;
class DOM_Document extends \DOMDocument {
public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') {
parent::__construct($version, $encoding);
if ($doctype && $doctype === 'html') {
@$this->loadHTML($data);
} else {
@$this->loadXML($data);
}
}
public function querySelectorAll($selector, $contextnode = null) {
if (isset($this->doctype->name) && $this->doctype->name == 'html') {
CssSelector::enableHtmlExtension();
} else {
CssSelector::disableHtmlExtension();
}
$xpath = new \DOMXpath($this);
return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode);
}
[...]
public function loadHTMLFile($filename, $options = 0) {
$this->loadHTML(file_get_contents($filename), $options);
}
public function loadHTML($source, $options = 0) {
if ($source && $source != '') {
$data = trim($source);
$html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true));
$data_start = mb_substr($data, 0, 10);
if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) {
$html5->loadHTML($data);
} else {
@$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>');
$t = $html5->loadHTMLFragment($data);
$docbody = $this->getElementsByTagName('body')->item(0);
while ($t->hasChildNodes()) {
$docbody->appendChild($t->firstChild);
}
}
}
}
[...]
}
Xem thêm Phân tích tài liệu XML bằng bộ chọn CSS của người sáng tạo Symfony Fabien Potencier về quyết định tạo thành phần CssSelector cho Symfony và cách sử dụng nó.
Với FluidXML, bạn có thể truy vấn và lặp lại XML bằng cách sử dụng XPath và CSS Selector .
$doc = fluidxml('<html>...</html>');
$title = $doc->query('//head/title')[0]->nodeValue;
$doc->query('//body/p', 'div.active', '#bgId')
->each(function($i, $node) {
// $node is a DOMNode.
$tag = $node->nodeName;
$text = $node->nodeValue;
$class = $node->getAttribute('class');
});
JSON và mảng từ XML trong ba dòng:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Ta da!
Có một số lý do để không phân tích HTML bằng biểu thức chính quy. Nhưng, nếu bạn có toàn quyền kiểm soát HTML nào sẽ được tạo, thì bạn có thể thực hiện với biểu thức chính quy đơn giản.
Trên đây là một chức năng phân tích cú pháp HTML bằng biểu thức chính quy. Lưu ý rằng chức năng này rất nhạy cảm và yêu cầu HTML tuân theo các quy tắc nhất định, nhưng nó hoạt động rất tốt trong nhiều tình huống. Nếu bạn muốn một trình phân tích cú pháp đơn giản và không muốn cài đặt thư viện, hãy thử cách này:
function array_combine_($keys, $values) {
$result = array();
foreach ($keys as $i => $k) {
$result[$k][] = $values[$i];
}
array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));
return $result;
}
function extract_data($str) {
return (is_array($str))
? array_map('extract_data', $str)
: ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</\1>#s', $str, $matches))
? $str
: array_map(('extract_data'), array_combine_($matches[1], $matches[2])));
}
print_r(extract_data(file_get_contents("http://www.google.com/")));
Tôi đã tạo một thư viện có tên HTML5DOMDocument có sẵn miễn phí tại https://github.com/ivopetkov/html5-dom-document-php
Nó cũng hỗ trợ các bộ chọn truy vấn mà tôi nghĩ sẽ cực kỳ hữu ích trong trường hợp của bạn. Dưới đây là một số mã ví dụ:
$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;
Nếu bạn quen thuộc với bộ chọn jQuery, bạn có thể sử dụng ScarletsQuery cho PHP
<pre><?php
include "ScarletsQuery.php";
// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);
// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];
// Get 'content' attribute value from meta tag
print_r($description->attr('content'));
$description = $dom->selector('#Content p');
// Get element array
print_r($description->view);
Thư viện này thường mất ít hơn 1 giây để xử lý html ngoại tuyến.
Nó cũng chấp nhận HTML không hợp lệ hoặc thiếu trích dẫn về các thuộc tính thẻ.
Phương pháp tốt nhất cho phân tích xml:
$xml='http://www.example.com/rss.xml';
$rss = simplexml_load_string($xml);
$i = 0;
foreach ($rss->channel->item as $feedItem) {
$i++;
echo $title=$feedItem->title;
echo '<br>';
echo $link=$feedItem->link;
echo '<br>';
if($feedItem->description !='') {
$des=$feedItem->description;
} else {
$des='';
}
echo $des;
echo '<br>';
if($i>5) break;
}