Python的XPath语法

时间:2014-12-25 14:17:07

标签: python xpath

Python新手,特别是xpath - 试图将字符串列表刮入Python列表。我明白我想做什么,但不知道我会怎么写。我试图从ESPN的球队名单中拉出球员名字:

我知道我的代码看起来像这样,因为有一个表,我要拉的每个条目都有这个xpath(取自Chrome) - 我相信a指向链接或文本哪个链接,链接到。

//*[@id="my-players-table"]/div[2]/div/table[1]/tbody/tr[3]/td[2]/a

对于我的问题,当右边的tr元素递增时,会改变播放器名称< ---与我的问题相关,因为这是我最终寻找的数据。

For EachRow in Table:
    If ChildElement exists:
    Add Child Element to List
    Else: nextrow

现在我只需将EachRow替换为//*[@id="my-players-table"]/div[2]/div/table[1]/tbody/tr[i],将ChildElement替换为//*[@id="my-players-table"]/div[2]/div/table[1]/tbody/tr[i]/td[2]/a

也有人有一个好的博客或学习帖子,我可以掌握Xpath或更具体地掌握Xpath与Python一起使用?我想知道阅读文档,因为我不确定他们是否有相关的例子,但如果有,我很乐意看看。

谢谢和Merry XMas所有人

BTW:我试图剖析http://espn.go.com/nba/team/roster/_/name/bos/boston-celtics

的链接

1 个答案:

答案 0 :(得分:2)

import lxml.html as LH
import urllib2
url = 'http://espn.go.com/nba/team/roster/_/name/bos/boston-celtics'
doc = LH.parse(urllib2.urlopen(url))
print(doc.xpath('''
    //div[@id="my-players-table"]/div//table[1]//tr/td[2]/a/text()''')[1:])

产量

['Brandon Bass', 'Avery Bradley', 'Jae Crowder', 'Jeff Green', 'Jameer Nelson',
'Kelly Olynyk', 'Phil Pressey', 'Marcus Smart', 'Jared Sullinger', 'Marcus
Thornton', 'Evan Turner', 'Gerald Wallace', 'Brandan Wright', 'James Young',
'Tyler Zeller']

在抓取页面时,首先要做的是直观地检查使用urllib或请求收到的HTML:

import urllib2
url = 'http://espn.go.com/nba/team/roster/_/name/bos/boston-celtics'
response = urllib2.urlopen(url)
with open('/tmp/test.html', 'wb') as f:
    f.write(response.read())

有时HTML看起来与您在GUI浏览器中看到的不同,因为 urllib或requests不处理JavaScript。在那种情况下,其他工具,如 可能需要硒作为硒。但是,在这种情况下,文本搜索“布兰登 Bass“显示可以在使用urllib2下载的HTML中访问数据:

<td class="sortcell"><a href="http://espn.go.com/nba/player/_/id/2745/brandon-bass">Brandon Bass</a></td>

使用您发布的XPath作为起点, 然后,您可以使用交互式Python会话来查找正确的XPath:

In [80]: import lxml.html as LH
In [81]: import urllib2
In [82]: url = 'http://espn.go.com/nba/team/roster/_/name/bos/boston-celtics'
In [83]: doc = LH.parse(urllib2.urlopen(url))
In [84]: [LH.tostring(elt) for elt in doc.xpath('//div[@id="my-players-table"]/div//table/tr')]
Out[84]: 
['<tr class="stathead"><td colspan="8">Team Roster</td></tr>',
 '<tr class="colhead"><td><a href="http://espn.go.com/nba/team/roster/_/name/bos/sort/jersey/order/false/boston-celtics">NO.</a></td><td><a href="http://espn.go.com/nba/team/roster/_/name/bos/order/false/boston-celtics">NAME</a></td><td>POS</td><td><a href="http://espn.go.com/nba/team/roster/_/name/bos/sort/age/order/false/boston-celtics">AGE</a></td><td><a href="http://espn.go.com/nba/team/roster/_/name/bos/sort/height/order/false/boston-celtics">HT</a></td><td><a href="http://espn.go.com/nba/team/roster/_/name/bos/sort/weight/order/false/boston-celtics">WT</a></td><td>COLLEGE</td><td>2014-2015 SALARY</td></tr>',
In [86]: [elt.text_content() for elt in doc.xpath('//div[@id="my-players-table"]/div//table/tr/td')]

导致

//div[@id="my-players-table"]/div//table[1]//tr/td[2]/a/text()

(上面,我使用LH.tostring函数检查HTML代码段,elt.text_content()检查各种元素中包含的文本。)


这是我读过的first tutorial以了解XPath。

一旦掌握了基础知识,就可以开始阅读the XPath v1.0 specification了。还有一个XPath v2XPath v3,但是当前的lxml只支持XPath 1.0。

同时,您可以阅读lxml docs,假设您使用的是lxml。

我还发现阅读Stackoverflow XPath questions,例如this one,很有帮助。

每次遇到新功能或技术时,我都会写一些 演示代码 - 一个最小的例子 - 显示(我自己)它是如何工作的。 这样,每当我需要再次执行XYZ时,我可以从一些可运行的代码开始。