如何用Python抓取网页中形似表格但非标准表格的数据?
问题描述
我是数据科学与Python领域的新手,想抓取https://m4.mobilelegends.com/stats页面里形似表格但非标准表格结构的数据——页面每行数据的元素用的是相同类名。我尝试了一段代码但没成功,代码如下:
from bs4 import BeautifulSoup import requests from csv import writer import pandas as pd url= 'https://m4.mobilelegends.com/stats' page = requests.get(url) soup = BeautifulSoup(page.text, 'html.parser') lists = soup.find('div', class_="m4-team-stats-scroll") with open('m4stats_team.csv', 'w', encoding='utf8', newline='') as f: thewriter = writer(f) header = ['Team', 'Win Rate', 'Average KDA', 'Average Kills', 'average Deaths', 'Average Assists', 'Average Game Time', 'Average Lord Kills', 'Average Tortoise Kills', 'Average Towers Destroy', 'First Blood Rate', 'Hero Pool'] thewriter.writerow(header) for list in lists: team = list.find_all('p', class_="h3 pl-5 whitespace-nowrap hidden xl:block") awr = list.find_all('p', class_="h4") akda = list.find('p', class_="h4").text akill = list.find('p', class_="h4").text adeath = list.find('p', class_="h4").text aassist = list.find('p', class_="h4").text atime = list.find('p', class_="h4").text aalord = list.find('p', class_="h4").text atortoise = list.find('p', class_="h4").text atower = list.find('p', class_="h4").text firstblood = list.find('p', class_="h4").text hrpool = list.find('p', class_="h4").text info = [team, awr, akda, akill, adeath, aassist, atime, aalord, atortoise, atower, firstblood, hrpool] thewriter.writerow(info) pd.read_csv('m4stats_team.csv').head()
我找不到合适的关键词搜索解决方法,希望得到思路、关键词或代码片段的指导,帮我掌握基础网页抓取技能。
解决思路
- 定位行元素:原代码只拿到了外层滚动容器,没定位到每一行的具体数据块。页面中每个队伍的数据都包裹在类名为
m4-team-stats-row的div里,需要用find_all()获取所有行。 - 批量提取同类别数据:多个统计项共用
h4类名,反复调用find()只会拿到第一个匹配项,应该一次性用find_all()获取所有h4元素,再按索引对应到每个统计字段。 - 文本提取与异常处理:获取元素文本时要加
strip()清理冗余空格,同时判断元素是否存在,避免因页面结构变动导致报错。
修正后的代码
from bs4 import BeautifulSoup import requests from csv import writer import pandas as pd url = 'https://m4.mobilelegends.com/stats' page = requests.get(url) soup = BeautifulSoup(page.text, 'html.parser') # 获取所有队伍数据行 team_rows = soup.find_all('div', class_="m4-team-stats-row") with open('m4stats_team.csv', 'w', encoding='utf8', newline='') as f: thewriter = writer(f) header = ['Team', 'Win Rate', 'Average KDA', 'Average Kills', 'Average Deaths', 'Average Assists', 'Average Game Time', 'Average Lord Kills', 'Average Tortoise Kills', 'Average Towers Destroy', 'First Blood Rate', 'Hero Pool'] thewriter.writerow(header) for row in team_rows: # 提取队伍名称,处理元素不存在的情况 team_elem = row.find('p', class_="h3 pl-5 whitespace-nowrap hidden xl:block") team_name = team_elem.text.strip() if team_elem else 'N/A' # 获取当前行所有统计数据 stats_list = row.find_all('p', class_="h4") # 按索引提取对应字段,确保索引不越界 win_rate = stats_list[0].text.strip() if len(stats_list) > 0 else 'N/A' avg_kda = stats_list[1].text.strip() if len(stats_list) > 1 else 'N/A' avg_kills = stats_list[2].text.strip() if len(stats_list) > 2 else 'N/A' avg_deaths = stats_list[3].text.strip() if len(stats_list) > 3 else 'N/A' avg_assists = stats_list[4].text.strip() if len(stats_list) > 4 else 'N/A' avg_game_time = stats_list[5].text.strip() if len(stats_list) > 5 else 'N/A' avg_lord_kills = stats_list[6].text.strip() if len(stats_list) > 6 else 'N/A' avg_tortoise_kills = stats_list[7].text.strip() if len(stats_list) > 7 else 'N/A' avg_towers_destroy = stats_list[8].text.strip() if len(stats_list) > 8 else 'N/A' first_blood_rate = stats_list[9].text.strip() if len(stats_list) > 9 else 'N/A' hero_pool = stats_list[10].text.strip() if len(stats_list) > 10 else 'N/A' # 组装数据并写入CSV info = [team_name, win_rate, avg_kda, avg_kills, avg_deaths, avg_assists, avg_game_time, avg_lord_kills, avg_tortoise_kills, avg_towers_destroy, first_blood_rate, hero_pool] thewriter.writerow(info) # 读取并展示结果 df = pd.read_csv('m4stats_team.csv') print(df.head())
基础网页抓取关键学习点
- 浏览器开发者工具:按F12打开,用“选择元素”工具定位目标元素的类名、层级结构,这是网页抓取的核心基础。
- BeautifulSoup常用方法:
find()获取单个匹配元素,find_all()获取所有匹配元素组成的列表,通过索引或遍历列表提取内容。 - 异常预防:处理网页结构变动、元素缺失的情况,用条件判断避免索引越界或属性不存在的报错。
- 文本清洗:用
strip()、replace()等方法去除文本中的空格、换行符,保证数据整洁。
内容的提问来源于stack exchange,提问作者Hati
相关产品推荐
相关产品推荐

