2010-04-02 171 views
11

我正在嘗試使用YQL從一系列網頁中提取HTML的一部分。頁面本身的結構略有不同(所以Yahoo Pipes「Fetch Page」及其「剪切內容」功能不起作用),但我感興趣的片段始終具有相同的class屬性。有沒有辦法讓YQL返回HTML?

如果我有一個HTML頁面是這樣的:

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

,並使用YQL表達這樣的:

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

什麼我回來是(顯然無序?)DOM元素,其中我想要的是HTML內容本身。我也試過SELECT content,但那隻能選擇文字內容。我想要HTML。這可能嗎?

回答

8

你可以寫一點Open Data Table發出一個正常的YQL html表查詢和stringify的結果。像下面這樣:

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

然後,您可以查詢使用的是自定義表用YQL查詢,如:

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' 

編輯:剛剛意識到這是一個很老的被碰撞的問題;最終,至少有一個答案在這裏,對於任何人在這個問題上磕磕絆絆。 :)

+0

美麗!謝謝。我現在唯一的問題是如何將Yahoo Pipes變量放入YQL表達式中。例如, SELECT * FROM html.tostring其中 URL = item.link 和XPath = '// DIV [@ ID = 「富」]' 還給錯誤「無效identfier item.link。我是在這種情況下唯一支持的標識符。「任何想法,我怎麼做? (對不起,代碼片斷,看起來像註釋不允許格式化) – 2010-05-05 13:53:10

+0

想出了這個答案:創建一個單獨的管道,它接受一個URL輸入,將它插入到一個字符串生成器中YQL查詢,並將其作爲查詢附加到YQL小部件。然後在你的主管道中,使用這個新管道並將URL作爲輸入傳遞給它。 我想我可能會爲此專門打開一個新問題,這樣人們就不必在這個問題的評論中追捕它。 – 2010-05-22 19:00:02

+0

打開:http://stackoverflow.com/questions/2889406/how-do-i-pass-a-yahoo-pipes-item-into-a-yql-query – 2010-05-22 19:38:44

0

YQL將頁面轉換爲XML,然後對其執行XPath操作,然後將DOMNodeList並將其序列化爲XML以用於輸出(然後在需要時轉換爲JSON)。您無法訪問原始數據。

爲什麼你不能處理XML而不是HTML?

+0

我在Yahoo Pipes的上下文中使用這個,所以我想將HTML插入RSS feed中,以便通過feed閱讀器/瀏覽器呈現。插入XML可能會起作用,但Pipes YQL模塊似乎只是將DOM元素插入到文檔中;我沒有看到獲取XML源的方法。 – 2010-04-04 12:12:59

2

我有這個相同的確切問題。我解決這個問題的唯一方法是避免使用YQL,並使用正則表達式來匹配開始和結束標記:/。不是最好的解決方案,但是如果html相對不變,並且模式從<div class='name'><div class='just_after>`,那麼你就可以逃避這一點。然後你可以得到之間的HTML。

+0

是的,這也是我最終做的。不幸的是,頁面的結構會根據它的輸入類型而改變,所以我最終不得不多次拆分提要來處理所有不同的類型,並將它們合併/排序。真正的痛苦,但它的作品。 – 2010-05-05 13:22:31