2011-03-08 41 views
4

我想尋求你的幫助,我想解決一個涉及XPaths的問題。推廣XPaths

我想推廣用戶提供的多個XPath,以獲得最適合所有提供的示例的XPath。這是針對我正在構建的網絡抓取系統。

如:如果用戶給出瞭如下的XPath(每個指向一個鏈接從谷歌新聞網頁的「特別關注」部分)

很好的例子:

/html/body/div[@id='page']/div/div[@id='main-wrapper']/div[@id='main']/div/div/div[3] /div[1]/table[@id='main-am2-pane']/tbody/tr/td[@id='rt-col']/div[3]/div[@id='s_en_us:ir']/div[2]/div[1]/div[2]/a[@id='MAE4AUgAUABgAmoCdXM']/span 

/html/body/div[@id='page']/div/div[@id='main-wrapper']/div[@id='main']/div/div/div[3]/div[1]/table[@id='main-am2-pane']/tbody/tr/td[@id='rt-col']/div[3]/div[@id='s_en_us:ir']/div[2]/div[6]/div[2]/a[@id='MAE4AUgFUABgAmoCdXM']/span 

/html/body/div[@id='page']/div/div[@id='main-wrapper']/div[@id='main']/div/div/div[3]/div[1]/table[@id='main-am2-pane']/tbody/tr/td[@id='rt-col']/div[3]/div[@id='s_en_us:ir']/div[2]/div[12]/div[2]/a[@id='MAE4AUgLUABgAmoCdXM']/span 

不好的例子:(指向另一部分的鏈接)

/html/body/div[@id='page']/div/div[@id='main-wrapper']/div[@id='main']/div/div/div[3]/div[1]/table[@id='main-am2-pane']/tbody/tr/td[@id='lt-col']/div[2]/div[@id='replaceable-section-blended']/div[1]/div[4]/div/h2/a[@id='MAA4AEgFUABgAWoCdXM']/span 

它應該能夠概括並生成一個xpath表達式,它將選擇「Spotlight」部分中的所有鏈接。 (它應該能夠扔出去給出了不正確的XPath)

廣義的XPath

/html/body/div[@id='page']/div/div[@id='main-wrapper']/div[@id='main']/div/div/div[3]/div[1]/table[@id='main-am2-pane']/tbody/tr/td[@id='rt-col']/div[3]/div[@id='s_en_us:ir']/div[2]/div/div[2]/a[@id='MAE4AUgLUABgAmoCdXM']/span 

能不能請諮詢我如何去做。我正在考慮使用最長的公共子字符串策略,但是如果給出了一個不好的例子,那麼它會過度泛化(就像給出的第四個例子)在這個區域是否有任何庫或任何開源軟件?

我看到一些類似的帖子(finding common ancestor from a group of xpath?Howto find the first common XPath ancestor in Javascript?)但他們正在談論最長的共同祖先。

我使用Javascript作爲Firefox擴展的形式編寫它。

感謝您的時間和任何幫助將不勝感激!

+0

目前尚不清楚問題是什麼。您尚未定義「糟糕的」XPath表達式以及「好」的Xpath表達式是什麼。另外,如果輸入「不良」表達式,您還沒有定義要執行的操作。請編輯您的問題並儘可能精確地定義問題。 – 2011-03-08 14:13:12

+0

嗨Dimitre,使用上面的例子,假設用戶想要從Google新聞的聚光燈部分提取所有鏈接,他可以舉幾個指向'聚光燈'鏈接的xpath示例。假設他不小心給了一個'壞'例子 - 一個隨機的xpath到其他一些內容,系統不應該陷入陷阱並試圖概括它,以便它覆蓋'壞'xpath。 – netvarun 2011-03-08 14:40:09

+0

@ user649851:它看起來像你想要的內部幾乎共同的祖先與一個給定的節點集更多的後代。當來自節點集的節點來自同一文檔時,它們至少有一個共同的祖先:最差情況下的根元素。所以,如果你想要最內層的意思,那就意味着你必須比較那個可靠的共同祖先。另外,因爲你想要幾乎普遍的,你必須從節點集合中選擇最重要的節點,這是你不會考慮的。我認爲,這兩個過程使得這個任務對於單個XPath表達式變得不可行。 – 2011-03-08 17:40:36

回答

1

這裏的問題是在自動機最小化問題。所以你有(Xpath1 | Xpath2 | Xpath3),你想獲得匹配相同節點的最小自動機Xpath4。這也是關於信息丟失與否最小化的問題,如JPEG。對於確切的最小化,你可以谷歌「算法最小化有限狀態自動機」。

好吧,最簡單的方法是將每個Xpath運算符轉換爲字符並從字符串列表中運行基於字符的子字符串查找程序後,找到常見的子序列。所以我們有例如

adcba,acba,adba --common substring - > aba --general reg exp - > a。* b。* a - 轉回到xpath - > ...

您也可以嘗試設置一些不太一般的地方。*