【问题标题】:scraping dynamic JavaScript table with python使用 python 抓取动态 JavaScript 表
【发布时间】:2022-01-08 07:00:02
【问题描述】:

我正在尝试抓取这个网站:https://madduxsports.com/college-basketball-lines.php
我对 python 和抓取非常陌生,我相信这个网站有一个用 JavaScript 生成的表格。
我希望只抓取前 7 列。 我试过了

from requests_html import HTMLSession
from bs4 import BeautifulSoup
session = HTMLSession()
resp = session.get("https://madduxsports.com/college-basketball-lines.php")
resp.html.render()
soup = BeautifulSoup(resp.html.html, "lxml")
script_tags = soup.find_all("script")
print(script_tags)

这将获得带有<script> 标签的所有内容,其中包含表格数据,但我不知道如何获得前 7 列。

感谢您的帮助

【问题讨论】:

    标签: javascript python web-scraping


    【解决方案1】:

    您可以直接通过请求获得它(但您需要对 html 转义字符进行一些操作,而不是什么。这会获得与我们从 <script> 标记中提取相同的数据。如果您愿意,我也可以向您展示如何获得它,但我认为这是更好的方法。

    import requests
    import pandas as pd
    
    url = 'https://madduxsports.com/newodds/v2/scheduler-ajax.php'
    payload = {
    'timezone': 'America/New_York',
    'is_first_request': '0',
    'league_id': '4',
    'sport_id': '2',
    'period_id': '1'}
    
    
    jsonData = requests.post(url, data=payload).json()
    
    # Everything above is the to get the data
    # jsonData is the json you see in the <script> tag
    
    
    odds = jsonData['odds']
    schedulers = jsonData['schedulers']
    
    odds_df = pd.json_normalize(odds)
    schedulers_df = pd.json_normalize(schedulers)
    
    names_dict = {}
    for each in odds:
        names_dict[each['id']] = each['name']
    
    cols = []
    for col in schedulers_df:
        for k, v in names_dict.items():
            col = col.replace(str(k),v)
            
        cols.append(col)
    
    schedulers_df.columns = cols
    
    cols = ['date','team_ids', 
    
    'team_names','score.away_score','score.home_score',
            'score.description','opener.1.away','opener.1.home']
    
    odds_cols = [x for x in schedulers_df.columns if ('1.away' in x or '1.home' in x) and ('class' not in x)]
    
    df = schedulers_df[cols + odds_cols]
    

    输出:

    print(df)
                        date          team_ids  ... odds.SIA.1.away odds.SIA.1.home
    0    2021-12-03 00:00:00  306123<br>306124  ...     143&frac12;      -1&frac12;
    1    2021-12-03 00:00:00  306127<br>306128  ...     142&frac12;              11
    2    2021-12-03 00:00:00  306129<br>306130  ...  126&frac12;u12      -5&frac12;
    3    2021-12-03 00:00:00  306131<br>306132  ...              17     146&frac12;
    4    2021-12-03 01:00:00  306133<br>306134  ...      -2&frac12;     135&frac12;
    ..                   ...               ...  ...             ...             ...
    107  2021-12-04 07:50:00  396155<br>396156  ...                                
    108  2021-12-04 07:50:00  396157<br>396158  ...                                
    109  2021-12-04 07:50:00  396159<br>396160  ...                                
    110  2021-12-04 07:50:00      9875<br>9876  ...                                
    111  2021-12-04 07:50:00      9877<br>9878  ...                                
    
    [112 rows x 22 columns]
    

    【讨论】:

    • 非常感谢您的回答,但是当我运行它时,似乎有很多数据和大多数空括号或 NaN。我做错了吗?
    • 没有错。这就是那里的东西。您正在查看所有列,对吗?有 300 多列。所以我不会对它的稀疏感到惊讶
    • 好的,谢谢,您可能是对的。快速提问,为什么实际表只有 11 列时会有 300 多列?
    • 它包含很多元数据。因此,在站点上实际呈现表格可能需要诸如 id、group_type 等。网站上的表格是根据这些数据呈现的,但显然他们选择只显示可能被认为重要的部分。其次,数据是json格式。所以它确实不需要被“扁平化”。当你这样做时,它往往会扩展并变得非常宽,以至于每一行/实例都包含所有相关信息。
    • 有没有办法过滤掉所有的元数据?
    猜你喜欢
    • 2021-10-04
    • 1970-01-01
    • 2018-09-02
    • 2018-10-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多