Nasıl HTML / XML ayrıştırılabilir ve ondan bilgi elde edilebilir?
Nasıl HTML / XML ayrıştırılabilir ve ondan bilgi elde edilebilir?
Yanıtlar:
PHP ile birlikte geldikleri için yerel XML uzantılarından birini kullanmayı tercih ederim , genellikle tüm 3. taraf kütüphanelerinden daha hızlıdır ve bana işaretleme üzerinde ihtiyacım olan tüm kontrolü veririm.
DOM uzantısı, PHP 5 ile DOM API aracılığıyla XML belgelerinde çalışmanıza izin verir. Programların ve komut dosyalarının dinamik olarak erişmesine ve güncellenmesine izin veren platform ve dilden bağımsız bir arayüz olan W3C'nin Belge Nesne Modeli Çekirdek Seviye 3'ün bir uygulamasıdır. belgelerin içeriği, yapısı ve stili.
DOM, gerçek dünya (bozuk) HTML'yi ayrıştırma ve değiştirme yeteneğine sahiptir ve XPath sorguları yapabilir . Libxml tabanlıdır .
DOM ile üretken olmak biraz zaman alır, ancak bu zaman IMO'ya değer. DOM bir dilden bağımsız arayüz olduğundan, birçok dilde uygulamalar bulacaksınız, bu nedenle programlama dilinizi değiştirmeniz gerekirse, o dilin DOM API'sini nasıl kullanacağınızı zaten biliyorsunuzdur.
Temel bir kullanım örneği, bir A öğesinin href özniteliğini yakalamada bulunabilir ve genel kavramsal genel bakış phd'de DOMDocument adresinde bulunabilir.
DOM uzantısını kullanma StackOverflow üzerinde kapsamlı bir şekilde ele alınmıştır , bu nedenle kullanmayı seçerseniz, karşılaştığınız sorunların çoğunun Yığın Taşması arama / tarama yoluyla çözülebileceğinden emin olabilirsiniz.
XMLReader uzantısı bir XML çekme ayrıştırıcısıdır. Okuyucu, belge akışında ilerleyen ve yoldaki her bir düğümde duran bir imleç görevi görür.
DOM gibi XMLReader libxml tabanlıdır. HTML Ayrıştırıcı Modülünün nasıl tetikleneceğinin farkında değilim, bu yüzden kırık HTML'yi ayrıştırmak için XMLReader'ı kullanma şansı, açıkça libxml'in HTML Ayrıştırıcı Modülünü kullanmasını söyleyebileceğiniz DOM kullanmaktan daha az güçlü olabilir.
Php kullanarak h1 etiketlerinden tüm değerleri almak temel bir kullanım örneği bulunabilir
Bu uzantı, XML ayrıştırıcıları oluşturmanıza ve ardından farklı XML olayları için işleyiciler tanımlamanıza olanak tanır. Her XML ayrıştırıcısının ayarlayabileceğiniz birkaç parametresi de vardır.
XML Ayrıştırıcı kitaplığı da libxml tabanlıdır ve SAX tarzı bir XML push ayrıştırıcı uygular . Bellek yönetimi için DOM veya SimpleXML'den daha iyi bir seçim olabilir, ancak XMLReader tarafından uygulanan çekme ayrıştırıcısından çalışmak daha zor olacaktır.
SimpleXML uzantısı, XML'i normal özellik seçicileri ve dizi yineleyicileri ile işlenebilen bir nesneye dönüştürmek için çok basit ve kolay kullanılabilir bir araç seti sağlar.
HTML'nin geçerli XHTML olduğunu bildiğinizde SimpleXML bir seçenektir. Bozuk HTML'yi ayrıştırmanız gerekirse, boğulacağı için SimpleXml'i bile düşünmeyin.
Temel bir kullanım örneği bulunabilir xml dosyasının CRUD düğüm ve düğüm değerleri basit bir programı ve orada Manuel PHP ek örnekler çok .
Üçüncü taraf bir lib kullanmayı tercih ediyorsanız , dize ayrıştırma yerine aslında DOM / libxml kullanan bir lib kullanmanızı öneririm .
FluentDOM, PHP'deki DOMDocument için jQuery benzeri bir akıcı XML arayüzü sağlar. Seçiciler XPath veya CSS'de yazılır (CSS'den XPath'e dönüştürücü kullanılarak). Mevcut sürümler DOM uygulama standart arayüzlerini genişletir ve DOM Living Standard'dan özellikler ekler. FluentDOM, JSON, CSV, JsonML, RabbitFish ve diğerleri gibi formatları yükleyebilir. Composer ile kurulabilir.
Wa72 \ HtmlPageDom` O gerektirir kullanarak HTML belgeleri kolay manipülasyon için bir PHP kütüphanesidir Symfony2'nin bileşenlerinden DomCrawler DOM ağacında geçiş için ve HTML belgelerinin DOM ağacını işlemek için yöntemleri ekleyerek genişletir.
phpQuery, PHP5 ile yazılmış ve ek Komut Satırı Arabirimi (CLI) sağlayan jQuery JavaScript Kütüphanesi tabanlı sunucu tarafı, zincirlenebilir, CSS3 seçici tahrikli Belge Nesne Modeli (DOM) API'sidir.
Ayrıca bakınız: https://github.com/electrolinux/phpquery
Zend_Dom, DOM belgeleri ve yapılarıyla çalışmak için araçlar sağlar. Şu anda, hem XPath hem de CSS seçicileri kullanan DOM belgelerini sorgulamak için birleştirilmiş bir arayüz sağlayan Zend_Dom_Query sunuyoruz.
QueryPath, XML ve HTML'yi değiştirmek için kullanılan bir PHP kütüphanesidir. Yalnızca yerel dosyalarla değil, web hizmetleri ve veritabanı kaynaklarıyla da çalışacak şekilde tasarlanmıştır. JQuery arabiriminin çoğunu (CSS stili seçiciler dahil) uygular, ancak sunucu tarafında kullanım için yoğun bir şekilde ayarlanmıştır. Composer ile kurulabilir.
fDOMDocument, standart DOM'ları PHP uyarıları veya bildirimleri yerine tüm hata durumlarında istisnalar kullanacak şekilde genişletir. Ayrıca, kolaylık sağlamak ve DOM kullanımını basitleştirmek için çeşitli özel yöntemler ve kısayollar eklerler.
saber / xml XMLReader ve XMLWriter sınıflarını saran ve genişleten basit bir "xml nesneye / diziye" eşleme sistemi ve tasarım deseni oluşturmak için bir kütüphanedir. XML yazmak ve okumak tek geçişlidir ve bu nedenle hızlı olabilir ve büyük xml dosyalarında düşük bellek gerektirir.
FluidXML, XML'i kısa ve akıcı bir API ile işlemek için kullanılan bir PHP kütüphanesidir. Eğlenceli ve etkili olması için XPath ve akıcı programlama modelinden yararlanır.
DOM / libxml üzerine oluşturmanın yararı, yerel bir uzantıya dayandığınız için kutudan iyi performans almanızdır. Ancak, tüm 3. parti kütüphaneleri bu rotadan geçmez. Bunlardan bazıları aşağıda listelenmiştir
- PHP5 + ile yazılmış bir HTML DOM ayrıştırıcısı, HTML'yi çok kolay bir şekilde değiştirmenizi sağlar!
- PHP 5+ gerektirir.
- Geçersiz HTML'yi destekler.
- HTML sayfasındaki etiketleri jQuery gibi seçicilerle bulun.
- Tek bir satırda HTML'den içerik ayıklayın.
Genellikle bu ayrıştırıcıyı önermiyorum. Kod tabanı korkunç ve ayrıştırıcının kendisi oldukça yavaş ve bellek aç. Tüm jQuery Seçicileri ( alt seçiciler gibi ) mümkün değildir. Libxml tabanlı kütüphanelerden herhangi biri bunu kolayca geçebilir.
PHPHtmlParser, jQuery gibi herhangi bir css seçiciyi kullanarak etiketleri seçmenizi sağlayan basit, esnek, html ayrıştırıcıdır. Amaç, geçerli olsun ya da olmasın, html'yi hurdaya atmanın hızlı ve kolay bir yolunu gerektiren araçların geliştirilmesinde yardımcı olmaktır! Bu proje orijinal sunra / php-simple-html-dom-parser tarafından destekleniyordu, ancak destek durmuş gibi görünüyor, bu yüzden bu proje daha önceki çalışmasına uyarlamam.
Yine, bu ayrıştırıcı tavsiye etmem. Yüksek CPU kullanımı ile oldukça yavaştır. Ayrıca, oluşturulan DOM nesnelerinin belleğini temizleme işlevi de yoktur. Bu sorunlar özellikle iç içe döngülerle ölçeklendirilir. Belgelerin kendisi yanlış ve yanlış yazılmış, 14 Nis 16'dan bu yana düzeltmelere yanıt yok.
- Evrensel bir belirteç ve HTML / XML / RSS DOM Ayrıştırıcı
- Elemanları ve niteliklerini manipüle edebilme
- Geçersiz HTML ve UTF8'i destekler
- Öğelerde gelişmiş CSS3 benzeri sorgular gerçekleştirebilir (jQuery gibi - ad alanları desteklenir)
- HTML güzelleştirici (HTML Düzenli gibi)
- CSS ve Javascript'i küçültün
- Nitelikleri sıralayın, karakter durumunu değiştirin, girintiyi düzeltin, vb.
- Genişletilebilir
- Geçerli karaktere / jetona dayalı geri aramalar kullanarak belgeleri ayrıştırma
- Kolay geçersiz kılma için daha küçük işlevlerde ayrılmış işlemler
- Hızlı ve kolay
Hiç kullanmadı. Bunun iyi olup olmadığını söyleyemem.
HTML5'i ayrıştırmak için yukarıdakileri kullanabilirsiniz, ancak HTML5'in izin verdiği biçimlendirme nedeniyle tuhaflıklar olabilir . HTML5 için, özel bir ayrıştırıcı kullanmayı düşünebilirsiniz.
Büyük masaüstü web tarayıcılarıyla maksimum uyumluluk için WHATWG HTML5 spesifikasyonunu temel alan bir HTML ayrıştırıcısının Python ve PHP uygulamaları.
HTML5 sonlandırıldığında daha özel ayrıştırıcılar görebiliriz. Ayrıca, W3'ün html 5 ayrıştırma için Nasıl Yapılır başlıklı bir blog yazısı da kontrol edilmeye değer.
PHP programlamak istemiyorsanız, Web servislerini de kullanabilirsiniz. Genel olarak, bunlar için çok az fayda buldum, ama bu sadece ben ve kullanım durumlarım.
ScraperWiki'nin harici arayüzü, web'de veya kendi uygulamalarınızda kullanmak istediğiniz formdaki verileri çıkarmanızı sağlar. Ayrıca herhangi bir kazıyıcı durumu hakkında bilgi de çıkarabilirsiniz.
Son ve en az tavsiye edilen , HTML'den düzenli ifadelerle veri ayıklayabilirsiniz . Genel olarak HTML'de Normal İfadeler kullanılması önerilmez.
İşaretlemeyi eşleştirmek için web'de bulacağınız snippet'lerin çoğu kırılgandır. Çoğu durumda yalnızca belirli bir HTML parçası için çalışırlar. Bir yere boşluk eklemek, bir etikete özellik eklemek veya bir etiketi değiştirmek gibi küçük biçimlendirme değişiklikleri, RegEx'in düzgün yazılmadığı zamanlarda başarısız olmasına neden olabilir. HTML'de RegEx'i kullanmadan önce ne yaptığınızı bilmelisiniz.
HTML ayrıştırıcıları HTML'nin sözdizimsel kurallarını zaten biliyorlar. Yazdığınız her yeni RegEx için düzenli ifadeler öğretilmelidir. RegEx bazı durumlarda iyidir, ancak gerçekten kullanım durumunuza bağlıdır.
Sen daha güvenilir ayrıştırıcılar yazabilirsiniz , ancak bir yazma tam ve güvenilir düzenli ifadeler ile özel ayrıştırıcı yukarıda belirtilen kütüphaneler zaten var ve bu konuda çok daha iyi bir iş yapmak zaman kaybıdır.
Ayrıca bkz. Html Cthulhu Yolu Ayrıştırma
Eğer biraz para harcamak istiyorsanız,
PHP Architect ya da yazarlara bağlı değilim.
Basit HTML DOM Ayrıştırıcısını Deneyin
// 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);
Sadece DOMDocument-> loadHTML () kullanın ve onunla işiniz bitti. libxml'in HTML ayrıştırma algoritması oldukça iyi ve hızlıdır ve popüler inanışın aksine, hatalı biçimlendirilmiş HTML'yi boğmaz.
Neden düzenli ifadeler kullanmamalısınız ve ne zaman kullanmalısınız?
Öncelikle, yaygın bir yanlış adlandırma: Normal ifadeler HTML'yi " ayrıştırmak " için değildir . Normal ifadeler verileri " çıkarabilir " . Çıkarmak için yapıldıkları şey budur. Normal SGML araç kitleri veya temel XML ayrıştırıcıları üzerinden normal ifade HTML'sinin çıkarılmasının en büyük dezavantajı sözdizimsel çabaları ve değişen güvenilirlikleri.
Biraz güvenilir bir HTML çıkarma normal ifadesi oluşturmayı düşünün:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
basit bir phpQuery veya QueryPath eşdeğerinden daha az okunabilir:
$div->find(".stationcool a")->attr("title");
Bununla birlikte, yardım edebilecekleri belirli kullanım durumları vardır.
<!--
, HTML yorumlarını göstermez , ancak bazen çıkarma için daha yararlı çapalardır. Özellikle sahte HTML varyasyonları <$var>
veya SGML kalıntılarının normal ifadelerle uyumu kolaydır.Bazen düzenli ifadeler kullanarak bir HTML snippet'inin ön ayıklanması bile önerilir /<!--CONTENT-->(.+?)<!--END-->/
ve daha basit HTML ayrıştırıcı ön uçlarını kullanarak kalanını işlemek .
Not: Aslında alternatif olarak XML ayrıştırma ve düzenli ifadeler istihdam bu app var . Geçen hafta PyQuery ayrışması kırıldı ve normal ifade hala işe yaradı. Evet garip, ve kendim açıklayamam. Ama öyle oldu.
Bu yüzden lütfen regex = evil meme ile eşleşmediği için gerçek dünyayı dikkate almayın. Ama buna çok fazla oy vermeyelim. Bu konu için sadece bir sidenote.
DOMComment
yorumları okuyabilir, bu nedenle bunun için Regex kullanmak için hiçbir neden yoktur.
DOM
kullanır ve libxml HTML yüklerken kullanılacak ayrı bir HTML ayrıştırıcı modülüne sahiptir . loadHTML()
phpQuery ve QueryPath , akıcı jQuery API'sinin çoğaltılmasında oldukça benzerdir. Bu yüzden PHP'de HTML'yi düzgün bir şekilde ayrıştırmak için en kolay iki yaklaşımdır .
QueryPath için örnekler
Temel olarak önce bir HTML dizesinden sorgulanabilir bir DOM ağacı oluşturursunuz:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
Ortaya çıkan nesne, HTML belgesinin tam bir ağaç temsilini içerir. DOM yöntemleri kullanılarak geçilebilir. Ancak ortak yaklaşım, jQuery'de olduğu gibi CSS seçicilerini kullanmaktır:
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
Çoğunlukla için basit #id
ve / .class
veya DIV
etiket seçicileri kullanmak istersiniz ->find()
. Ancak , bazen daha hızlı olan XPath deyimlerini de kullanabilirsiniz . Gibi Ayrıca tipik jQuery yöntemleri ->children()
ve ->text()
özellikle ->attr()
sağ HTML parçacıkları ayıklanması basitleştirmek. (Ve zaten SGML varlıklarının kodu çözüldü.)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath ayrıca akışa ( ->append
) yeni etiketler eklenmesine ve daha sonra güncellenmiş bir belgenin ( ->writeHTML
) çıktısına ve ön bilgisine izin verir . Yalnızca hatalı biçimlendirilmiş HTML'yi ayrıştırmakla kalmaz, aynı zamanda çeşitli XML lehçelerini (ad alanlarıyla birlikte) ve hatta HTML mikro biçimlerinden (XFN, vCard) veri ayıklayabilir.
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
.
phpQuery veya QueryPath?
Genellikle QueryPath belgelerin manipülasyonu için daha uygundur. PhpQuery de jQuery daha yakından benzemek için bazı sahte AJAX yöntemleri (sadece HTTP istekleri) uygular. PhpQuery genellikle QueryPath (daha az genel özellikleri nedeniyle) daha hızlı olduğu söylenir.
Farklılıklar hakkında daha fazla bilgi için tagbyte.org adresinden geri dönüşüm makinesindeki bu karşılaştırmaya bakın . (Orijinal kaynak kayboldu, işte bir internet arşivi bağlantısı. Evet, yine de eksik sayfaları, insanları bulabilirsiniz.)
Ve işte kapsamlı bir QueryPath tanıtımı .
Avantajları
->find("a img, a object, div a")
Basit HTML DOM harika bir açık kaynaklı ayrıştırıcıdır:
DOM öğelerini nesneye yönelik bir şekilde ele alır ve yeni yinelemenin, uyumsuz kod için çok fazla kapsama alanı vardır. Ayrıca, JavaScript'te gördüğünüz gibi, o etiket adının tüm öğelerinin örneklerini döndürecek "bul" işlevi gibi bazı harika işlevler de vardır.
Bunu birçok araçta kullandım, birçok farklı web sayfasında test ettim ve bence harika çalışıyor.
Burada bahsetmediğim genel bir yaklaşım HTML'yi Tidy aracılığıyla çalıştırmaktır , garantili geçerli XHTML tükürmek için ayarlanabilen . Sonra üzerinde herhangi bir eski XML kitaplığını kullanabilirsiniz.
Ancak özel sorununuza göre, bu projeye bir göz atmalısınız: http://fivefilters.org/content-only/ - Okunabilirlik algoritmasının yalnızca metinsel içeriği (başlıkları değil) çıkarmak için tasarlanmış değiştirilmiş bir sürümüdür ve altbilgiler) bir sayfadan alabilirsiniz.
1a ve 2 için: Yeni Symfony Componet sınıfı DOMCrawler'a ( DomCrawler ) oy verirdim . Bu sınıf, CSS Seçicileri'ne benzer sorgulara izin verir. Gerçek dünyadan örnekler için bu sunuma bir göz atın: symfony2-world haberleri .
Bileşen bağımsız çalışacak şekilde tasarlanmıştır ve Symfony olmadan kullanılabilir.
Tek dezavantajı, sadece PHP 5.3 veya daha yeni bir sürümle çalışmasıdır.
Bu, genellikle ekran kazıma olarak adlandırılır . Bunun için kullandığım kütüphane Simple HTML Dom Parser .
Daha önce ihtiyaçlarımız için oldukça az sayıda tarayıcı oluşturduk. Günün sonunda, genellikle en iyisini yapan basit düzenli ifadelerdir. Yukarıda listelenen kütüphaneler, oluşturuldukları nedenden ötürü iyi olsa da, ne aradığınızı biliyorsanız, düzenli ifadeler gitmek için daha güvenli bir yoldur, çünkü yüklenirse başarısız olan geçerli olmayan HTML / XHTML yapılarını da işleyebilirsiniz parsers çoğu aracılığıyla.
PHP Basit HTML DOM Ayrıştırıcı öneririm .
Gerçekten gibi güzel özelliklere sahip:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
Bu, W3C XPath teknolojisinin iyi bir görev açıklaması gibi görünüyor . " İç içe yerleştirilmiş etiketlerdeki tüm href
özellikleri döndür" gibi sorguları ifade etmek kolaydır . PHP tutkunu olmadığından, XPath'in hangi formda olabileceğini size söyleyemem. HTML dosyasını işlemek için harici bir program çağırabiliyorsanız, XPath'ın komut satırı sürümünü kullanabilmeniz gerekir. Hızlı bir giriş için bkz. Http://en.wikipedia.org/wiki/XPath .img
<foo><bar><baz> elements
Evet, amaç için simple_html_dom kullanabilirsiniz. Ancak, özellikle web hurdaya çıkarmak için, simple_html_dom ile oldukça çok çalıştım ve çok savunmasız olduğunu bulduk. Temel işi yapar ama yine de tavsiye etmeyeceğim.
Bu amaçla kıvrımı hiç kullanmadım ama öğrendiğim şey, kıvrımın işi çok daha verimli bir şekilde yapabilmesi ve çok daha sağlam olmasıdır.
Lütfen bu bağlantıyı kontrol edin: scraping-websites-with-curl
QueryPath iyidir, ancak "izleme durumu" na dikkat edin, çünkü ne anlama geldiğini anlamadıysanız, ne olduğunu ve kodun neden çalışmadığını bulmak için çok fazla hata ayıklama zamanı harcadığınız anlamına gelebilir.
Bunun anlamı, sonuç kümesindeki her çağrı nesnedeki sonuç kümesini değiştirir, her bağlantının yeni bir küme olduğu jquery'deki gibi zincirlenemez, sorgunuzdan elde edilen sonuçlar olan tek bir kümeniz vardır ve her işlev çağrısı değişir bu tek set.
jquery benzeri davranışlar elde etmek için, bir filtre yapmadan / benzer bir işlem yapmadan önce dallamanız gerekir, bu da jquery'de olanları çok daha yakından yansıtacağı anlamına gelir.
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
Şimdi bu çok beni tetikledi input[name='forename']
değil orijinal sorgu için sonuç kümesi içerir "div p"
, ne buldum QueryPath filtreleri ve bulgular ve sonuçlarınızı değiştirir ve bunları nesnede saklar her şeyi izledi . bunun yerine bunu yapmalısın
$forename = $results->branch()->find("input[name='forname']")
daha sonra $results
değiştirilmeyecek ve sonuç setini tekrar tekrar kullanabilirsiniz, belki çok daha fazla bilgiye sahip biri bunu biraz temizleyebilir, ancak temelde bulduğumdan böyle.
Advanced Html Dom , aynı arabirimi sunan basit bir HTML DOM değişimidir, ancak DOM tabanlıdır, bu da ilişkili bellek sorunlarının hiçbirinin meydana gelmediği anlamına gelir.
Ayrıca jQuery uzantıları da dahil olmak üzere tam CSS desteğine sahiptir .
İçin HTML5 , HTML5 lib yıllardır terk edildi. Son güncelleme ve bakım kayıtları ile bulabildiğim tek HTML5 kütüphanesi , bir haftadan biraz önce beta 1.0'a getirilen html5-php'dir .
GB dosyalarını kolayca işleyebilen genel amaçlı bir XML ayrıştırıcı yazdım. XMLReader'a dayanır ve kullanımı çok kolaydır:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
İşte github repo: XmlExtractor
PHPPowertools / DOM-Query adında , jQuery ile yaptığınız gibi HTML5 ve XML belgelerini taramanızı sağlayan bir kütüphane oluşturdum .
Kaputun altında, CSS seçicilerinin XPath seçicilerine dönüştürülmesi için symfony / DomCrawler kullanır . İyi bir performans sağlamak için bir nesneyi diğerine geçirirken bile her zaman aynı DomDocument'i kullanır.
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>');
[...]
Kitaplık ayrıca PSR-0 uyumlu kitaplıklar için kendi sıfır yapılandırmalı otomatik yükleyicisini de içerir. Dahil edilen örnek, herhangi bir ek yapılandırma olmadan kutudan çıkarılmalıdır. Alternatif olarak, besteci ile kullanabilirsiniz.
XML_HTMLSax
daha istikrarlı - artık korunmasa bile. Başka bir seçenek de HTML'yi Html Tidy aracılığıyla yönlendirmek ve daha sonra standart XML araçlarıyla ayrıştırmak olabilir.
Symfony'nin çerçeve HTML ayrıştırmak olabilir demetleri vardır ve seçmek için CSS stilini kullanabilirsiniz document object modelini kullanmak yerine XPath .
Daha önce bahsedilen HTML / XML DOM'yi işlemenin birçok yolu vardır. Dolayısıyla, bunları kendim listelemeye çalışmam.
Ben sadece DOM uzantısı kullanmayı tercih neden eklemek istiyorum ve neden:
CSS seçicilerini kullanma yeteneğini kaçırırken DOMDocument
, bu özelliği eklemenin oldukça basit ve kullanışlı bir yolu var: alt sınıfınıza alt sınıflandırma DOMDocument
ve JS benzeri querySelectorAll
ve querySelector
yöntemler ekleme .
Seçicileri ayrıştırmak için Symfony çerçevesinden çok minimalist CssSelector bileşenini kullanmanızı öneririm . Bu bileşen yalnızca CSS seçicilerini XPath seçicilerine çevirir;DOMXpath
karşılık gelen Nodelist'i almak için a'ya beslenebilir.
Daha sonra bu (hala çok düşük seviye) alt sınıfı daha yüksek seviyeli sınıflar için temel olarak kullanabilirsiniz, örn. çok özel XML türlerini ayrıştırın veya daha fazla jQuery benzeri davranış ekleyin.
Aşağıdaki kod doğrudan DOM-Query kütüphanemden çıkıyor ve tarif ettiğim tekniği kullanıyor.
HTML ayrıştırma için:
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);
}
}
}
}
[...]
}
Ayrıca Symfony için CssSelector bileşenini oluşturma kararı ve nasıl kullanılacağı konusunda Symfony'nin yaratıcısı Fabien Potencier tarafından XML belgelerini ayrıştırma konusuna bakın .
FluidXML ile XPath ve CSS Seçicileri kullanarak XML'yi sorgulayabilir ve yineleyebilirsiniz .
$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');
});
Üç satır halinde XML'den JSON ve dizi:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Ta da!
HTML'yi normal ifadeyle ayrıştırmamak için çeşitli nedenler vardır. Ancak, hangi HTML'nin oluşturulacağı üzerinde tam denetime sahipseniz, basit normal ifade ile yapabilirsiniz.
Yukarıda HTML'yi normal ifadeyle ayrıştıran bir işlev var. Bu işlevin çok hassas olduğunu ve HTML'nin belirli kurallara uymasını gerektirdiğini, ancak birçok senaryoda çok iyi çalıştığını unutmayın. Basit bir ayrıştırıcı istiyorsanız ve kitaplık yüklemek istemiyorsanız, bunu deneyin:
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/")));
Https://github.com/ivopetkov/html5-dom-document-php adresinde ücretsiz olarak bulunan HTML5DOMDocument adlı bir kütüphane oluşturdum.
Sorgu seçicileri de desteklediğini düşünüyorum. İşte bazı örnek kod:
$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;
JQuery seçicisine aşina iseniz, ScarletsQuery for PHP'yi kullanabilirsiniz
<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);
Bu kütüphane genellikle çevrimdışı html işlemek için 1 saniyeden az sürer.
Ayrıca, etiket özelliklerinde geçersiz HTML veya eksik teklifi kabul eder.
Xml ayrıştırma için en iyi yöntem:
$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;
}