如何在BeautifulSoup爬虫代码中集成XPath实现Oddsportal页面遍历?
解决方案
你不需要折腾BeautifulSoup的xpath支持,你已经在使用Selenium驱动,直接用Selenium自带的xpath选择方法操作元素即可,不需要和BeautifulSoup混用xpath功能。
修改逻辑
- 初始化浏览器时添加隐式等待,避免元素未加载就操作引发报错
- 定义你需要遍历的xpath列表
- 先打开初始页面爬取第一页数据,再逐个点击xpath对应的分页按钮,每次点击完成后爬取当前页面数据
- 每次循环都重新查找元素,避免页面刷新后元素失效报错
修改后完整代码
import pandas as pd from selenium import webdriver from bs4 import BeautifulSoup as bs import time # 初始化浏览器,添加10秒隐式等待 browser = webdriver.Chrome() browser.implicitly_wait(10) # 初始页面地址 base_url = "https://www.oddsportal.com/matches/soccer/" # 定义需要遍历的xpath列表 click_xpaths = [ "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[2]", "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[3]", "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[4]", "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[5]", "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[6]", "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[7]", "/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[3]/div/div/span/a[8]" ] class GameData: def __init__(self): self.country = [] def parse_current_page(): # 直接读取当前浏览器页面源码,不需要重复发送请求 df = pd.read_html(browser.page_source, header=0)[0] html = browser.page_source soup = bs(html, "lxml") cont = soup.find('div', {'id': 'wrap'}) content = cont.find('div', {'id': 'col-content'}) content = content.find('table', {'class': 'table-main'}, {'id': 'table-matches'}) main = content.find('th', {'class': 'first2 tl'}) if main is None: return None count = main.findAll('a') country = count[0].text game_data = GameData() for row in df.itertuples(): if not isinstance(row[1], str): continue elif ':' not in row[1]: country = row[1].split('»')[0] continue game_data.country.append(country) return game_data if __name__ == '__main__': results = None # 打开初始页面 browser.get(base_url) # 爬取第一页数据 first_page_data = parse_current_page() if first_page_data: results = pd.DataFrame(first_page_data.__dict__) # 遍历所有xpath切换分页爬取 for xpath in click_xpaths: try: # 每次循环重新查找元素,避免页面刷新后元素失效 element = browser.find_element_by_xpath(xpath) element.click() # 等待页面加载完成,可根据实际网速调整时长 time.sleep(2) # 爬取当前页数据 current_data = parse_current_page() if not current_data: continue current_df = pd.DataFrame(current_data.__dict__) if results is None: results = current_df else: # 高版本pandas用concat替代已废弃的append方法 results = pd.concat([results, current_df], ignore_index=True) except Exception as e: print(f"处理xpath {xpath} 时出错: {str(e)}") continue # 爬取完成后可以导出数据 # results.to_csv("odds_data.csv", index=False, encoding="utf_8_sig") browser.quit()
注意事项
- 如果点击后页面加载慢,可以适当调大
time.sleep的时长,或者换成Selenium的显式等待,性能更好 - 如果站点有反爬机制,频繁点击可能会被限制,可适当增加等待间隔
- 该方案完全复用了你原有页面解析逻辑,不需要修改原有解析规则
内容的提问来源于stack exchange,提问作者PyNoob
相关产品推荐
相关产品推荐

