Python 美丽的汤-在特定页面上遇到问题

Python 美丽的汤-在特定页面上遇到问题,python,web-scraping,beautifulsoup,Python,Web Scraping,Beautifulsoup,在过去,我已经成功地使用了美丽的汤(我仍在学习如何使用它),但我被困在如何获得这张特定的桌子上: 在过去,这很简单: url = 'https://fantasydata.com/nfl-stats/point-spreads-and-odds? season=2017&seasontype=1&week=1' html = requests.get(url) soup = BeautifulSoup(html.text, "html.parser") 或 但是表中没有

在过去,我已经成功地使用了美丽的汤(我仍在学习如何使用它),但我被困在如何获得这张特定的桌子上:

在过去,这很简单:

url = 'https://fantasydata.com/nfl-stats/point-spreads-and-odds?   season=2017&seasontype=1&week=1' 
html = requests.get(url)
soup = BeautifulSoup(html.text, "html.parser")

但是表中没有任何数据需要从页面源解析

有没有更好的方法来处理这道漂亮的汤

编辑:

好的,所以我回去做了:

driver = webdriver.Chrome()
page_url = 'https://fantasydata.com/nfl-stats/point-spreads-and-odds?season=2017&seasontype=1&week=1' %(year,nfl_week)
driver.get(page_url)
soup = BeautifulSoup(driver.page_source, "lxml")
再说一遍。这一次,数据显示出来了。我认为,由于它是加载的,所以使用Selenium是正确的方法,但当它不起作用时,就被抛弃了


你知道为什么第一次没用吗?在加载页面之前,我没有关闭浏览器或任何东西。

您不需要使用BeautifulSoup或Selenium。在
发布
查询到
https://fantasydata.com/NFLTeamStats/Odds_Read

query = {  # just mimicking sample query that I saw after loading your link
    'page': 1,
    'pageSize': 50,
    'filters.season': 2017,
    'filters.seasontype': 1,
    'filters.week': 1,
}
response = requests.post('https://fantasydata.com/NFLTeamStats/Odds_Read', data=query)
data = response.json()
data
{'Data': [{'Date': 'September 7, 2017 8:30 PM', 'Favorite': 'at Patriots', 'PointSpread': '-9.0', 'UnderDog': 'Chiefs', 'OverUnder': '48.0', 'AwayTeamMoneyLine': '+400', 'HomeTeamMoneyLine': '-450'}, {'Date': 'September 10, 2017 1:00 PM', 'Favorite': 'Buccaneers', 'PointSpread': '-2.5', 'UnderDog': 'at Dolphins', 'OverUnder': '41.5', 'AwayTeamMoneyLine': '-140', 'HomeTeamMoneyLine': '+120'}, {'Date': 'September 10, 2017 1:00 PM', 'Favorite': 'at ...  
通过研究Chrome开发者工具(push F12)的网络部分,特别是XHR小节,您可以找到这种方法:

您不需要使用BeautifulSoup或Selenium。在
发布
查询到
https://fantasydata.com/NFLTeamStats/Odds_Read

query = {  # just mimicking sample query that I saw after loading your link
    'page': 1,
    'pageSize': 50,
    'filters.season': 2017,
    'filters.seasontype': 1,
    'filters.week': 1,
}
response = requests.post('https://fantasydata.com/NFLTeamStats/Odds_Read', data=query)
data = response.json()
data
{'Data': [{'Date': 'September 7, 2017 8:30 PM', 'Favorite': 'at Patriots', 'PointSpread': '-9.0', 'UnderDog': 'Chiefs', 'OverUnder': '48.0', 'AwayTeamMoneyLine': '+400', 'HomeTeamMoneyLine': '-450'}, {'Date': 'September 10, 2017 1:00 PM', 'Favorite': 'Buccaneers', 'PointSpread': '-2.5', 'UnderDog': 'at Dolphins', 'OverUnder': '41.5', 'AwayTeamMoneyLine': '-140', 'HomeTeamMoneyLine': '+120'}, {'Date': 'September 10, 2017 1:00 PM', 'Favorite': 'at ...  
通过研究Chrome开发者工具(push F12)的网络部分,特别是XHR小节,您可以找到这种方法:

好吧,我四处窥探了一下,有人打了我一下!!!我做了与另一个答案相同的事情,但在Firefox开发工具(ctrl+shift+k组合)中,与另一个答案一样,使用网络选项卡的
xhr
部分。似乎在站点上填充表的API调用是对
POST
的请求https://fantasydata.com/NFLTeamStats/Odds_Read
。下面是一个包含所有可用参数的
js
对象:

{
filter:,    
filters.endweek:,
filters.exportType:,
filters.leaguetype:,
filters.minimumsnaps:,
filters.playerid:,
filters.position:,
filters.scope:,
filters.scoringsystem:,
filters.searchtext:,
filters.season: 2017,
filters.seasontype: 1,
filters.startweek:,
filters.stattype:,
filters.subscope:,
filters.team:,
filters.teamaspect:,
filters.week: 1,
group:,
page: 1,
pageSize: 50,
sort:
}

POST
的主体将是一个类似于上面的
json
对象。如果它们不阻止跨源请求,您可以直接使用Python请求库。如果它们确实阻止了跨源请求,您可以尝试模仿它们设置的标题和选项,或者,我忘了怎么做了,但我知道您可以从页面向selenium注入javascript AJAX请求。作为旁注,如果您想在Python中自动执行异步
js
操作,您必须使用
webDriverWait
或其他异步代码等待响应。

好的,所以我四处窥探了一下,有人打败了我!!!我做了与另一个答案相同的事情,但在Firefox开发工具(ctrl+shift+k组合)中,与另一个答案一样,使用网络选项卡的
xhr
部分。似乎在站点上填充表的API调用是对
POST
的请求https://fantasydata.com/NFLTeamStats/Odds_Read
。下面是一个包含所有可用参数的
js
对象:

{
filter:,    
filters.endweek:,
filters.exportType:,
filters.leaguetype:,
filters.minimumsnaps:,
filters.playerid:,
filters.position:,
filters.scope:,
filters.scoringsystem:,
filters.searchtext:,
filters.season: 2017,
filters.seasontype: 1,
filters.startweek:,
filters.stattype:,
filters.subscope:,
filters.team:,
filters.teamaspect:,
filters.week: 1,
group:,
page: 1,
pageSize: 50,
sort:
}

POST
的主体将是一个类似于上面的
json
对象。如果它们不阻止跨源请求,您可以直接使用Python请求库。如果它们确实阻止了跨源请求,您可以尝试模仿它们设置的标题和选项,或者,我忘了怎么做了,但我知道您可以从页面向selenium注入javascript AJAX请求。作为旁注,如果要在Python中自动执行async
js
InAction,则必须使用
webDriverWait
或其他一些异步代码等待响应。

页面加载后由javascripts填充的表。我在过去所做的工作是将驱动器驱动到页面,然后使用jQuery注入一个API调用。我相信还有很多其他选择。谢谢。我实际上是在使用selenium,因为我记得在页面加载后遇到了填充表的问题。我在这里遇到了麻烦,因为我像往常一样做了,但这次它工作不正常。最后我又试了几次,结果成功了。我我不确定最初的问题出在哪里。加载页面后,该表将由Java脚本填充。我在过去所做的工作是将驱动器驱动到页面,然后使用jQuery注入一个API调用。我相信还有很多其他选择。谢谢。我实际上是在使用selenium,因为我记得在页面加载后遇到了填充表的问题。我在这里遇到了麻烦,因为我像往常一样做了,但这次它工作不正常。最后我又试了几次,结果成功了。我我不确定最初的问题出在哪里。如果他们对http请求有相同的源策略,那么进行API调用就不会这么简单了。这个API可能不是这样,但我去过一些网站,在那里,只使用selenium比尝试和模仿绕过CORS块所需的选项/头/cookie更容易。如果它们对http请求具有相同的源策略,那么进行API调用就不会这么简单了。这个API可能不是这样,但我去过一些网站,在那里,只使用selenium比尝试模仿绕过CORS块所需的选项/标题/cookie更容易。