2010-04-02 25 views
11

Bir dizi web sayfasından HTML'nin bir bölümünü ayıklamak için YQL'yi kullanmaya çalışıyorum. Sayfaların kendileri biraz farklı bir yapıya sahiptir (bu yüzden "Kesilmiş içerik" özelliği ile bir Yahoo Pipes "Sayfa Getir" özelliği iyi çalışmaz) ancak ilgilendiğim parça her zaman aynı class özniteliğine sahiptir.YQL'i HTML'ye döndürmenin bir yolu var mı?

böyle bir HTML sayfası varsa:

<html> 
    <body> 
    <div class="foo"> 
     <p>Wolf</p> 
     <ul> 
     <li>Dog</li> 
     <li>Cat</li> 
     </ul> 
    </div> 
    </body> 
</html> 

ve bunun gibi bir YQL ifadesini kullanın:

SELECT * FROM html 
WHERE url="http://example.com/containing-the-fragment-above" 
AND xpath="//div[@class='foo']" 

ne geri almak (görünüşte sırasız?) Olan DOM elemanları, İstediğim şey HTML içeriğidir. Ben de SELECT content denedim, ancak sadece metinsel içeriği seçer. HTML istiyorum. Mümkün mü?

cevap

8

Normal bir YQL html tablo sorgusu ve stringify sonucunu göndermek için Open Data Table biraz yazabilirim. Aşağıdaki gibi bir şey:

<?xml version="1.0" encoding="UTF-8" ?> 
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd"> 
    <meta> 
    <sampleQuery>select * from {table} where url="http://finance.yahoo.com/q?s=yhoo" and xpath='//div[@id="yfi_headlines"]/div[2]/ul/li/a'</sampleQuery> 
    <description>Retrieve HTML document fragments</description> 
    <author>Peter Cowburn</author> 
    </meta> 
    <bindings> 
    <select itemPath="result.html" produces="JSON"> 
     <inputs> 
     <key id="url" type="xs:string" paramType="variable" required="true"/> 
     <key id="xpath" type="xs:string" paramType="variable" required="true"/> 
     </inputs> 
     <execute><![CDATA[ 
var results = y.query("select * from html where [email protected] and [email protected]", {url:url, xpath:xpath}).results.*; 
var html_strings = []; 
for each (var item in results) html_strings.push(item.toXMLString()); 
response.object = {html: html_strings}; 
]]></execute> 
    </select> 
    </bindings> 
</table> 

Daha sonra böyle bir YQL sorgusu ile bu özel tablo karşı sorgulamak olabilir:

use "http://url.to/your/datatable.xml" as html.tostring; 
select * from html.tostring where 
    url="http://finance.yahoo.com/q?s=yhoo" 
    and xpath='//div[@id="yfi_headlines"]/div[2]/ul/li' 

Düzenleme: Sadece bu oldukça eski olduğunu fark çarpılan soru; En azından bir cevap, en sonunda, soru üzerine tökezleyen herkes içindir. :)

+0

Güzel! Teşekkür ederim. Şu anda sahip olduğum tek sorun, YQL ifadesine bir Yahoo Pipes değişkeni elde etmektir. hata geri verir '[id = "foo" @] // div' Örneğin, * url = item.link ve nerede html.tostring gelen xpath = "Geçersiz identfier item.link. Benim select Bu bağlamda desteklenen tek tanımlayıcı. " Bunu nasıl yaptığım hakkında bir fikrin var mı? (Biçimlendirilmiş kod parçacığı için özür dilerim, yorumların biçimlendirmenin çok fazla yapılmasına izin vermez) –

+0

Bunun cevabını anladım: bir URL girişi alan ayrı bir boru oluşturmak, bunu oluşturan bir dize oluşturucuya ekler YQL sorgusu ve bunu YQL widget'ına sorgu olarak ekleyin. Daha sonra ana borunuzda, bu yeni boruyu kullanın ve URL'yi giriş olarak girin. Sanırım muhtemelen bunun için yeni bir soru açacağım, bu yüzden insanların bunu yorumlarında avlamak zorunda kalmayacakları. –

+0

Açıldı: http://stackoverflow.com/questions/2889406/how-do-i-pass-a-yahoo-pipes-item-into-a-yql-query –

0

YQL, sayfayı XML'ye dönüştürür, ardından XPath'ınızı yapar, daha sonra DOMNodeList'i alır ve çıktınız için XML'e geri döndürür (ve sonra gerekirse JSON'a dönüştürür). Orijinal verilere erişemezsiniz.

Neden HTML yerine XML ile baş edemiyorsunuz?

+0

Bunu Yahoo Pipes bağlamında kullanıyorum, bu yüzden HTML'yi bir yayın okuyucu/tarayıcı tarafından oluşturulacak bir RSS beslemesine eklemek istiyorum. XML'in eklenmesi işe yarayabilir, ancak Pipes YQL modülü DOM öğelerini belgeye yerleştiriyor gibi görünüyor; XML kaynağını da almanın bir yolunu görmüyorum. –

2

Ben de aynı sorunu yaşadım. Etrafımdaki tek yol, YQL'den kaçınmak ve sadece başlangıç ​​ve bitiş etiketlerini eşleştirmek için normal ifadeleri kullanmaktır: /. En iyi çözüm değil, ancak html göreceli olarak değişmezse ve desen <div class='name'> için <div class='just_after> `deyse, bundan kurtulabilirsiniz. Sonra aradaki html'yi alabilirsiniz.

+0

Evet, ben de bu işi bitirdim. Ne yazık ki sayfanın yapısı, ne tür bir girişe bağlı olarak değişir, bu yüzden tüm farklı türleri işlemek için beslemeyi birkaç kez bölmek zorunda kalırım ve bunları bir araya getirin/bir araya getirin. Gerçek bir acı, ama işe yarıyor. –