Beautiful Soup Web抓取复杂的HTML数据

时间:2020-03-16 05:55:26

标签: python html web-scraping beautifulsoup

好,所以我正在为我的大学编程课程开发一个自我指导的学期项目。我的计划是抓取overwatch league website的不同部分以获取统计信息等,将其保存在数据库中,然后使用discord bot从该数据库中提取。但是,我遇到了网站本身的问题。 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
"""

所有注释均为失败尝试,均不返回任何内容。唯一未注释掉的行将返回带有大量不必要信息的大量json,其中确实包含我想解析并用于项目的内容。我linked it as a google doc并突出显示了我要抓住的东西。

我现在还不确定如何解决这个问题。我曾经考虑过使用硒,但是我缺乏javascript的知识,因此,我尽可能地避免使用它。即使您可以就其他方法提出一些建议,我也将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:0)

您已经注意到,您的数据采用JSON格式。它直接嵌入在页面中的脚本标签中,因此可以很容易地使用来获取它。然后,您需要解析json以提取所有表(对应于3个标签):

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个选项卡的标题,而值是表数据