【问题标题】:Scraping new ESPN site using xpath [Python]使用 xpath [Python] 抓取新的 ESPN 站点
【发布时间】:2025-12-27 23:50:06
【问题描述】:

我正在尝试抓取新的 ESPN NBA 记分牌。这是一个简单的脚本,它应该返回 15 年 4 月 5 日所有游戏的开始时间:

import requests
import lxml.html
from lxml.cssselect import CSSSelector

doc =  lxml.html.fromstring(requests.get('http://scores.espn.go.com/nba/scoreboard?date=20150405').text)

#xpath
print doc.xpath("//title/text()") #print page title
print doc.xpath("//span/@time")
print doc.xpath("//span[@class='time']")
print doc.xpath("//span[@class='time']/text()")

#CCS Selector
sel = CSSSelector('span.time')
for i in sel(doc):
    print i.text

它不返回任何内容,而是返回页面标题:

['NBA Basketball Scores - NBA Scoreboard - ESPN']
[]
[]
[]

有人可以帮忙吗?谢谢

【问题讨论】:

标签: python xpath web-scraping lxml lxml.html


【解决方案1】:

页面的本质是动态的 - 有异步 XHR 请求,涉及到 javascript 逻辑。 requests 不是浏览器,仅下载初始 HTML 页面,requests 获取的 HTML 中没有带有 class="time"span 元素。

解决该问题的一种方法是让真正的浏览器使用selenium。以下是使用PhantomJS 无头浏览器的示例:

>>> from selenium import webdriver
>>> 
>>> url = "http://scores.espn.go.com/nba/scoreboard?date=20150405"
>>> 
>>> driver = webdriver.PhantomJS()
>>> driver.get(url)
>>> 
>>> elements = driver.find_elements_by_css_selector("span.time")
>>> for element in elements:
...     print element.text
... 

1:00 PM ET
3:30 PM ET
6:00 PM ET
7:00 PM ET
7:30 PM ET
9:00 PM ET
9:30 PM ET 

或者,您可以使用id="scoreboard-page"divdata-data 属性中查找所需数据:

import json
from pprint import pprint

import lxml.html
import requests

response = requests.get('http://scores.espn.go.com/nba/scoreboard?date=20150405')
doc = lxml.html.fromstring(response.content)

data = doc.xpath("//div[@id='scoreboard-page']/@data-data")[0]
data = json.loads(data)

pprint(data)

【讨论】:

  • 感谢您的解决方案。还有哪些不涉及使用真实浏览器的选项?
  • 这太好了,谢谢。我希望我能给你 2 个正确的答案检查!
  • 这是一个非常好的答案!