在 python 中使用 lxml 和 xpath 解析站点

Issue Parsing a site with lxml and xpath in python

我想我弄乱了我的 xpath。我想要做的是获取此页面中 table 上每一行的信息。

这是我目前所拥有的,但它没有输出我正在寻找的内容。

import requests
from lxml import etree

r = requests.get('http://mtgoclanteam.com/Cards?edition=DTK')
doc = etree.HTML(r.text)
#get list of cards
cards = [card for card in doc.xpath('id("cardtable")/x:tbody/x:tr[1]/x:td[3]')]
for card in cards:
    print card

这里的主要问题是服务器提供的实际文档包含一个空 table:

<table id="cardtable" class="cardlist"/>

页面加载后由空 table 元素后面的嵌入 javascript 填充数据:

<script>
    $('#cardtable').dataTable({
        "aLengthMenu": [[25, 100, -1], [25, 100, "All"]],


        "bDeferRender": true,
        "aaSorting": [],


        "bPaginate": false,
        "aaData": [
          ...DATA IS HERE...
        ],
        "aoColumns": [
            { "sTitle": "Card name", "sWidth": "260" },

                    { "sTitle": "Rarity", "sWidth": "40" },

            { "sTitle": "Buy", "sWidth": "80" },
            { "sTitle": "Sell", "sWidth": "80" },
            { "sTitle": "Bots with stock" }]

    })
</script>

数据本身包含在字典的 aaData 元素中 传递给 dataTable() 方法。在 Python 中提取 会很棘手(这不仅仅是一个 JSON 文档)。可能是一个 suitable 应用于脚本文本的正则表达式会让你 你想要什么(或者只是遍历脚本的行并在 aaData 键之后取一个)。

例如:

import pprint
import json
import requests
from lxml import etree

r = requests.get('http://mtgoclanteam.com/Cards?edition=DTK')
doc = etree.HTML(r.text)

script = doc.xpath('id("templatemo_content")/script')[0].text
found = False
result = None
for line in script.splitlines():
    if found:
        if '[' in line:
            result=line
            break
    if 'aaData' in line:
        found = True

if result:
    result =json.loads('[' + result + ']')
    pprint.pprint(result)

这是丑陋和脆弱的(如果脚本的格式,它会破坏 已更改),但它适用于当前输入。