我正在尝试从here获取玩家名称和FP列。通常,当我需要表信息时,我可以使用Dataframe
将其加载到pandas
,或至少使用find_all()
运行bs4
方法。我找到了一个推荐这样的页面:
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)
但这没有用,如果有人有一些指导我会非常感激。
答案 0 :(得分: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')