2013-04-30 73 views
2

我使用Python和lxml從彭博網站上刮取ETF和共同基金的數據。我試圖從中提取數據的頁面示例是http://www.bloomberg.com/markets/funds/country/usa/Python/lxml網頁抓取:處理空白條目

對於每個基金,我需要符號,名稱,基金類型和目標。我沒有任何問題刮取符號,名稱或基金類型。但是,我對目標有困難。你會在我引用的網頁(和後續頁面)上看到目標是空白的。在頁面上最後這個基金的HTML看起來像:

<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,開放式基金,封閉式基金等),第四列有目標(增長,價值,收入等)。對於這個特定的基金,目標不見了。

我使用以提取基金目標(最後一列)中的代碼是:

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」)?我願意處理這些不需要的標籤,因爲它們很容易刪除。

+1

沒有答案,但你一定要看看[Scrapy](https://scrapy.readthedocs.org/en/0.16/intro/tutorial.html)。 – Blender 2013-05-01 00:04:28

回答

3

不要文本節點明確匹配 - 剛剛得到的節點的文本值:

doc.xpath(u'string(.//tr[td[contains (@*, "name")]]/following-sibling::td)') 

或者你也可以做同樣的Python端:

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

不過我認爲你的做法是錯誤的。不是獲取四個不同的列表並將它們壓縮在一起,找到容器行,然後一次獲取該上下文中的項目。下面是一個完整的實現:

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上下文。