2017-04-26 92 views
1

我試圖從http://www.apkmirror.com下載scrapy APK下載頁面,但是我的一些XPath表達式沒有按照我的預期行事。在Scrapy中,爲什麼xpath表達式中的text()[n]後跟extract()不等於extract(),然後是選擇[n-1]個元素?

例如,在Scrapy殼爲http://www.apkmirror.com/apk/google-inc/maps/maps-9-2-0-9-release/maps-9-2-0-android-4-3-902013124-android-apk-download/,我提取「APK細節」部分,如下所示:

In [1]: response.xpath('//*[@title="APK details"]/following-sibling::*[@class="appspec-value"]//text()').extract() 
Out[1]: 
[u'Version: 9.2.0 (902013124)', 
u'arm ', 
u'Package: com.google.android.apps.maps', 
u'\n', 
u'40,353 downloads '] 

我要提取的支持的體系結構,這是這種情況下'arm '在第二行。我提取由

In [2]: response.xpath('//*[@title="APK details"]/following-sibling::*[@class="appspec-value"]//text()[2]').extract() 
Out[2]: [u'arm '] 

行到目前爲止,一切都很好,但也有其他的網頁,如http://www.apkmirror.com/apk/htc-corporation/htc-backup/htc-backup-4-5-696121-release/htc-backup-4-5-696121-android-apk-download/其中包含版本的行不存在。在這種情況下,我得到

In [3]: response.xpath('//*[@title="APK details"]/following-sibling::*[@class="appspec-value"]//text()').extract() 
Out[3]: 
[u'Version: 4.5.696121 (454663465) ', 
u'Package: com.htc.backup', 
u'\n', 
u'1,664 downloads '] 

奇怪的是,如果我前面的XPath表達式後添加[2],我得到一個空行:

In [2]: response.xpath('//*[@title="APK details"]/following-sibling::*[@class="appspec-value"]//text()[2]').extract() 
Out[2]: [u'\n'] 

這相當於列表的第三個元素從extract()獲得,而我期望它仍然是從Package:開始的第二行。

總之,好像我的假設,即「包括在XPath表達式[n]並呼籲extract()相當於調用extract()並從結果列表中選擇[n-1]」是不正確的。有人可以證實這一點,並解釋爲什麼不?

+0

'(// * [@ title =「APK詳細信息」]/following-sibling :: * [@ class =「appspec-value」] // text())[2]'? – choroba

+0

如果我嘗試'response.xpath('(// * [@ title =「APK details」]/following-sibling :: * [@ class =「appspec-value」] // text())[2] ').extract()',我得到一個'ValueError:所有的字符串必須是XML兼容的:Unicode或ASCII,沒有NULL字節或控制字符。 –

回答

3

拿這個XML爲例:

<r> 
    <p id="1"> 
    <c>text 1</c> 
    <c>text 2</c> 
    <c>text 3</c> 
    </p> 
    <p id="2"> 
    <c>text 4</c> 
    <c>text 5</c> 
    <c><a>text 6</a><a>text 7</a></c> 
    </p> 
</r> 

//c//text()[1]回報text 1 - 6,因爲他們都是低於c第一個文本。

//c//text()[2]回報text 7,因爲它下面c唯一秒文本。

(//c//text())[2]回報text 2,因爲它是下面的一些c所有文本的秒。

+0

在原始示例中,我注意到通過從XPath表達式中除去'// text()','extract()'結果中的不同列表項產生自自動關閉的'
'標記,該標記本身不會不包含'text()'。 –

相關問題