2016-01-04 46 views
1

不幸的是,我是XPath的初學者,並沒有完全確定ir是如何工作的。對於我的一個項目,我正在尋找一種解析9列表格的5列的方法。這裏是我迄今爲止的工作是什麼:python xpath表中的一些但不是全部列

url="".join(["http://www.basketball-reference.com/leagues/NBA_2011_games.html"]) 

#getting the columns 4-7 
page=requests.get(url) 
tree=html.fromstring(page.content) 
# the //text() is because some of the entries are inside <a></a>s 
data = tree.xpath('//table[@id="games"]/tbody/tr/td[position()>3 and position()<8]//text()') 

所以我的解決辦法的想法是什麼,是剛剛得到另一個列表中只獲得了第一個欄,然後在不過一個額外的步驟兩者結合,似乎unelgegant和不必要。

的XPath的我試圖到目前爲止

//table[@id="games"]/tbody/tr/td[position() = 1]/text() | //table[@id="games"]/tbody/tr/td[position()>3 and position()<8]//text() 

這還不包括第一列(日期)太莫名其妙。 (根據w3schools)|是連接兩個XPath語句的運算符。

所以這裏是我現在的完整代碼。這些數據現在將被放入兩個列表中。

希望我沒有做太笨的事,謝謝你的幫助。

from lxml import html 
import requests 


url="".join(["http://www.basketball-reference.com/leagues/NBA_1952_games.html"]) 

page=requests.get(url) 
tree=html.fromstring(page.content) 
reg_data = tree.xpath('//table[@id="games"]/tbody/tr/td[position() = 1]/text() | //table[@id="games"]/tbody/tr/td[position()>3 and position()<8]//text()') 
po_data = tree.xpath('//table[@id="games_playoffs"]/tbody/tr/td[position() = 1]/text() | //table[@id="games_playoffs"]/tbody/tr/td[position()>3 and position()<8]//text()') 
n=int(len(reg_data)/5) 

if int(year) == 2016: 
    for i in range(0,len(reg_data)): 
     if len(reg_data[i])>3 and len(reg_data[i+1])>3: 
      n = int((i)/5) 
      break  

games=[] 
for i in range(0,n): 
    games.append([]) 
    for j in range(0,5): 
     games[i].append(reg_data[5*i+j]) 

po_games=[] 
m=int(len(po_data)/5) 
if year != 2016: 
    for i in range(0,m): 
     po_games.append([]) 
     for j in range(0,5): 
      po_games[i].append(po_data[5*i+j]) 

print(games) 
print(po_games) 

回答

0

它看起來像一個很大的數據包在鏈接(一)標籤,這樣,當你所要求的文本節點孩子,你是不是因爲你需要去深入一層找到任何。

代替

/text() 

//text() 

的兩條斜線裝置來選擇文本(),它們是在任何級別decendants節點。

您也可以結合整個表達式爲

//table[@id="games"]/tbody/tr/td[position() = 1 or (position()>3 and position()<8)]//text() 

而不是有兩個表達式。

我們甚至可以進一步縮短到

//table[@id="games"]//td[position() = 1 or (position()>3 and position()<8)]//text() 

但這種表達的危險,因爲它會拿起其中的任何地方發生的表(只要他們是第一次TD元素,第4,第5 ,第6或第7列),而不僅僅是在身體的行中。然而,在你的目標中,這將起作用。

還要注意,像[position()=1]這樣的表達式是沒有必要的。你可以縮短到[1]。如果您需要上下文節點以外的節點的位置,則只需要位置函數,或者需要編寫更復雜的選擇,就像我們在需要不止一個特定索引時那樣。

相關問題