javascript - 无法使用 Selenium( headless )检索 Javascript 图表背后的数据/数组

标签 javascript python selenium web-scraping raphael

我正在尝试通过网络抓取本网站上的历史“市场值(value)发展”图表:

https://www.transfermarkt.com/neymar/marktwertverlauf/spieler/68290

在了解到它是 javascript 之后,我开始学习使用网络驱动程序 (Selenium)、 headless 浏览器和 Chrome/Chromium 来抓取 JS。检查页面后,我发现我可能正在寻找的 ID 是 id_= 'yw0',它似乎包含图表:

enter image description here

鉴于此,这是我的代码:

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")>

元素后的代码更改为

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)。但我无法找到图表的实际数据值。

奇怪的是,在我运行我的代码后图表发生了一些变化。图表“变宽”并超出图表的指定区域。它看起来像这样:

enter image description here

我想知道为了抓取显示在图表上的数据点,我可以并且需要更改代码中的哪些内容。

最佳答案

您可以从 javascript 中对其进行正则表达式处理并进行一些字符串操作。您可以从下面获得字典列表。不需要 Selenium 。

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)

查看第一项:

enter image description here


正则表达式:

enter image description here


tl;dr;

在加载时使用浏览器时,jQuery 从 script 标签中提取图表信息,从而生成您所看到的内容。正则表达式从 jQuery 获取系列的地方提取相同的信息,即图表的相关系列信息。

enter image description here


Selenium :

这当然有改进的余地,但它展示了一般原则。当您将鼠标悬停在图表上的每个数据点上时,会从脚本标签中检索这些值以更新工具提示。检索到的值与图表点的 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)

关于javascript - 无法使用 Selenium( headless )检索 Javascript 图表背后的数据/数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57247036/

相关文章:

python - 默认字典/按分钟排序

django - Docker、Django 和 Selenium - Selenium 无法连接

java - Selenium 找不到定位器

javascript - Phantomjs 使用 ruby​​-selenium 处理 onclick 事件

javascript - 自动 Iframe 高度

javascript - 为什么 "_"未定义而 "x"是 javascript 中的引用错误?

javascript - React 同级组件之间的状态泄漏

javascript - Highcharts 堆叠条形图边框不显示在右侧

python - 根据 header 身份验证 token 过滤 API 请求

python - 使用 setup.py 链接 library.lib