🎯 一款可定制、具备反检测功能的云浏览器,由自主研发的 Chromium驱动,专为网页爬虫AI 代理设计。👉立即试用
返回博客

从网站地图到渲染链接:全站 URL 发现的六种方法堆栈

Ava Wilson
Ava Wilson

Expert in Web Scraping Technologies

03-Jun-2026

主要要点:

  • 没有单一的命令可以列出每一页。 完整的URL清单来源于多种方法的叠加:使用 site: 搜索操作符进行快速估算,sitemap.xml 和网站地图索引获取网站发布的内容,robots.txt 的网站地图指令获取入口点,SEO爬虫或Python爬虫查看实际链接,以及云浏览器获取仅在JavaScript运行后才出现的客户端链接。
  • 网站地图是最快的权威来源——前提是它们存在且保持最新。 单个 requests.get("/sitemap.xml") 加上递归遍历任何网站地图索引可以在一次请求中返回数百个URL。
  • 广度优先爬虫可以发现网站地图遗漏的内容。 网站地图是作者编辑的,且经常过时;对内部 <a href> 链接进行的广度优先遍历可以发现孤立页面、深层链接内容以及网站地图遗忘的任何内容。本指南中的爬虫在抓取每个URL之前遵循 robots.txtDisallow 规则。
  • JavaScript渲染的链接需要真实浏览器。 单页面应用和无限滚动目录在客户端绘制其内部链接,因此简单的HTTP获取返回一个近乎空的壳。Scrapeless Scraping Browser 在云浏览器中渲染页面,然后从水合的DOM中收集锚点——并将美国住宅出口固定在会话上。
  • 免费开始。 新的Scrapeless账户包括免费的Scraping Browser运行时间——请在 app.scrapeless.com 注册。

引言:为什么完整的URL清单比看起来更难

了解网站上每一页是很多工作的基础:技术SEO审核、内容迁移、坏链接检查、需要每个产品URL的价格监测管道,或希望获取整个文本语料库的LLM摄取工作。问题在于没有网站提供保证完整的列表。主页链接到大多数部分,网站地图发布某些页面,而孤立页面——通过直接链接可达但在导航中不链接——则在两者之间滑落。

现有选项各自覆盖一个切片。Google的 site: 操作符提供快速的公共估算,但结果上限且仅反映被索引的内容。sitemap.xml 对于发布者选择声明的内容是权威的,但它会变得过时并遗漏CMS从未注册的页面。跟随链接的爬虫可以找到链接图,但对于JavaScript内容丰富的页面,普通的HTTP爬虫在导航客户端渲染的情况下返回一个空壳。

本指南按照成本和完整性依次介绍六种方法——便宜与快速优先,全面与渲染最后。Python示例使用 requests 和标准库进行静态层,使用 Scrapeless Scraping Browser 进行JavaScript层的云浏览器,因此客户端链接变得可发现。固定美国出口,渲染页面,收集锚点。兄弟指南的交叉链接在结尾处。


你可以用它做什么

  • 技术SEO审核。 列出每个索引URL,然后将爬取结果与网站地图进行对比,以找出孤立页面和网站地图遗忘的页面。
  • 内容迁移。 在重新平台之前生成完整的源URL列表,以便在切换后没有出现404,并将旧路径映射到新路径。
  • 坏链接检查。 遍历内部链接图,记录每个目标,并标记返回非200状态的链接。
  • 价格和目录监控。 找到零售商的每个产品URL——包括JavaScript渲染的链接——并将它们输入下游提取管道。
  • LLM语料库摄取。 生成完整的内容URL集,以便文本提取工作可以在不遗漏深度链接文章的情况下提取整个公共语料库。
  • 竞争内容映射。 从网站地图和链接图中进行竞争对手的公共部分结构清单,以评估他们的内容足迹。

为什么选择Scrapeless Scraping Browser

本指南的大部分内容基于Python标准库和 requests——网站地图和 robots.txt 是纯文本和XML,静态链接爬虫无需其他。Scrapeless Scraping Browser 是一个可定制的、抗检测的云浏览器,专为网络爬虫和AI代理设计;当你需要的链接仅在JavaScript运行之后存在时,这是你选择的层。针对全站URL发现,它带来了:

  • 云端JavaScript渲染, 使单页面应用、无限滚动目录或React/Vue/Next.js导航中的内部链接在你阅读的DOM中出现——而不是一个空的 <div id="root">
  • 美国住宅代理出口, 每个会话固定,以便地理限制的网站提供与美国访客相同的页面结构。
  • 每个会话的抗检测指纹识别, 以便渲染的页面匹配有机流量所看到的内容,而不是一个被标记的自动化配置文件。
  • 会话连续性 在热身导航与目标页面之间,因此访问主页设置的cookie会带入到您实际上想要枚举的页面。
  • 一个端点,标准CDP,因此Playwright(或任何Chrome DevTools协议客户端)通过WebSocket连接,而无需本地浏览器进行渲染。

在免费的计划中获取您的API密钥,网址为 app.scrapeless.com


先决条件

  • Python 3.10或更新版本。
  • 一个Scrapeless账户和API密钥 — 在 app.scrapeless.com 注册。
  • pip install requests playwrightplaywright install chromium(本地Chromium只是CDP协议客户端;渲染在Scrapeless的云中运行)。
  • 对终端和HTTP的基本熟悉。

方法 1 — Google的 site: 搜索运算符

最快的初步估算无需代码。将以下内容输入到Google中:

Copy
site:example.com

Google返回该主机的已索引页面,结果头显示一个近似计数。缩小范围以映射部分结构:

  • site:example.com/blog — 仅限于/blog下的URLs。
  • site:example.com inurl:product — 已索引的路径中包含product的URLs。
  • site:example.com -inurl:tag — 排除你不关心的路径段。

此方法的用途:快速了解网站的大小及存在哪些部分。不适用的方面:完整性。site:运算符仅反映Google选择索引的页面,结果计数是估算而非精确数字,并且该运算符限制了您可以翻阅的结果数量。将其视为对下面更彻底方法的有效检查 — 如果您的网站地图声明有5,000个URLs,而site:显示大约200个,则这个差距本身也是一个发现。


方法 2 — 解析 sitemap.xml 和网站地图索引

网站地图是发布者自己声明的URLs,以XML格式提供,常见路径为/sitemap.xml。当存在并保持更新时,它是最快的权威来源。有两种形状:

  • <urlset> 网站地图直接列出页面URLs,每页一个<url><loc>…</loc></url>
  • <sitemapindex> 列出其他网站地图 — 大型网站将其URLs分割到多个子文件(pages_sitemap.xmlblog_sitemap.xml等)中,并从一个索引指向它们。您可以遍历索引,然后遍历每个子网站地图。

requests脚本使用一个递归函数处理这两种形状。它检测根标签,递归进入网站地图索引,并从每个<urlset>中收集页面URLs:

python Copy
import requests
import xml.etree.ElementTree as ET
from urllib.parse import urljoin

SM_NS = "{http://www.sitemaps.org/schemas/sitemap/0.9}"
HEADERS = {"User-Agent": "Mozilla/5.0 (sitemap-discovery)"}

def walk_sitemap(url, seen=None):
    """返回从网站地图或网站地图索引可到达的每个页面URL。"""
    seen = seen if seen is not None else set()
    if url in seen:          # 防止一个自引用的网站地图
        return []
    seen.add(url)

    resp = requests.get(url, headers=HEADERS, timeout=30)
    resp.raise_for_status()
    root = ET.fromstring(resp.content)
    tag = root.tag.split("}")[-1]   # 去掉命名空间,保留"sitemapindex"或"urlset"

    urls = []
    if tag == "sitemapindex":
        # 索引指向子网站地图 — 遍历每一个。
        for sm in root.findall(f"{SM_NS}sitemap"):
            loc = sm.findtext(f"{SM_NS}loc")
            if loc:
                urls.extend(walk_sitemap(loc.strip(), seen))
    else:
        # urlset直接列出页面URLs。
        for u in root.findall(f"{SM_NS}url"):
            loc = u.findtext(f"{SM_NS}loc")
            if loc:
                urls.append(loc.strip())
    return urls

if __name__ == "__main__":
    pages = walk_sitemap("https://example.com/sitemap.xml")
    print(f"从网站地图树发现 {len(pages):,} 个URLs")
    for u in pages[:10]:
        print(" ", u)

针对一个其/sitemap.xml作为指向子网站地图的网站地图索引的网站运行,该递归遍历返回所有子网站地图的联合结果。

关于实际情况中的网站地图的几点说明:

  • 路径是一个约定,而非保证。 /sitemap.xml是常见位置,但网站可以将其命名为任何名称,并在robots.txt中声明真实路径(方法3)。在假设文件不存在之前,始终检查robots.txt
  • 存在压缩网站地图。 一些网站提供sitemap.xml.gzrequests不会自动解压.gz主体,因此如果您遇到,请在解析之前使用gzip模块进行解压。
  • 网站地图可能过时。 它们反映了在生成时CMS注册的内容。自上次生成以来添加的页面和CMS从未注册的孤立页面将会缺失——这正是方法5和方法6存在的原因。

方法3 — 读取robots.txt网站地图指令

在抓取任何内容之前,获取/robots.txt。它在URL发现上有两个目的:它通常通过一个或多个Sitemap:行声明网站地图的位置,并告诉你网站要求爬虫忽略哪些路径(Disallow:)。这两者都很重要——第一个为方法2提供信息,第二个是你在方法5中需要遵守的合规义务。

python Copy
import requests
from urllib.parse import urljoin

HEADERS = {"User-Agent": "Mozilla/5.0 (sitemap-discovery)"}

def sitemaps_from_robots(base_url):
    """提取robots.txt中声明的每个Sitemap:指令。"""
    resp = requests.get(urljoin(base_url, "/robots.txt"), headers=HEADERS, timeout=30)
    resp.raise_for_status()
    sitemaps = []
    for line in resp.text.splitlines():
        if line.lower().startswith("sitemap:"):
            sitemaps.append(line.split(":", 1)[1].strip())
    return sitemaps

if __name__ == "__main__":
    for sm in sitemaps_from_robots("https://example.com"):
        print("声明的网站地图:", sm)

一个网站的robots.txt通常会声明一个或多个Sitemap:行——例如Sitemap: https://example.com/sitemap.xml。将这些直接输入到方法2中的walk_sitemap中,你可以获得发布者完全部署的URL集,而无需猜测路径。

这种组合模式是静态发现的核心:读取robots.txt以找到网站地图和被禁止的路径,然后遍历每个声明的网站地图。无论这两者返回的是什么,都是你权威的起始库存。接下来的所有内容都与找到它们遗漏的页面有关。

在免费计划上获取你的API密钥:app.scrapeless.com


方法4 — SEO爬虫(无需编码的选项)

如果你不想编写Python代码,桌面或云端SEO爬虫可以在一个工具中进行发现、链接图映射和报告。常见的爬虫有 — Screaming Frog SEO Spider、Sitebulb,以及内置于Ahrefs和Semrush中的网站审计爬虫 — 都执行相同的核心工作:提供一个起始URL,广度优先地跟随内部链接,并生成一个包含每个找到的URL及其状态代码、标题、深度和入链计数的表格。

这些工具在以下情况下是正确的选择:

  • 你想要一个视觉报告和CSV导出,而不需要维护代码。
  • 你需要为你计算标准的SEO列(状态、标准、可索引性、重定向链)。
  • 网站主要是服务器渲染的HTML,桌面爬虫可以原生处理。

它们的局限性值得了解:免费层会限制URL数量(Screaming Frog的免费版最多支持500个URL),JavaScript渲染是可选的、更慢的模式,并不是每个层级都启用,云审计工具按项目规模定价。对于小型网站的一次性审计,它们很难被超越;对于一个可重复的管道以供其他系统使用,下面的编程方法则提供了作为数据的URL,而不是报告。接下来的两个方法就是这个编程路径。


方法5 — 一个Python广度优先的内部链接爬虫

当网站地图过时或缺失时,你可以像搜索引擎那样发现页面:从主页开始,解析出每个内部<a href>,将你还未见过的链接排入队列,然后广度优先重复,直到边界为空或达到页面上限。这可以找到没有网站地图声明的孤立页面和深链接页面。

链接爬虫有两个不可妥协的责任,以下代码中都已内置:

  1. 遵循robots.txt 在请求每个URL之前检查can_fetch,跳过网站所禁止的任何内容。标准库urllib.robotparser会为你读取和评估规则。
  2. 保持在主机上并去重。 仅将主机与起始主机匹配的链接排入队列,删除URL片段,以便/page/page#section仅计算一次,并保留一个seen集合,以防止链接图中的循环永远循环。
python Copy
import requests
from collections import deque
from html.parser import HTMLParser
from urllib.parse import urljoin, urldefrag, urlparse
from urllib.robotparser import RobotFileParser

HEADERS = {"User-Agent": "Mozilla/5.0 (link-discovery)"}

class LinkParser(HTMLParser):
    """从页面中的<a>标签收集每个href。"""
    def __init__(self):
        super().__init__()
        self.links = []
    def handle_starttag(self, tag, attrs):
        if tag == "a":
            for key, value in attrs:
                if key == "href" and value:
                    self.links.append(value)

def load_robots(base_url):
    rp = RobotFileParser()
    rp.set_url(urljoin(base_url, "/robots.txt"))
zh Copy
rp.read()           # 解析不允许的规则和任何爬行延迟
    return rp

def crawl(start_url, max_pages=200, user_agent="*"):
    """遵守 robots.txt 的内部链接广度优先遍历。"""
    host = urlparse(start_url).netloc
    robots = load_robots(start_url)

    seen = {start_url}
    queue = deque([start_url])
    found, skipped = set(), []

    while queue and len(found) < max_pages:
        url = queue.popleft()

        # 合规检查:绝不会获取网站禁止的路径。
        if not robots.can_fetch(user_agent, url):
            skipped.append(url)
            continue

        try:
            resp = requests.get(url, headers=HEADERS, timeout=30)
            resp.raise_for_status()
        except requests.RequestException:
            # 单个错误的 URL 被记录在带外,不被追逐。
            continue
        if "text/html" not in resp.headers.get("Content-Type", ""):
            continue

        found.add(url)

        parser = LinkParser()
        parser.feed(resp.text)
        for href in parser.links:
            absolute = urldefrag(urljoin(url, href))[0]   # 解析并删除 #fragment
            if urlparse(absolute).netloc == host and absolute not in seen:
                seen.add(absolute)
                queue.append(absolute)

    return found, skipped

if __name__ == "__main__":
    pages, disallowed = crawl("https://example.com/", max_pages=200)
    print(f"发现 {len(pages):,} 页; 跳过 {len(disallowed)} 个被 robots.txt 禁止的页面")

对一个静态示例目录进行这个爬虫的实时运行发现了 40 个页面,限制设置为 40,且没有跳过任何 URL,因为该站点的 `robots.txt` 不禁止任何内容。指向一个 `robots.txt` 禁止某路径的站点时,爬虫正确拒绝了被禁止的 URL,并将其记录在 `skipped` 列表中,而不是抓取 — 在每个 URL 上都强制执行合规,而不是事后考虑。

这与早期的方法结合的方式:

- **爬虫找到服务地图忽略的内容;** 服务地图找到爬虫无法通过链接访问的内容。将两者结合并取并集以获得最完整的清单。
- **失败保持在带外。** 一个发生错误的 URL 会在此传递中被丢弃,而爬行会继续进行 — 一个错误页面不会延迟整个遍历。分别收集丢弃的 URL 以供审查。
- **限制并发以保持礼貌。** 像上面的单线程爬虫已经很温和了。如果并行化,保持每个主机 **最多 3 个工作线程**,并遵循任何 `robots.txt` 声明的 `Crawl-delay`。
- **爬虫仅处理 HTML。** 加载后由 JavaScript 绘制的链接对 `requests` 是不可见的。这个缺口正是第 6 种方法解决的。

---

## 方法 6 — 使用无损抓取浏览器渲染 JavaScript 重的页面

基于 `requests` 的爬虫读取服务器发送的任何字节。对于单页面应用、无限滚动目录或 React/Vue/Next.js 导航,这些字节是一个应用外壳 — `<div id="root"></div>` 加上一个脚本标签 — 一旦捆绑包运行,内部链接将客户端绘制。普通的 HTTP 无法看到它们;真实的浏览器可以。

无损抓取浏览器在云浏览器中渲染页面,并通过 Chrome DevTools 协议将其暴露。你通过 WebSocket 端点与 Playwright 连接,预热主页以便会话携带 cookies,导航到目标,然后从水合的 DOM 中收集锚点 — 这在第 5 种方法中是链接解析步骤的渲染页面对应物。美国出口固定在会话上,因此地理限制的网站提供其标准结构。

连接是由你的 API 密钥构建的单个 WebSocket URL。这个连接形状如下:

```python
import os
from urllib.parse import urlencode
from playwright.sync_api import sync_playwright

def scraping_browser_url(proxy_country="US", session_ttl=240):
    params = urlencode({
        "token": os.environ["SCRAPELESS_API_KEY"],
        "sessionTTL": session_ttl,
        "proxyCountry": proxy_country,
    })
    return f"wss://browser.scrapeless.com/api/v2/browser?{params}"

手握端点,渲染目标并收集其内部链接:

python Copy
from urllib.parse import urljoin, urldefrag, urlparse

def discover_rendered_links(start_url, proxy_country="US"):
    """在云浏览器中渲染一个 JS 重的页面并收集同主机链接。"""
    host = urlparse(start_url).netloc
    homepage = f"{urlparse(start_url).scheme}://{host}/"

    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(scraping_browser_url(proxy_country))
        context = browser.contexts[0] if browser.contexts else browser.new_context()
        page = context.pages[0] if context.pages else context.new_page()

        # 首先预热主页,使会话携带 cookie,然后导航到目标。
        page.goto(homepage, wait_until="domcontentloaded", timeout=60_000)
        page.goto(start_url, wait_until="networkidle", timeout=60_000)

从经过客户端渲染的 DOM 中读取 href。

Copy
    hrefs = page.eval_on_selector_all(
        "a[href]", "els => els.map(e => e.getAttribute('href'))"
    )
    browser.close()

links = set()
for href in hrefs:
    if not href:
        continue
    absolute = urldefrag(urljoin(start_url, href))[0]
    if urlparse(absolute).netloc == host:
        links.add(absolute)
return links

if name == "main":
found = discover_rendered_links("https://example.com/app/catalog")
print(f"在渲染后发现 {len(found):,} 个客户端链接")
for u in sorted(found)[:10]:
print(" ", u)

Copy
使其可靠的模式:

- **先热身主页,然后导航。** 第一个 `goto` 到 `/` 让会话获取 Cookie 并通过站点的首次加载检查;第二个 `goto` 落在你真正想要枚举的页面上。在冷会话中直接访问深层 URL 更可能会引发挑战。
- **在目标上使用 `wait_until="networkidle"`** 给客户端路由器留出时间在你读取 DOM 之前挂载其链接。对于无限滚动页面,在循环中滚动到底部(`page.mouse.wheel`),直到链接数量停止增长,然后收集。
- **渲染在 Scrapeless 的云中进行,** 而不是在你的机器上。本地的 `playwright install chromium` 只是与 `wss://browser.scrapeless.com/...` 端点通信的 CDP 客户端。
- **将结果反馈到并集中。** 渲染的链接加入站点地图集合和静态抓取集合;通过标准化 URL 对合并集合进行去重,以便形成最终清单。

要将此集成到完整的抓取器中,将方法 5 中的 `requests.get` 内容替换为 `discover_rendered_links`,处理你知道基于 JavaScript 的主机,并保持廉价的 `requests` 路径以处理服务器渲染的多数。这样的 HTTP-优先、浏览器-次要的分割将云浏览器的使用限制在真正需要的页面上。

---

## 你得到的结果

每个方法都会输出一组绝对 URL;最终清单是它们的去重联合。同一个主机的合并记录如下所示:

```json
// 架构反映了四个编程方法的联合。
// 数量是示例样本,并非任何网站的固定快照。
{
  "host": "example.com",
  "discovered_at_methods": ["sitemap", "robots", "bfs_crawl", "rendered"],
  "counts": {
    "from_sitemap": 226,
    "from_bfs_crawl": 40,
    "from_rendered": 18,
    "union_unique": 248
  },
  "sample_urls": [
    "https://example.com/",
    "https://example.com/blog",
    "https://example.com/blog/how-to-scrape-bbb-business-listings",
    "https://example.com/app/catalog?page=2"
  ],
  "skipped_by_robots": [
    "https://example.com/private/"
  ]
}

关于完整站点 URL 发现的一些诚实观察,在大规模运行之前值得了解:

  • 联合优于任何单一来源。 站点地图声明发布者注册的内容;BFS 抓取找到链接孤儿;渲染传递找到客户端链接。覆盖率是三者的联合减去不允许的路径。
  • 在标准化 URL 上去重。 去除片段,决定是否尾部斜杠和 ?utm_* 查询参数对你的用例重要,在计数之前进行标准化 — 否则 /page/page/ 会膨胀总数。
  • 站点地图滞后内容。 发布在最后一次站点地图构建之后的页面仅会出现在抓取层中。如果完整清单很重要,请始终在读取站点地图的同时进行抓取。
  • 客户端链接对 HTTP 是不可见的。 如果已知大站点的 requests 抓取仅返回少量 URL,导航几乎肯定是客户端渲染的 — 将该主机升级到方法 6。
  • 端到端遵守禁止列表。 skipped_by_robots 数组不是待办事项列表。这些路径不应出现在清单中。

结论:构建完整的 URL 清单

寻找每个页面归结为四个程序性动作叠加在一个手动检查之上:使用 site: 估计大小,读取 robots.txt 获取站点地图位置和不允许的路径,遍历站点地图树以获取声明的 URL,BFS 抓取内部链接图以找到孤儿,以及在云浏览器中渲染基于 JavaScript 的主机以获取客户端链接。取联合,按标准化 URL 去重,这就是清单。
对于路由已渲染层的代理层,请参阅 什么是 SSL 代理?Scraping Browser 产品页面定价页面 涵盖了云浏览器层;完整的 SDK 参考文档见 docs.scrapeless.com。在已渲染层上固定美国出口,在目标页面之前预热首页,尊重每个 URL 的 robots.txt,并将最终列表视为每种方法的并集。


准备构建您的 AI 驱动数据管道?

加入我们的社区,领取免费计划,并与正在构建 URL 发现和爬虫管道的开发者连接: Discord · Telegram

app.scrapeless.com 注册,获取免费的 Scraping Browser 运行时,并将上述模式适应于管道所需的网站、网站地图和区域。


常见问题解答

问:爬取网站以寻找其所有页面合法吗?

发现本身读取公开可见的 URL,但合法性取决于您访问的内容、何处访问以及在何种条款下。尊重网站的 robots.txt,审核其服务条款,避免访问私密或认证区域,并在高风险用例中咨询法律顾问。Scrapeless 仅访问公开可用的数据。

问:网站地图或爬取 - 哪个提供完整列表?

两者都不是。网站地图是发布者的声明,通常是过时或部分的;爬取找到链接图,但错过没有页面链接到的页面。完整的清单是网站地图遍历(方法 2)和广度优先爬取(方法 5)的 并集,再加上为客户端链接添加的已渲染层(方法 6)。

问:为什么我的爬虫在大型网站上只找到少量页面?

该网站几乎肯定在客户端渲染其导航。普通的 requests 获取在 JavaScript 运行之前返回应用外壳,因此没有链接可供跟随。使用 Scrapeless Scraping Browser(方法 6)渲染这些主机,从已填充的 DOM 中收集锚点。

问:我需要代理进行 URL 发现吗?

对于单主机网站地图读取和礼貌的静态爬取,通常不需要。当网站限制内容的地理访问(您需要美国出口才能看到美国结构)、您的 IP 被限速,或者已渲染层需要住宅出口以匹配自然流量时,代理才发挥作用。方法 6 中的 Scrapeless 连接通过 proxy_country="US" 固定出口。

问:当页面提供访问挑战时,我如何获得干净的渲染?

在会话中固定美国住宅出口并 预热会话 - 首先在同一浏览器会话中导航到网站的主页,然后再访问目标页面,如方法 6 代码所示,以设置 Cookie,并在已信任的上下文中加载深层页面。直接跳转到深层 URL 更可能引发挑战。

问:当网站更改其 HTML 或链接结构时会发生什么?

静态爬虫依赖于通用的 <a href> 元素,因此标记更改很少会破坏它。如果您将已渲染层选择器缩紧到特定容器,当标记发生变化时请重新检查,并在网站重新组织导航时将其扩展回 a[href]

问:我如何在爬取时避免轰炸网站?

方法 5 中的单线程爬虫已经很温和。如果您并行化,保持并发 每个主机不超过 3 个工作线程,尊重 robots.txt 中的任何 Crawl-delay 指令,并且绝不要排队涉及禁止规则的路径。

问:我如何对最终的 URL 集进行去重复?

在计数之前进行规范化:去除 #fragments,判断尾部斜杠和跟踪查询参数(?utm_*)是否对您的用例重要,并将 URL 存储在以规范形式为键的 set 中。每种方法已经返回一个 set;取它们的并集,重复项将合并。

问:我可以在没有 AI 代理或任何 SDK 的情况下发现 URL 吗?

可以。方法 1-5 仅使用 Python 标准库和 requests。方法 6 添加了 Playwright,通过 CDP 连接到 Scrapeless Scraping Browser 端点 - 不需要代理框架,仅需根据您的 API 密钥构建的 WebSocket URL。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录