2016-12-23 80 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

相关问题