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

基于页面位置提取网站URL分组异常问题求助

解决URL按页面位置分组的问题

问题根源在于你靠URL关键词判断位置的思路完全行不通——页面页眉、页脚这些区域的链接没有固定的关键词特征,必须通过HTML元素的DOM结构(比如<header>、<footer>、<aside>这类标准标签,或者网站自定义的类名)来定位区域,再提取对应区域里的链接。

下面是修正后的代码,以numpy官网为例,通过定位页面的标准结构标签来分组URL:

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

def extract_urls_by_section(url):
    # 初始化分组字典
    url_groups = {
        "页眉": [],
        "正文": [],
        "侧边栏": [],
        "页脚": []
    }

    # 获取页面内容
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')

    # 1. 提取页眉区域的URL(通常对应<header>标签)
    header = soup.find('header')
    if header:
        header_links = header.find_all('a', href=True)
        for link in header_links:
            href = link['href']
            # 转成绝对URL,过滤无效链接(锚点、javascript跳转等)
            absolute_url = urljoin(url, href)
            if not absolute_url.startswith(('javascript:', '#', 'mailto:')):
                url_groups["页眉"].append(absolute_url)

    # 2. 提取页脚区域的URL(通常对应<footer>标签)
    footer = soup.find('footer')
    if footer:
        footer_links = footer.find_all('a', href=True)
        for link in footer_links:
            href = link['href']
            absolute_url = urljoin(url, href)
            if not absolute_url.startswith(('javascript:', '#', 'mailto:')):
                url_groups["页脚"].append(absolute_url)

    # 3. 提取侧边栏区域的URL(numpy官网侧边栏用<aside>标签)
    sidebar = soup.find('aside')
    if sidebar:
        sidebar_links = sidebar.find_all('a', href=True)
        for link in sidebar_links:
            href = link['href']
            absolute_url = urljoin(url, href)
            if not absolute_url.startswith(('javascript:', '#', 'mailto:')):
                url_groups["侧边栏"].append(absolute_url)

    # 4. 提取正文区域的URL(排除页眉、页脚、侧边栏后的内容,通常对应<main>标签)
    main_content = soup.find('main')
    if main_content:
        # 移除main里可能包含的其他区域元素,避免重复提取
        for section in [header, footer, sidebar]:
            if section and section.parent == main_content:
                section.decompose()
        main_links = main_content.find_all('a', href=True)
        for link in main_links:
            href = link['href']
            absolute_url = urljoin(url, href)
            if not absolute_url.startswith(('javascript:', '#', 'mailto:')):
                # 确保链接未被分到其他组
                if absolute_url not in url_groups["页眉"] and absolute_url not in url_groups["页脚"] and absolute_url not in url_groups["侧边栏"]:
                    url_groups["正文"].append(absolute_url)

    # 给每个分组去重
    for key in url_groups:
        url_groups[key] = list(set(url_groups[key]))

    return url_groups

# 测试numpy官网
if __name__ == "__main__":
    numpy_url = "https://numpy.org/"
    result = extract_urls_by_section(numpy_url)
    for section, urls in result.items():
        print(f"\n--- {section} URL ---")
        for url in urls:
            print(url)

关键说明:

  • 核心逻辑是通过HTML结构标签定位区域:用<header>抓页眉,<footer>抓页脚,<aside>抓侧边栏,<main>抓正文,这是大部分现代网站的标准结构。
  • 处理相对URL转绝对URL:用urljoin把页面里的相对路径(比如/install)转成完整URL,避免提取到无效的路径。
  • 过滤无效链接:排除锚点、javascript跳转、邮件链接这类非目标URL。
  • 去重处理:避免同一链接在多个区域重复出现(比如有些链接可能同时出现在页眉和页脚)。

运行这段代码后,你会发现/install、/learn这类原本属于页眉的链接会被正确分到“页眉”分组里,页脚的链接也会被正常提取,不会再出现分组为空的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:12:46