2016-12-23 81 views
1

我試圖從here搶玩家名稱和FP列。通常,當我需要表格信息時,我可以使用pandas將其加載到Dataframe中,或者至少使用bs4運行find_all()方法。我發現一個頁面,推薦這樣的:更簡單的方法來刮這個困難的網站?

import requests 
from bs4 import BeautifulSoup 

scrape_url ='http://www.numberfire.com/nba/fantasy/full-fantasy-basketball-projections' 
page = requests.get(scrape_url, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}) 

soup = BeautifulSoup(page.content, "html5lib") 

script = soup.find('script', text=lambda x: x and 'NF_DATA' in x).text 
data = re.search(r'NF_DATA = (.*?);', script).group(1) 
data = json.loads(data) 
print(data) 

但沒有工作,如果任何人有一定的指導我將不勝感激。

回答

3

這實際上是一個很好的問題。

首先,在深入研究解決方案之前,請務必研究"Terms of Service"並瞭解是否允許您以這種方式刮取資源,成爲好的web-scraping citizen


的問題是,現場檢查,如果被驗證,如果沒有,那就設置NF_DATA喜歡的東西:

{u'is_logged_in': False, u'FACEBOOK_APP_NAMESPACE': u'numberfire', u'FACEBOOK_APP_ID': u'103292676390270'} 

但是,如果你在瀏覽器中同時打開頁面沒有經過驗證或將研究page.content,您會看到所需的數據實際上存在於HTML中 - 您可以直接刮取它,不需要通過解析script標記內容。

獲得fp評分有點棘手 - 它們與實際的「玩家」表分開,但我們可以通過使用data-player-id唯一屬性將它們「連接」在一起。首先,我們解析fp評級並構建「player_id」 - >「fp值」字典。然後,通過「玩家」表格,刮取其餘的信息,並查找包含fp值的字典。

實現:

# parse fp ratings 
ratings = {player['data-player-id']: player.select_one(".fp.active").get_text(strip=True) 
      for player in soup.select("table.projection-table.no-fix tr[data-player-id]")} 

# parse player info 
for player in soup.select("table.projection-table.projection-table--fixed tr[data-player-id]"): 
    player_name = player.select_one(".player-info a.full").get_text(strip=True) 
    fp_rating = ratings.get(player['data-player-id']) 

    print(player_name, fp_rating) 

打印:

(u'Russell Westbrook', u'55.1') 
(u'Anthony Davis', u'49.3') 
(u'DeMarcus Cousins', u'48.9') 
(u'James Harden', u'48.4') 
(u'LeBron James', u'48.3') 
... 
(u'Tim Hardaway Jr.', u'0.0') 
(u'Kyle Korver', u'0.0') 
(u'Dwight Howard', u'0.0') 
(u'Reggie Williams', u'0.0') 

注意使用CSS selector select() and select_one() methods

相關問題