Be cautious when using //table[@class="times"][2]: it will select all descendant 2nd children table elements with class "times" of their parent element. So if a node has only 1 child table with class "times", there's not match for this node.
It's not the same as (//table[@class="times"])[2] which will give you the 2nd table with class "times" under the root node (which is probably what you want). You could also use /descendant::table[@class="times"][2].
And it's still different from //table[2][@class="times"] that selects all descendant table elements that are 2nd child of their parent, AND that have class "times".
See XPath 1.0 specifications on abbreviated syntax //:
NOTE: The location path //para1 does not mean the same as the location path /descendant::para1. The latter selects the first descendant para element; the former selects all descendant para elements that are the first para children of their parents.
Let's illustrate that with a scrapy shell session
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]:
Another thing, in your sample page, I see 4 tables that contain "times" in their class attribute:
<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...
so remember that a [@class="times"] predicate means class attribute being exactly "times", not simply containing "times" (you could use [contains(@class, "times")] for that)
sel.xpath('//table[@class="times"]')return the same thing in both environments? - Robin[2]index I get different results - Zach Cowellsel.xpath('//table[@class="times"]')is not[]in the second case)? Or could it be that the index starts at 0 in the second case, therefore you exceed your selection's length? - Robin