2015-04-05 192 views
0

我正試圖獲得公司名稱,部門和行業的股票。我下載了'https://finance.yahoo.com/q/in?s={}+Industry'.format(sign)的HTML,然後嘗試用.xpath()lxml.html解析它。這個XPath爲什麼不工作?

要獲取我試圖抓取的數據的XPath,我在Chrome中前往該網站,右鍵單擊該項目,單擊Inspect Element,右鍵單擊突出顯示的區域,然後單擊Copy XPath。這在過去一直適用於我。

import requests 
from lxml import html 

page_p = 'https://finance.yahoo.com/q/in?s=AAPL+Industry' 
name_p = '//*[@id="yfi_rt_quote_summary"]/div[1]/div/h2/text()' 
sect_p = '//*[@id="yfncsumtab"]/tbody/tr[2]/td[1]/table[2]/tbody/tr/td/table/tbody/tr[1]/td/a/text()' 
indu_p = '//*[@id="yfncsumtab"]/tbody/tr[2]/td[1]/table[2]/tbody/tr/td/table/tbody/tr[2]/td/a/text()' 

page = requests.get(page_p) 
tree = html.fromstring(page.text) 

name = tree.xpath(name_p) 
sect = tree.xpath(sect_p) 
indu = tree.xpath(indu_p) 

print('Name: {}\nSector: {}\nIndustry: {}'.format(name, sect, indu)) 

哪個給出了這樣的輸出:

這個問題可以用下面的代碼(我使用的是蘋果公司爲例)再現

Name: ['Apple Inc. (AAPL)'] 
Sector: [] 
Industry: [] 

它沒有遇到任何下載困難,因爲它能夠檢索name,但其他兩個不起作用。如果我有tr[1]/td/a/text()tr[1]/td/a/text()取代它們的路徑,分別是返回此:

Name: ['Apple Inc. (AAPL)'] 
Sector: ['Consumer Goods', 'Industry Summary', 'Company List', 'Appliances', 'Recreational Goods, Other'] 
Industry: ['Electronic Equipment', 'Apple Inc.', 'AAPL', 'News', 'Industry Calendar', 'Home Furnishings & Fixtures', 'Sporting Goods'] 

很顯然,我可以只切出來的第一個項目每個列表中獲得我所需要的數據。

我不明白的是,當我添加tbody/開始(//tbody/tr[#]/td/a/text())再次失敗,即使在Chrome控制檯清楚地表明這兩個tr S作爲是一個tbody元素的兒童。

Chrome console showing HTML hierarchy

爲什麼會出現這種情況?

回答

4

瀏覽器解析HTML並從中構建元素樹;在那個過程中,他們會插入輸入HTML文檔中可能丟失的元素。

在這種情況下,<tbody>元素不在源代碼HTML中。您的瀏覽器會插入它們,因爲如果缺失,它們將隱含在結構中。但是LXML不會插入它們。

您的瀏覽器工具並不是用於構建XPath查詢的最佳工具。

卸下tbody/路徑元素產生你正在尋找的結果:

>>> sect_p = '//*[@id="yfncsumtab"]/tr[2]/td[1]/table[2]/tr/td/table/tr[1]/td/a/text()' 
>>> indu_p = '//*[@id="yfncsumtab"]/tr[2]/td[1]/table[2]/tr/td/table/tr[2]/td/a/text()' 
>>> tree.xpath(sect_p) 
['Consumer Goods'] 
>>> tree.xpath(indu_p) 
['Electronic Equipment']