我在Scrapy中遇到了Xpath选择器问题。每当我在OS X上运行蜘蛛时,选择器按预期工作;但是当我在Ubuntu 12.04和Raspbian中运行相同的脚本时,选择器不起作用。我不知道为什么会发生这种情况。
选择器是:
sel.xpath('//table[@class="times"]')
返回表的2个选择器给我,但是当我更进一步并添加一个索引来选择返回的第二个表时:
sel.xpath('//table[@class="times"][2]')
OS X将第二个表返回给我没问题,而Ubuntu / Raspbian则不返回任何内容:[]
我完全不知道为什么会这样。我已尽力复制环境(scrapy版本0.20,python 2.7),但我仍然没有想到它。作为参考,我试图通过shell抓取的页面是
scrapy shell "http://washington.dc.gegov.com/webadmin/dhd_431/lib/mod/inspection/paper/_paper_food_inspection_report.cfm?inspectionID=200651&wgdmn=431&wguid=1367&wgunm=sysact"
感谢有关此事的任何帮助。
答案 0 :(得分:2)
使用//table[@class="times"][2]
时要小心:它会选择所有后代第二个子表格元素,其父元素的类别为“times”。因此,如果一个节点只有一个类为“times”的子表,则该节点不匹配。
它与(//table[@class="times"])[2]
不同,它会在根节点下为您提供第二个类“times”的表(这可能就是您想要的)。您也可以使用/descendant::table[@class="times"][2]
。
它仍然不同于//table[2][@class="times"]
,它选择所有后代表元素,它们是父元素的第二个子元素,并且具有类“times”。
请参阅XPath 1.0 specifications缩写语法//
:
注意:位置路径// para 1与位置路径/ descendant :: para 1的含义不同。后者选择第一个后代para元素;前者选择所有后代的para元素,这些元素是他们父母的第一个孩子。
让我们用scrapy shell
会话来说明
paul@wheezy:~$ scrapy shell "http://washington.dc.gegov.com/webadmin/dhd_431/lib/mod/inspection/paper/_paper_food_inspection_report.cfm?inspectionID=200651&wgdmn=431&wguid=1367&wgunm=sysact"
In [1]: sel.xpath('//table[@class="times"][2]')
Out[1]: []
In [2]: sel.xpath('(//table[@class="times"])[2]')
Out[2]: [<Selector xpath='(//table[@class="times"])[2]' data=u'<table class="times" style="font-size:9p'>]
In [3]: sel.xpath('/descendant-or-self::table[@class="times"]')
Out[3]:
[<Selector xpath='/descendant-or-self::table[@class="times"]' data=u'<table class="times" style="margin-top:1'>,
<Selector xpath='/descendant-or-self::table[@class="times"]' data=u'<table class="times" style="font-size:9p'>]
In [4]: sel.xpath('/descendant-or-self::table[@class="times"][2]')
Out[4]: [<Selector xpath='/descendant-or-self::table[@class="times"][2]' data=u'<table class="times" style="font-size:9p'>]
In [5]: sel.xpath('/descendant::table[@class="times"][2]')
Out[5]: [<Selector xpath='/descendant::table[@class="times"][2]' data=u'<table class="times" style="font-size:9p'>]
In [6]:
另外,在您的示例页面中,我看到4个表在其class属性中包含“times”:
<table class="times" style="margin-top:1...
<table class="times" style="font-size:9p...
<table class="times pt6" cellpadding="0"...
<table class="times fs_10px" style="bord...
所以请记住,[@class="times"]
谓词意味着类属性恰好是“时间”,而不是简单地包含“时间”(您可以使用[contains(@class, "times")]
)