用户登录
个人主页 用户中心 我的订单 添加授权 管理授权
退出登录
用户登录 用户注册
欢迎来到 UC建站系统

百度搜索结果页批量提取标题和链接的三种方案对比:自己写Python爬虫跑不到第三页就跳验证码今天能用的CSS选择器明天就失效,商业API和在线工具能不能批量稳定跑才是我真正需要的答案

百度搜索结果页想批量提取标题和链接,除了自己写Python爬虫,还有更省心的工具吗?

上个月帮朋友做竞品分析,需要提取某个行业词在百度前5页的所有自然结果——标题、链接、摘要、排名位置。需求听起来简单,但真正做起来才发现问题一大堆:百度页面结构经常变,昨天能用的CSS选择器今天就失效了;查到第3页就跳出验证码;广告结果和自然结果混在一起分不清。前后折腾了两天,换了四种方案才跑通。

这件事让我意识到,百度搜索结果页的批量提取其实有三个层次的问题:能不能抓到(反爬问题)、抓到的是不是对的(解析精度问题)、能不能批量稳定跑(规模问题)。大部分人卡在第一层就放弃了,实际上后面两层才是真正决定提取质量的关键。

三种方案的核心差异,选错等于白费力气

1自写Python爬虫:免费但维护成本高,百度改一次页面结构就得跟着改解析逻辑
2开源现成工具:上手快但功能固定,遇到验证码或大并发基本没法用
3付费SERP API:省心但按次计费,高频调用成本不低

一、百度搜索结果页到底长什么样,哪些字段值得提取

先搞清楚一个基础问题:百度一个搜索结果页面上,到底有哪些数据可以提取?很多人以为就是标题+链接+摘要三件套,实际上可以提取的字段远比想象中多。

一个标准的百度自然搜索结果,至少包含以下可提取字段:结果标题(h3标签内的文本,通常带关键词标红)、真实URL(点击后跳转的目标地址)、摘要文本(标题下方的描述段落)、站点名称(链接下方显示的网站名)、发布时间(部分结果会展示发布日期)、百度快照链接("百度快照"的跳转地址)、排名位置(第几页第几条)。

可提取字段典型提取难度实际用途
结果标题简单关键词排名监控、竞品标题分析
真实URL中等(需二次跳转解析)竞品域名清单、收录分析
摘要文本简单SERP特征分析、内容方向判断
站点名称简单行业玩家识别、域名分布统计
发布时间中等(不是每条结果都有)内容时效性分析
排名位置简单排名趋势追踪
广告标识简单区分付费和自然流量

一个容易忽略的细节:百度搜索结果页的URL并不是目标网站的真实地址,而是百度自己的跳转链接(格式类似 http://www.baidu.com/link?url=xxx)。你需要对这个跳转链接做一次HTTP请求或解析参数,才能拿到目标网站的真实URL。如果跳过这一步,提取出来的一串百度跳转地址是没有任何分析价值的。

二、自己写Python爬虫,Requests+BeautifulSoup是最快的起步方式

1 - 百度搜索结果页批量提取标题和链接的三种方案对比:自己写Python爬虫跑不到第三页就跳验证码今天能用的CSS选择器明天就失效,商业API和在线工具能不能批量稳定跑才是我真正需要的答案 - UC建站系统

如果你只需要偶尔提取少量关键词的搜索结果,Requests + BeautifulSoup这个组合完全够用,整个流程不超过100行代码。核心逻辑就四步:构造搜索URL、发请求拿HTML、用CSS选择器定位结果DOM、遍历提取字段。

构造搜索URL的格式是固定的:https://www.baidu.com/s?wd=关键词&pn=(页码-1)*10。其中wd是搜索词参数,pn控制分页偏移量,每页10条结果,第二页pn=10,第三页pn=20,以此类推。

import requestsfrom bs4 import BeautifulSoupimport timedef baidu_search(keyword, pages=5):results = []headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}for page in range(pages):url = f"https://www.baidu.com/s?wd={keyword}&pn={page*10}"resp = requests.get(url, headers=headers, timeout=10)soup = BeautifulSoup(resp.text, 'html.parser')# 定位自然结果容器(class可能随页面版本变化)for idx, item in enumerate(soup.select('.result.c-container')):title_tag = item.select_one('h3 a')if not title_tag:continueresults.append({'rank': page * 10 + idx + 1,'title': title_tag.get_text(strip=True),'baidu_url': title_tag.get('href', ''),'abstract': (item.select_one('.c-abstract') oritem.select_one('.content-right_8Zs40')).get_text(strip=True) if(item.select_one('.c-abstract') oritem.select_one('.content-right_8Zs40')) else ''})time.sleep(2)  # 请求间隔,别太快return results

这段代码有两个硬伤:第一,CSS选择器 .result.c-container.c-abstract 是百度某个时期的DOM结构,百度经常改版,可能下个月就失效了;第二,没有处理验证码页面,一旦触发验证码,所有后续请求拿到的都是验证码HTML,解析不出任何结果。

三、百度反爬的四个层次,大部分人倒在了第二层

用代码访问百度搜索结果页,反爬机制是绕不开的话题。百度的反爬不是单一策略,而是层层递进的组合拳。理解它的分层逻辑,才知道自己卡在哪一步。

第一层:User-Agent检查

最简单的一道门槛。Python requests库默认UA是"python-requests/2.x",百度一眼就能识别。换成真实浏览器的UA字符串基本就过了。

第二层:请求频率限制

同一个IP短时间内连续请求多个搜索页,百度会先弹出验证码,继续高频则直接封IP一段时间。间隔2-5秒是相对安全的节奏。

第三层:验证码挑战

触发条件:同一IP短时间多次搜索、使用了可疑的请求头组合、访问行为模式异常。验证码有文字验证码和滑块验证码两种,人工绕过成本高。

第四层:行为分析

最高级反爬:分析鼠标轨迹、滚动行为、页面停留时间、点击模式等。单纯的requests请求完全模拟不了这些,必须上浏览器自动化。

自写爬虫能稳定通过的通常只有第一层和第二层。到了第三层验证码,要么接打码平台(成本上去了),要么上浏览器自动化工具。第四层行为分析则几乎只有专业爬虫服务商才能稳定绕过。这也是为什么很多一开始用免费方案的人,跑着跑着就转向了付费工具。

四、升级到Playwright/Selenium,绕过行为分析层

当requests方案频繁触发验证码,就需要升级到浏览器自动化工具。Playwright和Selenium都能启动一个真实的Chrome/Edge浏览器实例,模拟完整的用户操作——打开百度首页、在搜索框输入关键词、点击搜索按钮、滚动页面、等待结果加载。这套流程的行为特征和真人非常接近,能有效降低触发验证码的概率。

Playwright比Selenium更适合这个场景,主要有三个优势:启动速度更快、API设计更现代、自带浏览器驱动不需要额外配置webdriver。写一个基础版的百度搜索结果提取器,Playwright版本的代码量大概在80行左右。

from playwright.sync_api import sync_playwrightdef baidu_search_playwright(keyword, max_pages=5):results = []with sync_playwright() as p:browser = p.chromium.launch(headless=False)  # 建议先非无头模式调试context = browser.new_context(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',viewport={'width': 1920, 'height': 1080})page = context.new_page()for pn in range(max_pages):url = f"https://www.baidu.com/s?wd={keyword}&pn={pn*10}"page.goto(url, wait_until='networkidle')# 检查是否跳到了验证码页if 'verify' in page.url.lower() or page.locator('#captcha').count() > 0:print(f"第{pn+1}页触发验证码,停止抓取")break# 等待搜索结果加载page.wait_for_selector('.result', timeout=10000)items = page.locator('.result.c-container').all()for idx, item in enumerate(items):title_el = item.locator('h3 a').firstif not title_el.count():continueresults.append({'rank': pn * 10 + idx + 1,'title': title_el.inner_text(),'baidu_url': title_el.get_attribute('href'),'abstract': item.locator('.c-abstract,.content-right_8Zs40').first.inner_text()if item.locator('.c-abstract,.content-right_8Zs40').count() else ''})page.wait_for_timeout(3000)  # 翻页间隔browser.close()return results

Playwright方案的实际效果:单次提取一个关键词前5页(约50条自然结果),成功率大概在70-80%之间。剩下的20-30%失败情况,通常是触发了验证码或百度页面改版导致选择器失效。如果你需要每天稳定提取几十个关键词的排名数据,这个成功率不太够用。

五、不写代码的方案:现成的开源工具和在线平台

2 - 百度搜索结果页批量提取标题和链接的三种方案对比:自己写Python爬虫跑不到第三页就跳验证码今天能用的CSS选择器明天就失效,商业API和在线工具能不能批量稳定跑才是我真正需要的答案 - UC建站系统

不想自己写代码的话,GitHub上有几个还不错的开源项目可以直接用。但这些工具的共同问题是维护者更新频率不稳定,百度页面一改版就可能罢工几周甚至几个月。

工具名称类型核心能力局限
BaiduSpiderPython库pip安装即用,支持多页提取、自定义结果数量更新频率低,遇到百度改版可能临时失效
python-baidusearchPython库轻量级,零依赖,直接返回结构化JSON不支持验证码绕过,大批量请求容易挂
baidu-search-scraperGitHub项目封装了ScraperAPI的方案,含完整教程依赖付费API,不是纯免费方案
5118/爱站排名查询在线平台输入域名+关键词即可查排名,无需代码按次/按会员收费,不支持导出原始SERP数据

5118和爱站这类SEO平台也能查关键词排名,但它们返回的是排名数值,不是搜索结果页的原始数据(标题、摘要、URL列表)。如果你的需求是"查自己的网站在某个关键词下排第几",这些平台完全够用。但如果要的是"把某个关键词前5页所有自然结果的标题和链接全导出来做竞品分析",它们就满足不了了。

区分清楚需求:"查排名"和"提取SERP原始数据"是两件完全不同的事。查排名只需要一个数字(第几页第几条),而提取SERP数据需要拿到每条结果的完整信息。选工具之前先确认自己到底要什么。

六、付费SERP API,贵但有贵的道理

如果前面几种方案都不能满足需求——自写爬虫维护太累、开源工具不够稳定、在线平台功能不对口——那就到了付费SERP API的考虑范畴。这类服务的核心价值一句话概括:把反爬、解析、代理、重试这些脏活累活全包了,你只需要一个HTTP请求就能拿到干净的JSON数据。

目前主流的百度SERP API方案有两类:一类是ScraperAPI、Bright Data这类通用爬虫服务商,它们提供百度搜索的专用端点,价格按成功请求次数计费;另一类是Crawlbase、SerpApi这类专注搜索引擎抓取的服务商,对百度页面结构的适配更深入。

服务商免费额度付费起步价百度支持情况
ScraperAPI5000次/月$49/月起支持百度SERP专用端点,返回结构化JSON
Bright Data5000次/月$0.75/千条记录SERP API产品线支持百度,按成功结果计费
SerpApi100次/月$50/月起原生支持baidu引擎参数,解析精度高
Crawlbase1000次/月$29/月起提供百度专用爬取模板,含智能重试

调用付费API的方式非常简单,以ScraperAPI为例,只需要构造一个带参数的URL即可:

import requestsAPI_KEY = "your_api_key"keyword = "网站SEO优化"url = "https://api.scraperapi.com/structured/baidu/search"params = {"api_key": API_KEY,"query": keyword,"page": 1,           # 页码"country_code": "cn" # 中国地区结果}resp = requests.get(url, params=params)data = resp.json()# data["organic_results"] 直接就是结构化结果列表for item in data.get("organic_results", []):print(item["title"], item["link"], item["snippet"])

付费API的真实成本:以一个中等规模的SEO项目为例,每天监控200个关键词的排名变化,每个关键词查前3页(30条结果),按Bright Data $0.75/千条的计费标准,日均成本约$4.5,月成本不到$150。对比自己搭建和维护爬虫系统的时间成本,对于商业项目来说这个开销是划算的。

七、提取出来的数据怎么用,五个实际落地场景

工具和方案讲完了,回到更实际的问题:提取出来的百度搜索结果数据,到底能用在什么地方?

关键词排名监控

这是最基础的应用。提取目标关键词的搜索结果,遍历结果列表匹配自己的域名位置,记录排名变化趋势。相比5118等平台,自己提取能拿到更细粒度的数据——比如前后排名的是哪些网站、它们的标题和摘要长什么样。

竞品SERP分析

提取某个行业核心词前3页的所有结果,统计哪些域名出现频率最高、它们用的是什么标题模式、摘要长度和关键词密度。这些数据能帮你快速摸清一个赛道的竞争格局。

内容缺口发现

对比自己的收录内容与搜索结果中已有的内容,找出用户搜索了但现有结果中缺乏高质量回答的关键词方向。这是做内容差异化最直接的数据来源。

SERP特征变化追踪

百度会不定期调整搜索结果页的展示形式——增加视频结果、知识图谱、AI摘要等。持续提取SERP数据可以监测这些变化,提前调整SEO策略。

行业内容库构建

定期提取行业长尾词的搜索结果,汇总所有自然结果的标题和摘要,构建一个行业级的内容数据库。用UC建站系统的内容中台对这批数据做差异化重组——不同站点从不同角度切入同一个话题,AI生成不同结构的文章,再用百度API和IndexNow双通道推送,比人工逐个词分析效率高出一个数量级。

3 - 百度搜索结果页批量提取标题和链接的三种方案对比:自己写Python爬虫跑不到第三页就跳验证码今天能用的CSS选择器明天就失效,商业API和在线工具能不能批量稳定跑才是我真正需要的答案 - UC建站系统

八、自然结果和广告结果的区分,不区分等于白提取

百度搜索结果页上,广告结果和自然结果是混排的。页面前几条带"广告"或"推广"标识的是付费结果,后面才是自然排名结果。如果你的提取逻辑不区分这两类,数据就会严重失真——把广告位当成自然排名去分析,结论全偏。

区分的方法不复杂。百度广告结果在DOM结构上有明显的特征:通常带有 ec_wise_ad 或类似的广告标识class,或者包含"广告""推广"等文字标签。在解析循环里加一个过滤逻辑即可:

def is_ad_result(item_element):class_str = ' '.join(item_element.get('class', []))# 检查class名是否包含广告标识if any(kw in class_str for kw in ['ec_wise_ad', 'c-gap-top-small']):return True# 检查是否包含"广告"或"推广"文字标签ad_tags = item_element.select('.c-color-gray2')for tag in ad_tags:if tag.get_text(strip=True) in ['广告', '推广']:return True# 检查百度推广专属链接格式if item_element.select('a[href*="e.baidu.com"]'):return Truereturn False

一个数据污染的典型案例:有人用Python脚本提取了"装修公司"这个关键词前3页的结果,导出了30条"排名"数据做竞品分析。结果前4条全是百度竞价的广告,真正自然排名第一的网站被误标成了第5名。基于这个数据做的所有策略全是错的。区分广告和自然结果不是可选项,是必须项。

九、四种方案的选择逻辑,看完不会再纠结

方案选型这件事,说穿了就三个维度:量有多大、频率多高、预算多少。把这三个问题想清楚,方案自动就出来了。

场景推荐方案理由
偶尔用,每月查不到50次Requests+BS4 自写脚本量小不怕封,代码简单,零成本
每天查几十个词,需要稳定Playwright + 代理IP池浏览器自动化降低验证码概率,成本可控
每天几百个词,需要高成功率付费SERP API反爬和解析全托管,95%+成功率,解放精力
只查排名数字,不需要原始SERP5118/爱站/千峰等SEO平台按会员付费,直接出排名结果,不折腾

还有一个很多人忽略的中间方案:自写提取逻辑 + 付费代理服务。解析代码自己写(灵活度高),但把IP代理和验证码绕过外包给代理服务商。这种方案的成本介于纯自建和全托管API之间,适合有一定开发能力但不想花精力维护代理池的团队。

十、批量提取的五个注意事项,踩过坑才总结出来的

不管用哪种方案,批量提取百度搜索结果时有一些通用的注意事项,这些细节直接影响提取成功率:

请求间隔至少2秒

同一个IP两次搜索请求之间至少间隔2-5秒。1秒以内几乎必然触发验证码。可以用time.sleep()加随机抖动,模拟人类操作的不规律性。

User-Agent必须像真人

不要用Python默认的UA字符串。从真实浏览器的UA列表中随机轮换,并且确保UA和请求头中的其他字段(Accept-Language、Accept-Encoding)保持一致。

处理百度URL跳转

搜索结果中的链接是百度跳转地址,不是目标网站的真实URL。要么对跳转链接发HEAD请求获取Location头,要么解析跳转URL中的参数提取真实地址。

容错和重试机制

单次请求失败不应该中断整个批量任务。加try-except包裹每个请求,失败时记录日志、等待更长时间后重试,超过重试次数再跳过。

第五点最重要——合规边界:提取百度搜索结果用于个人学习和研究是灰色地带,用于商业目的(如搭建竞品监控SaaS、转卖数据)则涉及法律风险。百度服务条款明确禁止自动化抓取,大规模高频提取可能导致IP被永久封禁甚至法律追责。做之前想清楚用途和规模。

最后说一点:百度搜索结果页的DOM结构不是一成不变的。它会因为用户是否登录、搜索设备类型(PC/移动)、搜索词类型(普通词/品牌词/新闻词)、甚至A/B测试而返回不同的页面结构。这意味着没有任何一个CSS选择器方案是永远有效的。不管你选哪种方案,都要有"过一段时间可能需要更新解析逻辑"的心理准备。付费API的价值之一就是服务商帮你持续跟进这些变化。

方案选择一句话版

1量小又偶尔 → 自己写几十行Python,零成本够用
2量大要稳定 → Playwright自动化,把反爬成本降到最低
3量大又不想维护 → 付费SERP API,$50-150/月换来省心
4只查排名不查SERP数据 → SEO平台开个会员就行

相关推荐
在线客服
👇找客服拿折扣
QQ咨询&售后
在线时间
11:00 ~ 5:30
QQ:3155555535
👇联系QQ
👇联系WX
首页 程序 帮助 登录