资讯动态

Python网页数据自动录入Excel:从爬虫到表格的完整方案

发布时间:2026/10/24 6:07:50 来源:尧图企业网站定制
没接触过爬虫的人一听到“网页数据录入Excel”第一反应多半是复制、粘贴、再清洗一条一条地弄。但凡是干过几次这种重复劳动都会觉得不对劲网页上明明有几百上千条数据靠手工录到表格里又慢又容易错。后来我给自己写了一套小工具用Python把网页里的目标数据抓下来再直接写进Excel整个过程几分钟就跑完。今天把这个思路完整地拆开聊一聊包含方案选型、代码实现、踩坑实录让不写代码的同事看完也能动手试一把。这个“网页数据录入Excel”的解决方案本质上是三个环节的组合抓取网页内容、解析筛选出需要的数据、把结构化结果写入Excel表格。需要的基础是懂一点点HTML标签、会安装Python库不需要数学编程基础。适合四类人看经常要看网页做报表的运营、电商选品和比价的人、被重复粘贴折磨的职场新人、想用代码解决日常问题但不知道从哪入手的开发者。我这里用的组合是requestsBeautifulSoupopenpyxl这也是这个场景里最稳妥、最省心的技术栈。下面按完整流程来讲。1. 为什么选择“脚本解决”这条路1.1 先看几个真实场景先说个我遇到的典型需求。某运营同事负责每周整理竞品线上商城的商品价格和库存光这一件事每周要花掉大半天时间打开网页、逐条复制名称、价格、上下架状态再贴进Excel还要顺手调整格式来保证表格干净。最麻烦的是同样操作下周还要再做一遍一点技术含量都没有还容易在复制粘贴中漏掉一行。类似的场景非常多从行业公示网站收集一批企业名单、编号、状态信息。把电商平台某个分类下的商品名称、价格、链接整理成比价表。从技术文档或新闻列表页批量获取标题、发布时间、摘要。把网页表格HTML table里的数据整体转换为Excel表格。这些场景有一个共同特点数据已经存在于网页上结构是规律的只是没有一个直接的“下载Excel”按钮。所以真正需要的不是一个复杂的大数据平台而是一个能“把网页上的结构化信息搬进表格”的机械化流程。1.2 复制粘贴为什么不是长久之计手工复制粘贴最大的问题不是慢而是不可控。你永远不知道自己是不是漏掉了某一行也不知道网页加载出来的数据在粘贴后有没有发生错位。尤其是数据量超过几十条之后肉眼很难逐条检查。除此之外重复性操作还带来一个隐藏成本注意力消耗。人的精力放在机械操作上就没法去思考数据本身的意义。用脚本代替重复劳动并不是懒人想法而是把时间留给真正需要判断的事比如检查数据差异、分析价格走势、发现异常项。1.3 方案选型为什么是Python三件套做网页数据采集可选的技术路线其实不少。可以写浏览器插件也可以用现成的图形化工具还可以用Python写脚本。几个方案对比之后我最终一直推荐“Python requests BeautifulSoup openpyxl”这套组合原因是requests负责网络请求代码量极小十几行就能拿到网页HTML源码。BeautifulSoup解析HTML的逻辑很贴近人的思维可以像“在网页里找元素”一样写选择器不用写复杂正则表达式。openpyxl直接操作.xlsx文件能做样式、能设置列宽、能追加数据不需要经过CSV中转。组合起来一共只有三个依赖库环境搭建成本低初学者也能在一个下午跑通。也有人问为什么不用Selenium这种自动化浏览器工具这个后面会专门讲这里先说结论如果你的目标网页是纯静态的打开就能看到数据用Selenium属于“杀鸡用牛刀”启动浏览器、加载页面带来的时间开销和稳定性问题都会被无限放大。2. 动手前必须做好的准备工作2.1 环境搭建与镜像源配置开始写代码前先把Python环境理顺。我建议从头建一个干净的虚拟环境避免和系统里其他项目冲突。命令行窗口执行python -m venv venvWindows下激活虚拟环境venv\Scripts\activatemacOS/Linux下激活source venv/bin/activate然后安装三个库pip install requests beautifulsoup4 openpyxl如果下载速度不理想可以临时指定一个国内PyPI镜像源下载速度会快很多。这类镜像源在网上非常多随便选一个稳定可用的即可。注意不要图省事直接pip install bs4之后不装beautifulsoup4这两个包名对应不同的发行版本。推荐直接安装beautifulsoup4这样在脚本里from bs4 import BeautifulSoup才能正常工作。2.2 网页结构基础先看懂HTML再说写爬虫脚本本质上就是在HTML里“找东西”所以起码要看得懂最基本的标签长什么样。一个最简单的网页条目结构通常是这样的div classproduct-item span classtitle无线鼠标/span span classprice¥89.00/span a href/detail/123查看详情/a /div这里面涉及三个HTML核心概念标签tagdiv、span、a这些尖括号包裹的标记。属性attribute标签里的classproduct-item就是属性用来标记元素的类别或身份。层级关系外层div里面包裹了多个子元素这就是HTML的树状结构。爬虫的解析逻辑就是根据这些标签和属性把目标数据“摘”出来。这个过程跟在超市里按货架标签找商品差不多先定位到货架外层容器再拿想要的那几样名称、价格、链接。2.3 用浏览器开发者工具定位目标元素打开目标网页后按F12打开开发者工具使用左上角的“选取元素”按钮点击页面上你想要的数据右侧Elements面板会自动定位到对应的HTML代码。这时需要做的只是观察每条数据是不是都在同一个容器标签里名称、价格、链接分别用了什么class属性数据是在HTML源码里直接可见还是需要等页面JS加载之后才出现最后这个问题特别关键它直接决定了你用静态请求还是自动化浏览器。判断方法很简单在Elements面板里看到的数据如果右键“查看网页源代码”也能找到就说明是静态数据如果源代码里没有只有Elements里能看到那就是动态加载静态方案要换思路。3. 核心代码实现从网页到Excel的完整流程3.1 一次合格的网页请求长什么样写爬虫最容易犯的错是不带任何请求头直接requests.get(url)然后莫名其妙被拦截。很多网站不仅看你的IP还看请求头里的User-Agent一个普通浏览器的UA和一个Python脚本默认UA服务器的回应完全不一样。一个比较规范的请求是这样import requests 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, Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9, } resp requests.get(https://example.com/products, headersheaders, timeout10) resp.raise_for_status() # 状态码不是200时抛出异常避免继续往下执行 resp.encoding resp.apparent_encoding # 自动识别网页编码防中文乱码 html resp.text这几个细节都有原因User-Agent改成浏览器的UA是为了让服务器觉得“这是一个正常用户在访问”。timeout10是网络超时限制防止某个请求卡住导致整个脚本停摆。resp.encoding resp.apparent_encoding是为了解决中文编码乱码中文网页常见的编码有UTF-8和GBK手动指定容易出错让requests自动探测最省事。3.2 解析HTML并提取数据拿到HTML字符串之后交给BeautifulSoup解析from bs4 import BeautifulSoup soup BeautifulSoup(html, html.parser) items soup.select(div.product-item)soup.select()接收的是CSS选择器这个语法对熟悉前端的人零成本。不熟悉也没关系记住几种常用写法就行select(div)选择所有div标签。select(.price)选择所有class包含price的元素。select(#main)选择id等于main的元素。select(div.product-item .title)选择class为product-item的div里面的、class为title的所有元素。拿到列表之后逐条提取字段for item in items: title item.select_one(.title) price item.select_one(.price) link item.select_one(a) if not title or not price: continue # 缺字段的就跳过别硬处理 product_name title.get_text(stripTrue) product_price price.get_text(stripTrue) product_link link.get(href, ) if link else select_one()只取第一个匹配元素适合已知每个条目里只有一个目标字段的情况。get_text(stripTrue)获取元素里的纯文本并去掉首尾空格get(href, )取链接属性取不到就返回空字符串。这里有个经验解析的时候别写得太“死”。比如价格字段刚才还是£89.0过两天网页结构改成₽89.0那脚本就抓不到了。更稳妥的做法是只取字段内部的关键文本不要硬编码完整的匹配文本。3.3 数据清洗环节不要原样写入网页上提取出来的数据很少是“干净”的。价格可能带货币符号库存状态可能混着一堆空白字符链接可能是相对路径。所以写入Excel之前需要做一次简单的数据清洗。拿价格举例常见处理方式import re price_text ¥ 89.00 price_clean re.sub(r[^\d.], , price_text) # 只保留数字和小数点 price_value float(price_clean)链接如果是相对路径要拼接成完整URLfrom urllib.parse import urljoin full_url urljoin(https://example.com, product_link)清洗的目标不是把数据改得漂亮而是让Excel里的数据格式统一方便后面做筛选、排序、求和。如果带货币符号直接写入你会发现Excel里“求和”根本算不出来。3.4 用openpyxl写入Excel并处理格式写入环节来看代码from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment wb Workbook() ws wb.active ws.title 商品清单 ws.append([商品名称, 价格(元), 商品链接]) for name, price, url in cleaned_data: ws.append([name, price, url])追加表头和数据都用ws.append()它会自动在下一空行写入。但光写入还不够一个让读者舒服的Excel至少应该做到三点表头加粗底色加深和数据区域区分开。列宽根据内容自动调整。价格列设置数字格式单位为元保留两位小数。代码是这样的header_font Font(colorFFFFFF, boldTrue) header_fill PatternFill(start_color4472C4, end_color4472C4, fill_typesolid) for cell in ws[1]: cell.font header_font cell.fill header_fill cell.alignment Alignment(horizontalcenter) ws.column_dimensions[A].width 30 ws.column_dimensions[B].width 12 ws.column_dimensions[C].width 40 for row in ws.iter_rows(min_row2, min_col2, max_col2): for cell in row: cell.number_format 0.00 wb.save(网页数据.xlsx)注意ws[1]是第一行的所有单元格column_dimensions设置列宽需要手动指定合理的宽度Excel没有“自动最适合列宽”的默认设置。3.5 完整脚本一套可以直接抄的流程把前面的部分拼起来就是一套从URL到Excel的完整脚本。我习惯把项目拆成三个文件spider.py负责抓取解析cleaner.py负责清洗exporter.py负责写Excel。不过对于一次性任务写一个脚本文件完全够用。完整核心逻辑如下import re import requests from bs4 import BeautifulSoup from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment from urllib.parse import urljoin BASE_URL https://example.com/products 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, } def fetch_html(url): resp requests.get(url, headersHEADERS, timeout10) resp.raise_for_status() resp.encoding resp.apparent_encoding return resp.text def parse_products(html): soup BeautifulSoup(html, html.parser) results [] for item in soup.select(div.product-item): title_el item.select_one(.title) price_el item.select_one(.price) link_el item.select_one(a) if not title_el or not price_el: continue name title_el.get_text(stripTrue) price_text price_el.get_text(stripTrue) price_value float(re.sub(r[^\d.], , price_text)) href link_el.get(href, ) if link_el else full_url urljoin(BASE_URL, href) results.append([name, price_value, full_url]) return results def save_to_excel(data, filename网页数据.xlsx): wb Workbook() ws wb.active ws.title 商品清单 ws.append([商品名称, 价格(元), 商品链接]) for row in data: ws.append(row) header_font Font(colorFFFFFF, boldTrue) header_fill PatternFill(start_color4472C4, end_color4472C4, fill_typesolid) for cell in ws[1]: cell.font header_font cell.fill header_fill cell.alignment Alignment(horizontalcenter) ws.column_dimensions[A].width 30 ws.column_dimensions[B].width 12 ws.column_dimensions[C].width 60 for row in ws.iter_rows(min_row2, min_col2, max_col2): for cell in row: cell.number_format 0.00 wb.save(filename) if __name__ __main__: html fetch_html(BASE_URL) clean_data parse_products(html) save_to_excel(clean_data) print(f完成共写入 {len(clean_data)} 条数据)这段代码已经能覆盖绝大多数静态网页的数据采集需求。4. 完整演示案例从商品列表抓取到Excel4.1 演示目标与关键分析为了把前面几个章节串起来我给一个真实的模拟案例目标是一个商品列表页页面上有多条商品信息结构固定。我们要做的事情是抓取所有商品名称、价格、链接清洗后保存成一份带表头的Excel文件。打开页面F12后观察到以下结构div classproduct-item span classtitle樱桃机械键盘/span span classprice¥ 349.00/span a href/goods/1001详情/a /div这说明每条商品都在div.product-item里名称在.title价格在.price链接在条目里的a标签。这就是前面代码里选择器写法的来源。4.2 运行流程与结果验证在命令行执行脚本python spider.py正常情况下输出完成共写入 36 条数据打开生成的Excel文件可以看到商品名称价格(元)商品链接樱桃机械键盘349.00https://example.com/goods/1001无线静音鼠标89.00https://example.com/goods/1002检查时不要只看条数随手抽查三行数据把Excel里的内容和网页实际内容比对一下。重点检查三处价格小数位是否正确、链接是否完整、是否有空行混入。4.3 如何把脚本泛化成通用工具实际工作中需求不大可能是“永远抓同一个页面”。更多情况是“换个页面再抓一遍”。所以脚本里的选择器和URL最好抽出来作为配置项放在脚本顶部的变量区域。我一般会这样做CONFIG { url: https://example.com/products, container_selector: div.product-item, fields: { name: .title, price: .price, link: a, }, excel_name: 商品清单.xlsx, }每次换新页面只需要改CONFIG字典改完后再跑一次确认新页面的结构匹配。如果新页面结构差异太大再微调选择器即可。4.4 多页翻页抓取思路网页数据如果分布在多页可以做一个翻页的循环。常见翻页URL有两种形式一是URL里有页码参数二是点击“下一页”按钮触发请求。URL页码形式的处理最简单for page in range(1, 6): page_url fhttps://example.com/products?page{page} html fetch_html(page_url) data.extend(parse_products(html)) time.sleep(1) # 每页之间延迟1秒降低对目标站点的压力这里加time.sleep(1)不是磨蹭而是基本的访问礼节。爬虫和普通浏览器的区别在于速度快如果每秒钟请求几十个页面服务器很容易判断为异常访问。主动降低请求频率是避免被封号的最简单手段。5. 那些年我们踩过的坑常见问题排查实录5.1 网页元素抓不到可能是动态加载最常遇到的坑是用requests请求后发现HTML源码里根本没有目标数据。这时候先在浏览器里看整个HTML源码搜索目标字段如果搜索不到说明数据是通过JavaScript发请求后用脚本渲染上去的静态请求拿不到完整内容。这时的处理路径有三条找到页面背后的数据接口往往是一个JSON API直接请求接口拿数据效率最高。改用Selenium或Playwright做自动化浏览器让真实浏览器渲染完成后再解析。放弃页面渲染直接在HTML里找服务器预埋的数据变量有时也能挖到。判断到底用哪条路径取决于对方站点是否提供了一种不需要完整页面渲染的数据来源。很多网页为了前后端分离都会有一个直接返回JSON的接口找到这个接口连BeautifulSoup都可以省掉。5.2 中文乱码问题中文乱码十有八九是编码判断错误。解决方案就是前面代码里那句resp.encoding resp.apparent_encodingapparent_encoding是requests根据HTTP头、HTML 声明、内容统计推测出来的编码。多数情况下它是对的但偶尔也会猜错。如果遇到中文乱码可以自己打印resp.apparent_encoding值再手动指定一次。比如网站明确是GBK编码resp.encoding gbk5.3 被反爬限制返回403或验证码请求返回403大多是反爬策略生效。优先检查是否缺少User-Agent。然后检查是否需要添加Referer很多站点会校验请求来源Referer必须是目标页面本身的域名才放行。再不行可以加Cookie模拟一个已登录用户的状态。反爬这块的重点是不做对抗而是减少特征降低请求频率加随机延迟。随机化User-Agent多备用几个浏览器UA。遇到重要数据页面优先找公开的数据接口。注意采集公共数据之前一定先看目标网站的条款。本文讨论的是自动化办公场景下的数据整理所有实践都应限定在允许访问的公开信息范围内。5.4 写入Excel后数字格式不对价格写入Excel后如果变成文本格式求和时会出问题。根因是清洗环节没把字符串转成float写入Excel的仍是文本。检查方式很简单在Excel里点击该列单元格看编辑栏显示的是数字还是文本。如果是文本回到清洗代码确认float()转换是否成功执行。还有一种情况是价格字段里混入了逗号千分位比如1,299.00这时候用re.sub(r[^\d.], , price_text)会把逗号删掉变成1299.00正好处理干净。5.5 常见问题速查表现象根因解决方案返回403缺请求头或触发反爬补全UA/Referer降低频率中文乱码编码判断错误resp.encoding resp.apparent_encoding目标数据为空动态加载找JSON接口或改用SeleniumExcel里价格求和为0价格是文本格式清洗时float()数字格式化链接只有相对路径页面内链接是相对路径用urljoin拼接完整URL某条数据缺字段报错页面上有空条目字段缺失时continue跳过5.6 独家避坑技巧先用本地文件调试一个我常年使用的调试习惯先不直接请求线上网页而是把网页HTML源码保存到本地先用本地文件跑通解析和写入逻辑。with open(page.html, r, encodingutf-8) as f: html f.read() soup BeautifulSoup(html, html.parser)这样做的价值在于解析逻辑不会受到网络波动、反爬拦截的影响出错时可以基于同一份HTML反复调试选择器。等本地解析完全正确了再把逻辑接回requests一次性跑通。尤其是选择器写不对的时候这招能把调试时间压缩一半以上。6. 进阶玩法让这套方案更“程序员范儿”6.1 用pandas替代手写清洗逻辑当数据量变大、字段变多之后逐条清洗和写入的手写逻辑会越来越繁琐。这时候可以引入pandas把数据先组装成二维表再一行代码导出Excel。import pandas as pd df pd.DataFrame(data, columns[商品名称, 价格, 商品链接]) df[价格] pd.to_numeric(df[价格], errorscoerce) df.to_excel(网页数据.xlsx, indexFalse)pandas的优势在于表格处理能力可以直接筛选、排序、去重、分组统计甚至还能从多个网页抓来的数据做横向合并。适合需要做进一步分析的场景。6.2 定时自动采集脚本跑通之后下一步自然是让它自动跑。Windows下可用任务计划程序“触发器”设置每周或每天执行一次“操作”指定需要执行的Python命令就会在指定时间自动运行脚本并生成新的Excel文件。macOS或Linux下用crontab0 9 * * 1 cd /path/to/project /path/to/venv/bin/python spider.py上面的意思是每周一早上9点执行一次。固定时间自动采集的最大好处是你只需要在数据真正变化的那一天打开Excel看结果其他时间完全不用管。6.3 处理动态网页的进阶方案Selenium什么时候才用强调一下Selenium不是首选方案而是兜底方案。只有在确认目标页面是动态渲染、且找不到数据接口的时候才用Selenium。它启动浏览器、加载页面、点击翻页真实模拟人的操作能拿到完整渲染后的HTML。用Selenium的简单示例from selenium import webdriver from selenium.webdriver.chrome.options import Options options Options() options.add_argument(--headless) # 无界面模式不弹浏览器窗口 driver webdriver.Chrome(optionsoptions) driver.get(https://example.com/products) html driver.page_source driver.quit()拿到的HTML再交给BeautifulSoup解析后续流程完全一样。但要清醒地认识到Selenium的启动开销大、运行速度慢、对资源占用高只适合少量动态页面。6.4 这套方案的边界这个方案能解决“网页数据录入Excel”但并不适合所有场景。比如大规模爬取、需要登录的复杂系统、高度反爬的站点这些都需要更专业的工程化手段不在本文讨论范围内。对手头这个需求——把网页上公开可见的结构化数据整理成Excel——脚本方案已经做到了“低成本、可复制、免重复劳动”这三件事剩下的就是随用随改。最后说点个人体会。我见过很多同事第一次跑通脚本时的表情有点不敢相信网页数据真的自己进了Excel。但你真把这个流程跑通之后会觉得它其实没什么高深的地方——拆解问题、选工具、写循环、调格式每一步都是可以学习的经验。这个方案后续还能扩展成定时任务、邮件自动推送、图表自动生成全看你的想象力。动手是第一步别想太多装好环境复制这段代码换上你自己的网页地址跑一下试试。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑