You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python爬取Oddsportal平台足球赛事相关的全部URL?

实现方案(Python)

前置依赖安装

目标站点是动态渲染页面,静态请求无法获取完整内容,推荐使用playwright做页面渲染,不用手动配置浏览器驱动,适配反爬规则更简单。
安装命令:

pip install playwright
playwright install chromium

实现逻辑

采用层级递归+自动去重的方案,覆盖所有层级页面:

  1. 从入口页提取所有足球区域类链接,递归进入每个区域页
  2. 从区域页提取所有赛事(含不同年份)的结果页链接,自动存入结果集
  3. 识别每个赛事结果页的分页数量,自动生成所有分页URL
  4. 全程用集合做去重,避免重复请求和重复存入URL

核心代码

from playwright.sync_api import sync_playwright
import time
from urllib.parse import urljoin

# 配置参数
BASE_ENTRY = "https://www.oddsportal.com/results/#soccer"
# 过滤规则,只保留足球相关的有效链接,可按需调整
DOMAIN_CHECK = "oddsportal.com"
PATH_CHECK = "/soccer/"
RESULT_FLAG = "/results/"

# 结果存储
valid_urls = set()
crawled_pages = set()

def crawl(page, cur_url):
    # 跳过已爬过的页面
    if cur_url in crawled_pages:
        return
    crawled_pages.add(cur_url)

    # 页面加载,可根据自身网络调整等待时长
    page.goto(cur_url, timeout=60000)
    time.sleep(2)

    # 提取当前页所有链接
    links = page.locator("a")
    for i in range(links.count()):
        try:
            href = links.nth(i).get_attribute("href")
            if not href:
                continue
            full_url = urljoin("https://www.oddsportal.com", href)
            # 过滤无关链接
            if DOMAIN_CHECK not in full_url or PATH_CHECK not in full_url:
                continue
            # 结果页链接直接入库,同时生成所有分页链接
            if RESULT_FLAG in full_url:
                valid_urls.add(full_url)
                # 处理分页
                pagination = page.locator(".pagination a")
                if pagination.count() > 0:
                    max_page = 1
                    for j in range(pagination.count()):
                        page_num = pagination.nth(j).text_content().strip()
                        if page_num.isdigit():
                            max_page = max(max_page, int(page_num))
                    for p in range(2, max_page+1):
                        paged_url = f"{full_url}#/page/{p}/"
                        valid_urls.add(paged_url)
            # 非结果页的足球类链接递归爬取
            else:
                crawl(page, full_url)
        except:
            # 单个链接提取失败不中断整体流程
            continue

if __name__ == "__main__":
    with sync_playwright() as p:
        # 启动无头浏览器,要可视化爬取可把headless改成False
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        # 模拟正常浏览器请求头,降低被反爬拦截概率
        page.set_extra_http_headers({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
        })
        try:
            crawl(page, BASE_ENTRY)
        finally:
            browser.close()
        # 结果写入本地文件
        with open("soccer_result_urls.txt", "w", encoding="utf-8") as f:
            for url in sorted(valid_urls):
                f.write(url + "\n")
        print(f"爬取完成,共获取有效URL {len(valid_urls)} 条,已保存到soccer_result_urls.txt")

注意事项

  • 反爬规避:不要把页面等待时间改得太短,建议至少留1秒以上间隔,短时间高频请求会被封IP,爬取量较大的话可以自行加代理池逻辑
  • 深度适配:如果页面层级超过Python默认递归深度,可以把递归逻辑改成队列实现的广度优先遍历,避免栈溢出
  • 规则调整:如果爬取结果有多余的无关链接,可以修改过滤规则的关键词,精准匹配需要的URL类型

内容的提问来源于stack exchange,提问作者user16304089

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 18:57:04