首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python/lxml web抓取:处理空白条目

Python/lxml web抓取:处理空白条目
EN

Stack Overflow用户
提问于 2013-05-01 07:56:52
回答 1查看 1.4K关注 0票数 2

我正在使用Python和lxml从Bloomberg网站上抓取ETF和共同基金的数据。我试图从其中抓取数据的页面的一个示例是http://www.bloomberg.com/markets/funds/country/usa/

对于每个基金,我需要符号、名称、基金类型和目标。我在抓取符号、名称或基金类型时没有任何问题。然而,我在目标上遇到了困难。在我引用的网页(以及后续页面)上,你会看到目标是空白的。页面上最后一只基金的HTML如下所示:

代码语言:javascript
复制
    <tr class='tkr_alt'>
    <td class="name">
    <a href="/quote/ADTKEX:US"><span>Advisor Disciplined Trust 193 - Taxable Municipal Bond Portfolio - Series 1</span> (ADTKEX)</a></td>
    <td class="symbol">ADTKEX:US</td>
    <td>UIT</td>
    <td></td>
    </tr>

第一列有基金名称,第二列有股票代码,第三列有基金类型(ETF、UIT、开放式基金、封闭式基金等),第四列有目标(增长、价值、收益等)。对于这个特殊的基金来说,目标是缺失的。

我用来提取基金目标(最后一列)的代码是:

代码语言:javascript
复制
    result = urllib.urlopen(filename)
    element_html = result.read()
    doc = lxml.html.document_fromstring (element_html)
    list_obj = doc.xpath (u'.//tr[td[contains (@*, "name")]]/following-sibling::td/text()')

此代码将资金目标复制到一个数组中。不幸的是,代码完全忽略了缺少条目的事实。因此,名称、符号和基金类型的列表将分别具有X个元素,但用于目标的列表将仅具有X-1个元素。

如何让脚本识别空条目并提供nil或'‘数组元素?

有没有办法捕获整个列条目(看起来像"blahblahblah")?我愿意处理这些不需要的标签,因为它们很容易删除。

EN

回答 1

Stack Overflow用户

发布于 2013-05-01 08:23:52

不要显式地匹配text节点--只需获取该节点的文本值:

代码语言:javascript
复制
doc.xpath(u'string(.//tr[td[contains (@*, "name")]]/following-sibling::td)')

或者,您可以在Python端执行相同的操作:

代码语言:javascript
复制
tds = doc.xpath(u'.//tr[td[contains (@*, "name")]]/following-sibling::td')
etree.tostring(tds[0], method="text")

然而,我认为你的方法是错误的。不是获取四个不同的列表并将它们压缩在一起,而是找到容器行,然后一次性获取该上下文中的所有项。下面是一个完整的实现:

代码语言:javascript
复制
from lxml import etree
from collections import namedtuple

Fund = namedtuple('Fund', 'name symbol type objective')

def astext(elem):
    "Return stripped text value of element"
    return etree.tostring(elem, method='text').strip()

url = 'http://www.bloomberg.com/markets/funds/country/usa/'
xpfundrows = u"//table[@class='ticker_data']/descendant::tr[td[1][@class='name']]"


doc = etree.parse(url, etree.HTMLParser())

funds = []
for row in doc.xpath(xpfundrows):
    cells = row.findall('td')
    fund = Fund(astext(cell) for cell in cells)
    funds.append(fund)

print funds

您可以在内部循环中更加谨慎(例如,对每一位数据使用name = row.xpath("td[@class='name']"),依此类推),但基本原则是相同的--将搜索锚定到tr上下文。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16310803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档