使用BeautifulSoup爬取公交线路站点并按行车方向拆分为两个独立列表的实现问询
华沙公交线路双向站点分拆爬取实现
现有代码的核心问题
原代码无差别抓取全页面的所有<a>标签文本做去重,没有对网页DOM结构做层级划分,导致两个行车方向的站点被混进同一个列表,同时还会把页面上非站点的导航链接、功能按钮文本也误纳入提取结果。
实现思路
通过BeautifulSoup先定位页面上和两个行车方向一一对应的独立容器区块,逐区块在容器内部范围提取站点信息,避免跨区块的内容混杂:
- 首先定位所有视觉上独立的方向分区DOM块,每个分区对应一个行车方向
- 在单个分区内部遍历属于该方向的站点链接,完成站点文本提取
- 仅在单个分区内部做站点去重(避免全局去重误删双向线路共名的首末站),最后按方向分别输出独立的站点列表
改造后可直接运行的代码
import requests from bs4 import BeautifulSoup def get_bus_stops_split_by_direction(bus_number): # 添加常规请求头,避免被站点反爬拦截 request_headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" } request_url = f"https://www.m2.rozkladzik.pl/warszawa/rozklad_jazdy.html?l={bus_number}" page_resp = requests.get(request_url, headers=request_headers) soup = BeautifulSoup(page_resp.content, "html5lib") # 定位所有独立的行车方向区块 direction_sections = soup.find_all("div", class_="direction") split_result = [] for section in direction_sections: # 提取当前方向的标识文本(即线路的终点方向名) section_heading = section.find("h3").get_text(strip=True) current_direction_stops = [] # 仅在当前方向区块范围内检索站点链接 stop_links = section.find_all("a") for link in stop_links: stop_name = link.get_text(strip=True) # 过滤空文本、当前方向内重复出现的站点 if stop_name and stop_name not in current_direction_stops: current_direction_stops.append(stop_name) split_result.append({ "direction_label": section_heading, "stop_list": current_direction_stops }) return split_result # 测试212路线路提取 line_result = get_bus_stops_split_by_direction("212") for line_dir in line_result: print(f"=== 行车方向:{line_dir['direction_label']} ===") print(f"站点明细:{line_dir['stop_list']}\n")
实操优化提示
- 不要对全量提取的站点做跨方向全局去重:双向线路的首末站往往名称一致,全局去重会导致其中一个方向的站点被错误删除,仅在单个方向区块内部去重即可
- 提取站点文本时必须加
strip=True参数,清除链接文本前后附带的换行、空格等格式杂质 - 若遇到请求失败的情况,可适当降低请求频率,不要短时间内高频爬取线路页面
内容的提问来源于stack exchange,提问作者wychen
相关产品推荐
相关产品推荐

