从 lxml xpath 查询操作列表

otr*_*rov 3 python xpath lxml

今天我尝试了 lxml,因为我从特定的 web 服务中得到了非常讨厌的 html 输出,我不想使用 re 模块,只是为了改变和学习新的东西。我做到了,并行浏览http://codespeak.net/lxml/http://stackoverflow.com

我不会试图解释上面的 html 模板,但只是为了概述它充满了故意嵌套的表格。

我用 html 解析器提取了感兴趣的部分,然后 find_class() 并用 xpath 遍历 TR(甚至这个 TR 里面都有表)。现在我正在尝试根据 class 和 id 属性提取数据对:

  • 名字孩子有类“标题”
  • 价值孩子有id“文本”

代码如下所示:

fragment = root.find_class('foo')

for node in fragment[0].xpath('table[2]/tr'):
    name = node.xpath('//div[@id="title"]')
    value = node.xpath('//td[@class="text"]')
Run Code Online (Sandbox Code Playgroud)

问题是并非我迭代的每个 TR 都有这些对:有些只有名称(id“title”),所以稍后当我尝试压缩它们时,我得到了错误的配对数据。

我尝试了几件事,但没有成功:我尝试比较列表长度(名称和值),如果它们不匹配跳过名称查找,那么如果它们不匹配,则删除最后一个列表项(在很多方面)但没有任何效果。例如:

if not len(name) == len(value):
    name.pop()
Run Code Online (Sandbox Code Playgroud)

或者

if len(name) == len(value):
    name = node.xpath('//div[@id="title"]')

value = node.xpath('//td[@class="text"]')
Run Code Online (Sandbox Code Playgroud)

一些经验丰富的评论?

Mat*_*ttH 5

这个怎么样?

from lxml import etree
doc = etree.HTML(open('test.data').read())

for t in doc.xpath('//table[.//div[@id="title"] and .//td[@class="text"]]'):
    print etree.tostring(t.xpath('.//div[@id="title"]')[0])
    print etree.tostring(t.xpath('.//td[@class="text"]')[0])
    print "--"
Run Code Online (Sandbox Code Playgroud)

产量:

<div id="title">
              <span class="Browse">string</span>
            </div>

<td class="text" style="padding-left:5px;">
            <a href="/***/***.dll?p=***&amp;sql=xxx:yyy">string</a>
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
            <a href="/***/***.dll?p=***&amp;sql=xxx:yyy">string</a>
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
            Gospodar of Lutaka
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
            1986
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
            Sep 1985-Dec 1985
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
            Elektra
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
            54:51
          </td>

--
<div id="title">
              <span>string</span>
            </div>

<td class="text" style="padding-left:5px;">
          </td>

--
Run Code Online (Sandbox Code Playgroud)

更新,扩展 xpath 表达式的前导部分以消除不需要的结果。感谢 Alejandro 指出这一点并提出了一个似乎对 otrov 不起作用的修复程序。

from urllib2 import urlopen
from lxml import etree
doc = etree.HTML(urlopen('http://pastebin.com/download.php?i=cg5HHJ6x').read())

for t in doc.xpath('//table/tr/td/table[.//div[@id="title"] and .//td[@class="text"]]'):
    print etree.tostring(t.xpath('.//div[@id="title"]')[0])
    print etree.tostring(t.xpath('.//td[@class="text"]')[0])
    print "--"
Run Code Online (Sandbox Code Playgroud)