更简单的方法来抓取这个困难的网站?

Easier Way To Scrape This Difficult Site?

我正在尝试从 here 中获取玩家姓名和 FP 列。通常,当我需要 table 信息时,我可以使用 pandas 或至少 运行 使用 bs4 方法将其加载到 Dataframe 中。我找到了一个推荐这样的页面:

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)

但这没有用,如果有人能提供一些指导,我将不胜感激。

这其实是个好问题。

首先,在深入研究解决方案之前,请务必研究 "Terms of Service" and understand if you are allowed to scrape the resource this way, be a good 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 评分有点棘手 - 它们与实际 "player" table 分开,但是,我们可以 "connect" 通过使用 data-player-id独有的属性。首先,我们解析 fp 评分并构建一个 "player_id" -> "fp value" 字典。然后,浏览 "player" table,抓取其余信息并查找包含 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.

的使用