【问题标题】:scrape data from interactive chart using selenium, bs4 or requests使用 selenium、bs4 或请求从交互式图表中抓取数据
【发布时间】:2021-07-01 18:20:00
【问题描述】:

我想从这个页面的图表中抓取数据:http://188.166.44.172/match/live-stats/100941310

我尝试了 requests 和 bs4,但未能获取任何数据,我也尝试了 selenium,但也没有数据。

这是使用请求的代码:

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0'}

session = requests.Session()
r = session.get(u, timeout=30, headers=headers)    

soup = BeautifulSoup(r.content, 'html.parser')

for i in soup.find_all('rect'):
    if i.has_attr("onmouseover"):
        text = i.get('onmouseover')
        print(text)

以及使用 selenium 的代码:

from selenium import webdriver
from bs4 import BeautifulSoup
u = "http://188.166.44.172/match/live-stats/100941310"

driver = webdriver.Chrome(executable_path=r"C:/chromedriver.exe", options=options)

driver.get(url)

soup = BeautifulSoup(driver.page_source, 'html.parser')

for i in soup.find_all('rect'):   #I also tried soup.select('*')
    if i.has_attr("onmouseover"):
        text = i.get('onmouseover')
        print(text)

有没有办法使用 python 从这些图表中抓取数据?

【问题讨论】:

    标签: python selenium web-scraping beautifulsoup


    【解决方案1】:

    您没有得到任何回报的原因是因为所有图表都是由JavaScript 动态生成的,例如,bs4 您不会阅读任何内容。

    但是,图表的数据嵌入在HTML 中。你可以解析它并绘制。

    方法如下:

    import ast
    import re
    
    import requests
    import matplotlib.pyplot as plt
    
    target_url = "http://188.166.44.172/match/live-stats/100941310"
    page_source = requests.get(target_url).text
    
    raw_attack_data = ast.literal_eval(
        re.search(r"var all_attack = (\[.*\])", page_source).group(1),
    )
    all_attack = [i[1] for i in raw_attack_data if isinstance(i, list)]
    
    plt.plot(all_attack, label="attack")
    plt.legend(loc="lower right")
    plt.show()
    

    这应该会给你一个这样的情节:

    正如我所说,您需要的一切都在源代码中,因此您必须使用这些值。

    源码如下:

    内部列表的第一个值是游戏时间,第二个值是图表上绘制的统计数据。

    请注意,某些数组的值位于 {} 中。这些是图表上的那些图标标记。您可以使用isistance(i, list) 将它们过滤掉,因为它们可以很容易地解析为dicts,如上所示。

    编辑:

    是的,可以获取部门和团队信息,因为所有信息都在 HTML 中。我已经修改了最初的答案并想出了这个:

    import ast
    import re
    
    import requests
    from bs4 import BeautifulSoup
    import matplotlib.pyplot as plt
    
    target_url = "http://188.166.44.172/match/live-stats/100941310"
    page_source = requests.get(target_url).text
    
    
    def get_match_info(html_source: str) -> list:
        return [
            i.getText(strip=True) for i
            in BeautifulSoup(html_source, "lxml").select("h1 a")
        ]
    
    
    def get_stats(html_source: str, search_str: str) -> tuple:
        raw_data = ast.literal_eval(
            re.search(fr"var {search_str} = (\[.*\])", html_source).group(1),
        )
        filtered = [i[1] for i in raw_data if isinstance(i, list)]
        game_time = [i[0] for i in raw_data if isinstance(i, list)]
        return game_time, filtered
    
    
    division, home, away = get_match_info(page_source)
    
    time_, attack_home = get_stats(page_source, "dangerous_home")
    _, attack_away = get_stats(page_source, "dangerous_away")
    
    plt.suptitle(f"{division} - {home} v {away}")
    plt.ylabel("Attack")
    plt.xlabel("Game time")
    plt.plot(time_, attack_home, color="blue", label=home)
    plt.plot(time_, attack_away, color="black", label=away)
    plt.legend(loc="lower right")
    plt.show()
    
    

    这会产生一个情节:

    【讨论】:

    • 这工作真的很棒,从抓取的数据中,我们可以准确地知道每个数据是哪个团队的?
    • 有什么方法可以知道每个特定团队的数据吗?
    • @KhaledKoubaa 是的,有办法。我已经更新了答案。如果您觉得它有用,请考虑投票和/或接受它。
    • 如何使用浏览器在页面源代码中找到变量?我应该如何在我的浏览器中找到并查看“var all_attacks”(在与页面源相关的图像中)以使用?
    • 您能告诉我如何找到此页面交互式图表的变量吗? fxempire.com/macro/canada/consumer-confidence
    猜你喜欢
    • 2014-06-08
    • 2019-04-26
    • 2021-04-05
    • 2015-08-12
    • 1970-01-01
    相关资源
    最近更新 更多