如何从跨度标签中提取值

Posted

技术标签:

【中文标题】如何从跨度标签中提取值【英文标题】:How to extract value from span tag 【发布时间】:2019-08-31 07:25:47 【问题描述】:

我正在编写一个简单的网络爬虫来提取 ncaa 篮球比赛的比赛时间。代码不需要漂亮,只需工作即可。我已经从同一页面上的其他 span 标签中提取了值,但由于某种原因,我无法让这个标签正常工作。

from bs4 import BeautifulSoup as soup
import requests

url = 'http://www.espn.com/mens-college-basketball/game/_/id/401123420'
response = requests.get(url)
soupy = soup(response.content, 'html.parser')

containers = soupy.findAll("div","class" : "team-container")
for container in containers:
    spans = container.findAll("span")
    divs = container.find("div","class": "record")
    ranks = spans[0].text
    team_name = spans[1].text
    team_mascot = spans[2].text
    team_abbr = spans[3].text
    team_record = divs.text
    time_container = soupy.find("span", "class":"time game-time")
    game_times = time_container.text
    refs_container = soupy.find("div", "class" : "game-info-note__container")
    refs = refs_container.text
    print(ranks)
    print(team_name)
    print(team_mascot)
    print(team_abbr)
    print(team_record)
    print(game_times)
    print(refs)

我关心的具体代码是这个,

 time_container = soupy.find("span", "class":"time game-time")
    game_times = time_container.text

我只是提供了其余的代码来显示其他跨度标签上的 .text 有效。时间是我真正想要的唯一数据。我只是得到一个空字符串,其中包含我的代码当前的状态。

这是我调用 time_container 时得到的代码输出

<span class="time game-time" data-dateformat="time1" data-showtimezone="true"></span>

或者当我做 game_times 时只是 ''。

这是来自网站的 HTML 行:

<span class="time game-time" data-dateformat="time1" data-showtimezone="true">6:10 PM CT</span>

我不明白为什么运行脚本时下午 6:10 消失了。

【问题讨论】:

如果这是由 javascript 填充的,您将无法使用 BeautifulSoup 获取它。 【参考方案1】:

该站点是动态的,因此,您需要使用selenium

from selenium import webdriver
d = webdriver.Chrome('/path/to/chromedriver')
d.get('http://www.espn.com/mens-college-basketball/game/_/id/401123420')
game_time = soup(d.page_source, 'html.parser').find('span', 'class':'time game-time').text

输出:

'7:10 PM ET'

查看完整的selenium 文档here。

【讨论】:

太棒了,谢谢!我没有想到。我对此很陌生,这是我第一次尝试。 @zezima 很高兴为您提供帮助! @Reedinationer 谢谢,我添加了帖子的链接。 甜蜜。虽然它不是官方文档,但它并没有让我误入歧途,我发现它比你的链接更容易导航 完美运行!我有一个循环来抓取 61 页,所以我注意到我的运行时间增加了很多。不知道是不是我自己的错误。【参考方案2】:

另一种方法是使用 ESPN 的一些端点。这些端点将返回 JSON 响应。 https://site.api.espn.com/apis/site/v2/sports/basketball/mens-college-basketball/scoreboard

您可以在此 GitHub 链接 https://gist.github.com/akeaswaran/b48b02f1c94f873c6655e7129910fc3b 上查看其他端点

与运行 Selenium 相比,这将使您的应用程序的重量非常轻。

我建议打开检查并转到网络选项卡。你可以看到各种很酷的事情正在发生。您可以查看站点中发生的所有请求。

【讨论】:

【参考方案3】:

您可以通过请求轻松地从页面上的属性中获取

import requests
from bs4 import BeautifulSoup as bs
from dateutil.parser import parse

r = requests.get('http://www.espn.com/mens-college-basketball/game/_/id/401123420')
soup = bs(r.content, 'lxml')
timing = soup.select_one('[data-date]')['data-date']
print(timing)
match_time = parse(timing).time()
print(match_time)

【讨论】:

谢谢!!昨晚运行我的脚本后,我意识到 selenium 将运行时间增加了很多(除非我做错了什么,这绝对是可能的)。我在 61 页之间刮了一遍,也意识到标准时间会更好。我很高兴我学会了使用硒,但是我认为这就是我要做的。感谢您为我节省了一些 Google 时间!

以上是关于如何从跨度标签中提取值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jQuery 为跨度设置值

遍历 HTML div 并使用 JavaScript 或 jQuery 从子跨度中提取值

有没有办法使用 Power Query 从跨度中提取“标题”属性内容?

如何通过 Selenium 和 Python 从 html 标签跨度获取文本

如何在 PL/SQL 中使用 FOR LOOP 从具有相同标签的 xml clob 中提取值

如何提取和忽略标记中的跨度? - Python