如何用BeautifulSoup定位网页元素抓取指定数据生成pandas DataFrame
德甲球员数据爬取元素定位方案
你当前爬取的分页列表页仅能直接获取球员姓名、所属球队2个字段,出生日期、身高、场上位置3个字段需要进入每个球员的个人详情页才能抓取,具体定位规则如下:
1. 分页列表页元素定位(你当前循环访问的按姓名排序分页)
首先修正你现有代码的变量错误:你定义Request对象时变量名写的是r,但urlopen里传了不存在的req,直接运行会报未定义错误。
列表页所有球员数据存放在class属性为standard_tabelle的球员数据表格中,跳过第一行表头后,每一个<tr>标签对应一名球员:
- 球员姓名:当前行第一个
<td>标签内的<a>标签文本内容,这个<a>标签的href属性是球员详情页的相对路径,拼接网站根域名就能得到详情页完整地址 - 所属球队:当前行第二个
<td>标签内的<a>标签文本内容,就是球员2021-2022赛季效力的德甲球队
2. 球员详情页元素定位
进入球员个人详情页后,找到页面上方展示球员基础信息、class属性为standard_tabelle的个人信息表,按文本匹配对应行即可拿到剩余字段:
- 场上位置:定位表中文本包含
Position:的<tr>行,取该行第二个<td>的文本就是球员场上位置 - 出生日期:定位表中文本包含
Geburtsdatum:(德语“出生日期”)的<tr>行,取该行第二个<td>的文本就是出生日期,可自行清洗格式转为pandas的时间类型 - 身高:定位表中文本包含
Größe:(德语“身高”)的<tr>行,取该行第二个<td>的文本就是身高数据,一般为xxx cm格式,可提取数值做结构化处理
参考代码逻辑补全
import pandas as pd import time import random from urllib.request import Request, urlopen from bs4 import BeautifulSoup base_domain = "https://www.weltfussball.de" data = [] for i in range(1,12): URL = 'https://www.weltfussball.de/spielerliste/bundesliga-2021-2022/nach-name/' URL_ = URL + str(i) + '/' req = Request(URL_, headers={'User-Agent': 'Mozilla/5.0'}) webpage = urlopen(req).read() soup = BeautifulSoup(webpage,'lxml') # 定位球员列表 player_table = soup.find("table", class_="standard_tabelle") for tr in player_table.find_all("tr")[1:]: # 跳过表头 tds = tr.find_all("td") if len(tds) < 2: continue player_name = tds[0].a.text.strip() team_name = tds[1].a.text.strip() if tds[1].a else tds[1].text.strip() player_detail_url = base_domain + tds[0].a["href"] # 请求详情页 detail_req = Request(player_detail_url, headers={'User-Agent': 'Mozilla/5.0'}) detail_page = urlopen(detail_req).read() detail_soup = BeautifulSoup(detail_page, 'lxml') info_table = detail_soup.find("table", class_="standard_tabelle") position = "" birth_date = "" height = "" for info_tr in info_table.find_all("tr"): info_tds = info_tr.find_all("td") if len(info_tds) <2: continue label = info_tds[0].text.strip() val = info_tds[1].text.strip() if "Position" in label: position = val elif "Geburtsdatum" in label: birth_date = val elif "Größe" in label: height = val data.append({ "球员姓名": player_name, "所属球队": team_name, "出生日期": birth_date, "身高": height, "场上位置": position }) # 加随机延时避免被封 time.sleep(random.uniform(0.5,1.5)) # 转成目标DataFrame df = pd.DataFrame(data)
内容的提问来源于stack exchange,提问作者Tobitor
相关产品推荐
相关产品推荐

