Python爬虫实战:搞定SEO数据采集与排名监控
发布时间:2026/9/2 2:28:49 作者:尧图编辑部 阅读量:1,286

简介这是基于Python开发的SEO数据采集与分析工具面向SEO从业者、网站运营者以及Python爬虫学习者定位在帮助用户用自动化脚本代替手工采集。程序通过自动抓取网页内容可辅助完成关键词研究、元信息检查、链接结构分析、内容质量检测、页面速度测试与错误链接排查等常见SEO任务帮助用户快速定位网站优化点。资料包共6个文件以可执行程序、配置文件、文本说明和网页说明为主压缩包仅786KB轻量易用。其中包含可直接运行的爬虫主程序、配套ini配置项、txt版使用说明与网址导航覆盖从安装到实际运行的完整环节降低了初学者的上手门槛。目前已有375人学习适合希望用自动化方式提升网站搜索引擎排名的初学者和中级运营者参考使用。 做SEO这行最烦的不是分析数据而是收集数据。每天打开浏览器手动访问几十个页面查TDK、检查死链、复制粘贴标题描述一个上午基本就没了。后来我把大部分重复采集动作交给Python爬虫程序才真正从手工搬运工里解放出来。写这篇东西不是讲多么高深的技术就是把我实际写SEO爬虫时用到的方案、踩过的坑都摊开说尤其是程序跑完只显示exit code 0却什么都没输出这种让新手直接懵掉的问题这次一并讲透。1. 日常SEO工作里爬虫程序到底能替我干什么1.1 手动操作半小时脚本几秒钟跑完SEO日常里有太多需要重复收集数据的场景。比如批量抓取全站TDKTitle、Description、Keywords检查有没有空白标题、重复描述、关键词堆砌又比如每隔一段时间把所有页面链接拿出来测一遍状态码看有没有出现死链再比如每周固定查一批核心关键词排名确认最近做的优化动作有没有效果。这些事如果全手动做一次能吞掉大半天。我自己的情况是公司站点两千多个页面过去做全站TDK抽检需要逐条打开页面再复制标题整个人像人肉采集器。后来写了Python爬虫程序把URL列表丢给脚本打印结果几秒出导成Excel表格也就两三分钟。同事看了演示当场要了一份脚本这比我解释十遍爬虫能干嘛都管用。1.2 不同抓取规模要选不同方案也不是所有抓取需求都用同一个方案我按照实际使用频率把它们分成三档轻量静态页面用 requests BeautifulSoup速度快、代码短、好调试适合TDK采集、状态码检测这些小批量任务。中等规模、持续运行用 Scrapy自带并发、中间件、调度器适合每天定时抓几千几万个页面。需要JS渲染用 Playwright 或 Selenium先起一个浏览器内核加载脚本再拿渲染完成后的页面源码适合大量数据靠Ajax加载的站点。这里我建议初期别一上来就上Scrapy。它的学习曲线明显更陡对SEO场景里常见的小批量临时需求经常是杀鸡用牛刀。requests加BeautifulSoup写出来的代码可读性强出了问题也容易顺着代码一行行查。等哪天真到了每天抓几万页的规模再考虑迁移到Scrapy不迟。2. 先把环境搭明白从安装Python到依赖就绪2.1 安装Python与虚拟环境写爬虫程序的第一步是确认本机有Python环境。Windows上建议直接从官网下载安装包安装界面里有一项Add Python to PATH千万别漏勾否则后面在CMD里敲python会提示找不到命令。装好后打开终端验证输入python --version能输出版本号说明安装没问题。我强烈建议给爬虫项目单独建一个虚拟环境。虚拟环境能把requests、beautifulsoup4这些依赖隔离到项目目录里避免多个项目之间的包版本互相打架。Windows下创建和激活的命令python -m venv seo_env seo_env\Scripts\activatemacOS或Linux下激活命令略有区别用source seo_env/bin/activate。激活成功的标志是终端提示符前面出现(seo_env)看到这个前缀再继续装依赖能省掉后面一大堆麻烦。2.2 装依赖时两个高频疑问进入虚拟环境后安装依赖只需要两条命令pip install requests pip install beautifulsoup4如果下载速度实在慢就换国内镜像源例如清华源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests第一次装依赖的朋友特别容易遇到一个怪现象pip install明明提示安装成功运行脚本却报ModuleNotFoundError。这种情况九成是没激活虚拟环境或者当前终端里的python和pip指向了不同的Python路径。解决方式很简单查看一下python和pip分别指向哪个目录确保它们属于同一套环境where python where pip两条命令返回的路径前缀应该一致。3. 从需求到落地一个TDK批量采集脚本的完整实现3.1 写一个能直接跑的版本先给一个最基础的TDK采集脚本。逻辑很直白遍历URL列表请求页面解析title、description、keywords三个字段把结果打印出来。import requests from bs4 import BeautifulSoup HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } urls [ https://example.com, https://example.com/about, https://example.com/products/1 ] for url in urls: try: resp requests.get(url, headersHEADERS, timeout10) resp.encoding resp.apparent_encoding soup BeautifulSoup(resp.text, html.parser) title soup.title.string.strip() if soup.title else desc_tag soup.find(meta, attrs{name: description}) description desc_tag.get(content, ).strip() if desc_tag else kw_tag soup.find(meta, attrs{name: keywords}) keywords kw_tag.get(content, ).strip() if kw_tag else print(url, resp.status_code, title, description, keywords) except requests.RequestException as e: print(url, 请求失败, e)把urls列表换成目标网站的真实页面地址就能跑。里面有一个新手最容易忽略的细节resp.encoding resp.apparent_encoding。中文网页如果未手动指定编码requests有可能用错误的编码去解码响应体导致title和description里全是乱码。apparent_encoding是requests根据响应内容自动推断的编码方式实测成功率比单纯依赖响应头里的charset高很多。3.2 为什么要带User-Agent推荐用什么喂URL代码里HEADERS是用来模拟浏览器的。现在很多站点对裸requests请求会直接拒绝返回403或者丢一个安全验证页面。带上常见浏览器的User-Agent之后被拦截的概率会明显下降。如果对付的站点特别严格还可以把Accept、Accept-Language这些字段一起补上让它看起来更像真实用户。另一个建议是别把URL列表硬编码在代码里。更合理的做法是维护一份urls.txt文本文件让脚本去读取with open(urls.txt, r, encodingutf-8) as f: urls [line.strip() for line in f if line.strip()]这样每次增删页面只需要编辑文本文件不用动代码更不用翻到脚本里找列表改来改去。3.3 从打印到Excel让数据可以直接交给老板print结果只能自己看真要给客户、给老板做报告还是导出成Excel最省事。推荐用pandas配合openpyxlpip install pandas openpyxl然后在循环里把每条结果追加到rows列表最后统一转成DataFrame写入Excelimport pandas as pd rows [] # 在for循环里 append (url, status_code, title, description, keywords) # 循环结束后执行 df pd.DataFrame(rows, columns[URL, 状态码, 标题, 描述, 关键词]) df.to_excel(tdk_check.xlsx, indexFalse) print(已导出, len(rows), 条数据)pandas不是爬虫的必需品但它处理表格数据非常方便。如果只想快速看结果用python自带csv模块写CSV也完全可行按个人习惯选。4. 排名监控脚本批量拿到关键词排名数据4.1 构造搜索URL并定位自己的站点排名监控是SEO需求里的高频场景。思路不复杂用requests请求搜索引擎的结果页解析每一条结果的链接然后判断目标域名出现在第几位。我以必应搜索为例写一个可运行版本import requests import urllib.parse from bs4 import BeautifulSoup HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } keywords [SEO优化, 网站推广] site_domain example.com for keyword in keywords: url https://www.bing.com/search?q urllib.parse.quote(keyword) resp requests.get(url, headersHEADERS, timeout10) soup BeautifulSoup(resp.text, html.parser) rank 0 found False for li in soup.select(li.b_algo): rank 1 a_tag li.find(a) if not a_tag: continue href a_tag.get(href, ) if site_domain in href: print(f关键词「{keyword}」排名第 {rank} 位) found True break if not found: print(f关键词「{keyword}」未发现目标域名)这里用urllib.parse.quote对关键词做URL编码避免中文和特殊符号导致请求出错。选择器li.b_algo是必应搜索结果列表的通用DOM类名。不同搜索引擎的结构不一样换百度或Google时记得先打开网页源码确认对应搜索结果块的CSS类名再改。4.2 排名数据准确性有限定位为趋势监测更靠谱自写排名监控脚本胜在免费、可定制、关键词数量不限但准确性肯定比不过商业工具。搜索引擎结果页常常带地域推荐、个人化推荐同一个关键词在你这里和同事那里返回顺序可能不同。所以我建议把脚本定位成趋势监测而不是绝对排名。连续记录一周、一个月看排名曲线的走向比纠结某一天到底排第几更有参考价值。另外如果站点本身被搜索引擎处罚或者收录不稳定排名数据会特别难看。这个脚本恰好能当预警工具用当某类页面排名集中消失立刻去查收录情况和蜘蛛抓取日志定位效率会高很多。4.3 合规与反爬控制频率、遵守robots协议自己写爬虫程序抓搜索引擎结果页必须注意合规问题。搜索引擎服务条款普遍对自动化采集有限制所以第一原则是严格控制请求频率比如每次请求之间至少sleep三到五秒。关键词多就分批跑不要一次性连发几十个请求。第二是尽量遵守目标网站的robots.txt规范抓取之前先看一眼允许和禁止的路径。这类脚本只适合监测自己站点和竞品公开页面的基础信息不要拿去做恶意采集、撞库或者攻击性动作这是底线。5. 高频报错现场程序跑完只显示exit code 0却完全没有输出5.1 先理解exit code 0到底代表什么我见过不少SEO同行的爬虫问题描述Python程序运行不出内容只显示Process finished with exit code 0。第一次遇到这个提示很多人以为程序崩了其实exit code 0在Python里恰好表示程序正常结束没有抛出异常。真正的问题不是程序报错而是它什么都没做或者做了但没留下可见结果。后面的排查思路可以归结为一句话人肉判断程序到底执行到了哪一步把看不见的中间过程显性化。5.2 第一个高频原因逻辑根本没被执行最常见的场景是写了ifname main: main()但main函数名写错或者缩进有问题又或者核心打印代码被注释掉了。程序启动了但核心逻辑一行没跑。之前帮同事排查过一段代码发现他把main()调用写在了if语句外面缩进层级不对主流程根本没有被触发。这时候程序当然正常退出但也什么都看不到。排查方法很粗暴在脚本开头和关键函数第一行各临时加一句print(进入xxx)确认执行流走到哪里。一旦看到打印语句一条条出现就说明问题出在更靠后的环节而不是被拦在最前面。5.3 第二个高频原因数据解析为空但程序没有报错BeautifulSoup的find系列方法在找不到目标节点时不会抛异常而是返回None或空列表。如果继续往下取属性就得到空字符串。又因为print输出为空界面看起来一片空白给人程序没干活的错觉。解决办法是先把解析结果存进变量再打印出来观察soup BeautifulSoup(resp.text, html.parser) title_node soup.title print(标题节点:, title_node) if title_node: print(标题文本:, title_node.string) else: print(页面里没有title节点检查是否被反爬拦截或选择器写错)这样至少能看清楚到底拿到数据没有而不是让程序默默吞掉所有逻辑。写正式脚本时宁可多打印几行调试信息也不要写完就删成哑巴程序运行结果一旦异常有日志比没日志容易排查得多。5.4 第三个高频原因请求被拦截返回的是验证页面请求被目标站点的反爬机制拦截时HTTP状态码可能仍然是200但响应体根本不是真实页面而是验证码页或安全校验页。用BeautifulSoup去解析这种页面自然拿不到想要的title和结果列表程序也就安静地跑到结束最后exit code 0。所以每次请求后最好打印resp.status_code以及resp.text的前200个字符观察返回内容是否符合预期。一旦确认被拦截先检查User-Agent设置再看看是否缺少Cookie、Referer等请求头以及请求间隔是不是太短。如果目标站点是重前端渲染的必要时升级成Playwright方案用真实浏览器加载后再解析代价是资源占用明显提升权衡之后再做。6. 几处进阶经验和长期维护建议6.1 定时任务让爬虫程序自己跑起来SEO监控是周期性需求没必要每次手动跑脚本。Windows下用任务计划程序Linux下用crontab都能实现定时执行。跑起来之后建议把结果输出到带日期的文件里比如tdk_check_20250601.xlsx方便追溯历史数据。我实际工作中的节奏是周一周四各跑一次排名监控周六跑一次全站死链检查每次自动把日志写入文本文件月底汇总对比。死链检查的脚本本质上就是批量发HEAD请求def check_links(urls): for url in urls: try: resp requests.head(url, headersHEADERS, timeout8, allow_redirectsTrue) print(url, resp.status_code) except requests.RequestException: print(url, 请求异常)用HEAD请求的原因是很省流量它只返回响应头不下载整个页面正文。这个脚本跑在定时任务里能及时发现页面被删除、域名解析异常、服务器响应超时等问题。6.2 改代码之前先备份放量之前先小样验证爬虫脚本虽然看起来简单但线上跑久了改起来容易踩雷。我习惯在每次改动前复制一份带日期的备份文件例如seo_crawler_20250601.py。改坏了随时回滚不至于连能跑的版本都没了。另外一个必须养成的习惯是凡是涉及大批量请求的脚本强烈建议先拿3到5个URL做小规模验证。确认输出格式、状态码、解析结果都正常再放开到全量列表。千万别一上来直接跑几千个URL万一选择器写歪或者编码设错了Excel里全是半截数据排查成本比省下的那几分钟高多了。6.3 SEO爬虫程序带来的真正变化从我的实际感受看最大的变化不是表面上的省了多少时间而是采集频率提上去了。以前一周只能做一次全站TDK抽检现在每天都能跑一遍页面标题一旦缺失或者被程序二次修改当天就能发现。另一个变化是报告交付速度变快了客户上午要排名表下午就能出一份带格式的Excel不需要临时截图和手动录入。做SEO爬虫程序核心其实不是代码写得多花哨而是你愿不愿意把重复劳动拆解成可以自动化的流程。一个顺手的小脚本每次改一点慢慢就会长成最适合自己工作流的工具。本文还有配套的精品资源点击获取