【问题标题】:Beautiful Soup web scraping complex html for dataBeautiful Soup 网页抓取复杂的 html 数据
【发布时间】:2020-03-16 05:55:26
【问题描述】:

好的,我正在为我的大学编程课程做一个自主的学期项目。我的计划是抓取overwatch league website 的不同部分以获取统计信息等,将它们保存在数据库中,然后使用不和谐机器人从该数据库中提取。但是,我遇到了网站本身的问题。 Here's a screenshot of the html for the standings page

正如您所看到的,使用重复的 div 和 body 标签非常复杂且难以导航,我很确定它是动态创建的。我的教授建议我找到一种方法来隔离表格顶部的排名标题,然后访问父行,然后遍历兄弟姐妹,将团队名称、位置等数据暂时提取到字典中。我无法在网上找到任何对我有帮助的东西,大多数网站都没有提供足够的信息或者已经过时了。

这是我目前所拥有的:

from bs4 import BeautifulSoup
import requests
import link
import re
import pprint

url = 'https://overwatchleague.com/en-us/standings'

response = requests.get(url).text

page = BeautifulSoup(response, features='html.parser')



# for stat in page.find(string=re.compile("rank")):
#     statObject = {
#         'standing' : stat.find(string=re.compile, attrs={'class' : 'standings-table-v2styles__TableCellContent-sc-3q1or9-6 jxEkss'}).text.encode('utf-8')
#     }

# print(page.find_all('span', re.compile("rank")))  

# for tag in page.find_all(re.compile("rank")):
    # print(tag.name)

print(page.find(string=re.compile('rank')))

"""
# locate branch with the rank header,
# move up to the parent branch
# iterate through all the siblings and 
# save the data to objects
"""

cmets 都是失败的尝试,都没有返回任何内容。唯一没有被注释掉的行会返回一个包含大量不必要信息的大量 json,其中确实包括我想要解析并用于我的项目的内容。我已经linked it as a google doc 强调了我想要获取的内容。

我现在不确定如何处理这个问题。我考虑过使用 selenium,但是我缺乏 javascript 知识,所以我尽可能避免使用它。即使您可以就如何处理此问题提出一些建议,我将不胜感激。

谢谢

【问题讨论】:

    标签: python html web-scraping beautifulsoup


    【解决方案1】:

    如您所见,您的数据是 JSON 格式。它直接嵌入页面中的脚本标记中,因此使用 很容易获得它。然后需要解析json来提取所有的表(对应3个tab):

    import requests
    from bs4 import BeautifulSoup
    import json
    
    url = 'https://overwatchleague.com/en-us/standings'
    
    r = requests.get(url)
    
    soup = BeautifulSoup(r.text, "html.parser")
    script = soup.find("script",{"id":"__NEXT_DATA__"})
    
    data = json.loads(script.text)
    
    tabs = [
        i.get("standings")["tabs"]
        for i in data["props"]["pageProps"]["blocks"] 
        if i.get("standings") is not None
    ]
    
    result = [
        { i["title"] : i["tables"][0]["teams"] }
        for i in tabs[0]
    ]
    
    print(json.dumps(result, indent=4, sort_keys=True))
    

    上面的代码给你一个字典,键是3个标签的标题,值是表数据

    【讨论】:

    • 非常感谢!我什至没有意识到它已经嵌入到页面中,但现在这很有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2020-10-24
    • 2023-03-31
    • 2016-05-16
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多