javascript - 无法使用 Selenium(无头)检索 Javascript 图表后面的数据/数组
问题描述
我正在尝试在此网站上抓取历史“市场价值发展”图表:
https://www.transfermarkt.com/neymar/marktwertverlauf/spieler/68290
在得知它是 javascript 之后,我开始学习使用 webdrivers (Selenium)、无头浏览器和 Chrome/Chromium 来抓取 JS。检查页面后,我发现我可能正在寻找的 IDid_= 'yw0'
似乎包含图表:
鉴于此,这是我的代码:
import selenium as se
from selenium import webdriver
options = se.webdriver.ChromeOptions()
options.add_argument('headless')
driver = se.webdriver.Chrome(executable_path='/Applications/Utilities/chromedriver', chrome_options=options)
driver.get('https://www.transfermarkt.com/neymar/marktwertverlauf/spieler/68290')
element = driver.find_element_by_id(id_='yw0')
print(element)
当我运行它时,它会输出:
<selenium.webdriver.remote.webelement.WebElement (session="bd8e42834fcdd92383ce2ed13c7943c0", element="8df128aa-d242-40a0-9306-f523136bfe57")>
之后更改代码element
时
value = element.text
print(value)
我得到:
Current Market Value : 180,00 Mill. €
2010
2012
2014
2016
2018
50,0
100,0
150,0
200,0
这不是数据,而是图表间隔的 x 和 y 值。
我尝试了图表的不同 id 标签,看看我是否只是在识别错误的容器(例如 highcharts-0)。但我无法找到图表的实际数据值。
奇怪的是,在我运行我的代码后,图表会发生一些变化。图表“变宽”并超出图表的指定区域。它看起来像这样:
我想知道为了抓取图表上显示的数据点,我可以和需要在代码中进行哪些更改。
解决方案
您可以从 javascript 中对其进行正则表达式并进行一些字符串操作。您可以从下面获得字典列表。不需要硒。
import requests, re, ast
r = requests.get('https://www.transfermarkt.com/neymar/marktwertverlauf/spieler/68290', headers = {'User-Agent':'Mozilla/5.0'})
p = re.compile(r"'data':(.*)}\],")
s = p.findall(r.text)[0]
s = s.encode().decode('unicode_escape')
data = ast.literal_eval(s)
看第一个项目:
正则表达式:
tl;博士;
在加载时使用浏览器时,jQuery 从script
标签中提取图表信息,从而产生您所看到的内容。正则表达式提取相同的信息,即图表的相关系列信息,jQuery 从中获取系列。
硒:
这当然有改进的余地,但它展示了一般原则。当您将鼠标悬停在图表上的每个数据点上时,将从脚本标签中检索值以更新工具提示。检索到的值与图表点的 x、y 相关联。因此,您无法从查看工具提示信息的位置读取。相反,您可以单击每个数据点并从工具提示元素中获取更新的信息。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from bs4 import BeautifulSoup as bs
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument("--start-maximized")
url = 'https://www.transfermarkt.com/neymar/marktwertverlauf/spieler/68290'
d = webdriver.Chrome(options = options)
d.get(url)
WebDriverWait(d, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".as-oil__btn-optin"))).click()
markers = d.find_elements_by_css_selector('.highcharts-markers image')
time.sleep(1)
for marker in markers:
ActionChains(d).click_and_hold(marker).perform()
text = d.find_element_by_css_selector('div.highcharts-tooltip').text
while True:
if len(text) == 0:
ActionChains(d).click_and_hold(marker).perform()
else:
break
print(text)
推荐阅读
- c++ - memcpy 的奇怪行为
- reactjs - 使用 React 进行 Firebase Google 身份验证
- python - 通过 docker 文件挂载主机目录的问题,检索无法打开文件 .h5
- php - 无法使用 PHP 从 IIS Web 服务器的服务帐户连接到 SQL 2019
- laravel - Laravel 语言文件新添加的字符串不起作用
- python - Zeep:努力将 mustunderstand=1 添加到 WSE 标头
- php - 在 laravel 中获取用户当前位置
- c# - 读取 NameValueCollections 的 C# 列表的意外结果
- javascript - 根据另一个键的值验证两个字段之一是否存在或不存在
- python - 使用 python 在 SQLite3 中搜索变量