2010-04-02 7 views
11

Sto cercando di utilizzare YQL per estrarre una porzione di HTML da una serie di pagine Web. Le pagine stesse hanno una struttura leggermente diversa (quindi una "pagina di recupero" di Yahoo Pipes con la sua funzione "Taglia contenuto" non funziona bene) ma il frammento a cui sono interessato ha sempre lo stesso attributo class.C'è un modo per ottenere YQL per restituire HTML?

Se ho una pagina HTML come questo:

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

e utilizzare un'espressione YQL come questo:

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

quello che torno sono la (apparentemente non ordinato?) Elementi DOM, in cui quello che voglio è il contenuto HTML stesso. Ho provato anche SELECT content, ma questo seleziona solo il contenuto testuale. Voglio HTML. È possibile?

risposta

8

Si potrebbe scrivere un po 'Open Data Table di inviare un normale YQL html interrogazione tavolo e stringa i il risultato. Qualcosa di simile a quanto segue:

<?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> 

È quindi possibile eseguire una query contro quella tabella personalizzata con una query YQL come:

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' 

Edit: appena realizzato questo è un piuttosto vecchio domanda che è stata urtata; almeno una risposta è qui, alla fine, per chiunque inciampa nella domanda. :)

+0

Bello! Grazie. L'unico problema che ho ora è come ottenere una variabile Yahoo Pipes nell'espressione YQL. Ad esempio, select * from html.tostring dove url = item.link e XPath = '// div [@ id = "foo"]' restituisce l'errore "non valido Identficatore item.link. Mi è l'unico identificatore supportato in questo contesto. " Qualche idea su come lo faccio? (Ci scusiamo per lo snippet di codice macellato, sembra che i commenti non consentano molto in termini di formattazione) –

+0

Capito la risposta a questo: creare una pipe separata che accetta un input URL, inserendola in un generatore di stringhe che costruisce la query YQL e allegarla come query al widget YQL. Quindi, nella tua pipe principale, usa questo nuovo pipe e passa l'URL come input. Penso che probabilmente aprirò una nuova domanda per questo in modo specifico in modo che la gente non debba scovarla nei commenti di questo. –

+0

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

0

YQL converte la pagina in XML, quindi fa il vostro XPath su di esso, quindi prende il DOMNodeList e lo serializza di nuovo in XML per l'output (e quindi converte in JSON se necessario). Non è possibile accedere ai dati originali.

Perché non riesci a gestire XML anziché HTML?

+0

Io sto usando questo nel contesto di Yahoo Pipes, quindi voglio inserire l'HTML in un feed RSS per essere reso da un lettore di feed/browser. L'inserimento dell'XML potrebbe funzionare, ma il modulo YQL di Pipes sembra semplicemente inserire gli elementi DOM nel documento; Neanche io vedo un modo per ottenere il codice XML. –

2

Ho avuto lo stesso esatto problema. L'unico modo per aggirarlo è evitare YQL e usare solo espressioni regolari per abbinare i tag di inizio e fine: /. Non è la soluzione migliore, ma se l'html è relativamente invariato, e il modello solo da dire <div class='name'> a <div class='just_after> `, allora puoi farcela. Quindi è possibile ottenere l'html tra.

+0

Sì, questo è quello che ho fatto anch'io. Sfortunatamente la struttura della pagina cambia a seconda del tipo di voce, quindi finisco per dover dividere il feed più volte per gestire tutti i diversi tipi e unirli/riordinarli di nuovo. Un vero dolore, ma funziona. –

Problemi correlati