如何在Selenium Python中从JSON中提取数据

6

我的页面返回JSON HTTP响应,其中包含id:14

在Selenium Python中是否有一种方法可以抓取它?我搜索了网络,但找不到任何解决方案。现在我想知道可能根本就不可能吗?虽然我可以从数据库中获取此ID,但我正在尝试避免这样做。请告诉我是否有任何解决方法。谢谢。


你可以使用 driver.page_source 查看页面的源代码。但如果响应的格式是纯 JSON,是否有必要使用 Selenium?或者你可以使用更轻量级的东西(例如 requestsurllib2 等)来代替吗? - Alex Woolford
Selenium在这里是必要的,因为我正在运行一个基于Selenium的测试,需要那个变量。 - Nro
3个回答

22
你遇到的问题是,当浏览器返回原始的JSON数据时,它会将其包装在一小段HTML代码中,以便在屏幕上向用户显示。例如,当我在Firefox中访问https://httpbin.org/user-agent时,以下原始JSON数据将出现在我的浏览器窗口中:
{"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0"
}

但事实上,Firefox(和Chrome)为了创建可以显示的文档,将JSON包装在一些额外的HTML中。这是Firefox包装它的HTML,我可以通过评估表达式document.documentElement.innerHTML在JavaScript控制台中看到:

<head><link rel="alternate stylesheet" type="text/css"
 href="resource://gre-resources/plaintext.css" title="Wrap Long Lines"></head>
 <body><pre>{"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:42.0)
 Gecko/20100101 Firefox/42.0"
}
</pre></body>

使用BeautifulSoup来解析HTML,正如另一个回答中所建议的那样,有两个严重的缺点:它会引入新的项目依赖,并且与利用浏览器已经为您解析HTML并准备好您使用的DOM相比,速度也会相当慢。
要求浏览器为您提取JSON,只需请求<body>元素内部的文本,浏览器添加的所有额外结构都将被排除,纯粹的JSON将被返回。
driver.find_element_by_tag_name('body').text

或者,如果您希望将其解析为Python数据结构:

import json
json.loads(driver.find_element_by_tag_name('body').text)

1
这显然是一个更好的解决方案!顺便说一句,我喜欢你的 PyCon 视频,Brandon。 - RobinL
1
同样的Selenium+Splinter:br.find_by_tag('body').text(而不是br.html) - mirek

6
您可以使用BeautifulSoup解析页面并提取json数据。您需要的代码应该类似于这样。如果json不直接在响应主体中,则可能需要更改soup.find命令。
from bs4 import BeautifulSoup
import json

soup = BeautifulSoup(driver.page_source)
dict_from_json = json.loads(soup.find("body").text)

2
请求Python解析原始HTML不仅需要额外的第三方库,而且与让浏览器进行解析相比会相当缓慢。 - Brandon Rhodes

0

其他解决方案对我无效。我发现使用requests的这个解决方案快速且简单:

import requests
requests.get(browser.current_url).json()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接