【问题标题】:XPath syntax with PythonPython 的 XPath 语法
【发布时间】:2015-02-23 05:24:30
【问题描述】:

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,或者更具体地说,在与 Python 一起使用时掌握 Xpath?我想知道是否阅读文档,因为我不确定他们是否有相关示例,但如果有,我很乐意看看。

谢谢大家,圣诞快乐

顺便说一句:我要剖析的链接http://espn.go.com/nba/team/roster/_/name/bos/boston-celtics

【问题讨论】:

    标签: python xpath


    【解决方案1】:
    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 或 requests 接收到的 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。在这种情况下,其他工具,例如 作为硒,可能需要。但是,在这种情况下,文本搜索“Brandon 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 sn-ps,并使用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 时,我都可以从一些可运行的代码开始。

    【讨论】:

      猜你喜欢
      • 2014-07-26
      • 1970-01-01
      • 2018-10-13
      • 2021-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      相关资源
      最近更新 更多