资讯动态

Python requests库实战:从自动化办公到接口调用的全面指南

发布时间:2026/9/26 7:21:01 来源:尧图企业网站定制
每天打开电脑先把昨天的报表页面挨个刷一遍复制粘贴到汇总表里再花十几分钟处理那些登录、下载、重命名的机械操作。如果你也被这类工作缠住Python里的requests库就是你最值得先学会的那个自动化工具。它要做的事情一句话就能讲明白把浏览器里那些手动点击、填写、提交的动作变成几行可以被反复执行的代码。我用requests做自动化办公的时间不短从批量下载报表到定时推消息从和内部系统对接数据到处理几十个接口的联调绝大多数重复劳动都是靠它解决的。这篇文章就把我自己的使用经验、踩过的坑和可复制的套路都整理出来适合刚刚接触Python、想用代码省下时间的办公人也适合已经会写脚本但一直没把它用顺的开发者。1. 为什么自动化办公的第一步我推荐requests1.1 自动化的本质是让机器去和机器对话办公自动化的核心并不是把事情变得更复杂而是把人盯着网页操作变成程序直接向服务器要数据、交数据。你在浏览器里点按钮、填表单、按查询背后其实都在做同一件事向服务器的某个地址发送一个请求然后等服务器返回页面或数据。requests这个库就是专门干这个的它把整个流程简化成一行代码。我经常和同事打一个比方requests就像一个非常听话、手脚麻利的实习助理你告诉它去某个网址带上这些参数问一下它就去问然后把对方的原话一个字不改地带回来。区别在于真人助理会累、会漏、会拖延但脚本不会只要你有耐心把逻辑写好它可以从早到晚干同一个动作上千遍不发脾气。很多人一提自动化办公第一反应是用Excel宏、按键精灵、影刀这类工具。这些方案当然有用但它们更偏向于机械模拟一旦网页改版、弹窗变化脚本就很容易失灵。requests走的是另一条路——直接和接口对话只要后台地址和参数没变前端页面怎么折腾都不影响你的脚本。这不光更稳定也让你能处理更复杂的数据流转任务。1.2 requests能覆盖办公里的哪几类活requests是个HTTP请求库所以它擅长所有和请求接口相关的场景。以我自己的实际经验日常办公里至少有四类活儿是它的舒适区一是信息收集比如每天把各系统里的状态、数据拉回来集中汇总二是批量操作比如批量核对订单、批量查物流、批量下载附件三是定时推送比如每天定点把统计结果发到群里四是系统间对接比如把A系统的数据提交给B系统。但它也不是万能的。如果某个页面里的数据是JavaScript动态渲染出来的单纯用requests拿不到完整内容因为那需要浏览器环境去执行脚本。这种时候通常要配合其他工具比如找背后的真实接口地址或者使用能够渲染页面的自动化框架。所以requests更像是一把趁手的螺丝刀能覆盖大多数场景但遇到极少数硬骨头时你得知道它是边界在哪。1.3 什么人需要把它学透我觉得只要你的工作里出现过下面任何一种情况就有必要认真学一下requests每天要下载好几个报表、月底要汇总一堆Excel、经常在各种系统之间搬运数据、或者总需要帮同事写点小工具。不夸张地说行政、财务、运营、数据分析、测试、运维几乎每个岗位都能用到它。更关键的是requests的入门成本极低。你不需要先啃完整本Python语法书只要懂变量、循环、函数这仨概念就能开始写自动化脚本。它的核心模型只有一个请求——响应。你在浏览器里看到的那套东西在代码里用几十行就能还原出来。2. 五分钟快速上手安装和第一行请求代码2.1 环境准备装好Python和requests动手之前先把地基打好。requests是第三方库需要先装上Python建议用3.8以上的版本因为新版本的urllib3依赖和安全机制都更省心。Python装好后打开命令行直接安装requestspip install requests装完顺便确认一下版本避免后面出现莫名其妙的兼容问题python -c import requests; print(requests.__version__)如果看到类似2.31.0这样的版本号就说明环境没问题了。我一般习惯顺手建一个独立虚拟环境来装第三方库不和系统里的其他项目互相污染。不过这只是个人习惯如果只是写几个脚本放自己电脑上用直接全局安装也没有太大问题。提示Windows用户如果在命令行里发现pip不是内部或外部命令多半是装Python时没勾选Add Python to PATH。重新跑一下安装包勾上这个选项再修复一遍就好。2.2 第一个GET请求requests库的看家本领requests里面最常用的方法就是get它对应浏览器里输入网址回车后发出的那种请求。下面这段就是最精简的GET调用import requests r requests.get(http://192.168.1.10:8000/api/status, timeout5) print(r.status_code) print(r.text)我拿内网地址举例是因为真实办公场景里绝大多数自动化脚本访问的都是公司内部系统的接口这种地址在外网无法访问所以大家放心替换成自己系统的地址就行。如果请求的接口还需要带查询条件比如搜索关键词、页码、时间范围就把它放到params参数里r requests.get( http://192.168.1.10:8000/api/search, params{keyword: 月度报表, page: 1}, timeout5 ) print(r.url)这里有个容易被新手忽略的细节params里的字典requests会自动帮你做URL编码。你不需要自己把中文转换成百分号开头的字符串这一点比我最早用urllib时省心太多。我把r.url打印出来就是为了确认最终发出的地址是不是自己想要的这也是调试接口时的第一步。2.3 拿到响应之后怎么读懂它一次请求完成后服务器会返回一个响应对象它身上挂着几个常用的属性基本覆盖了办公场景下90%的需求。属性作用典型使用场景status_codeHTTP状态码判断请求是否成功200代表正常text响应文本查看接口返回的原始内容json()解析JSON的字典绝大多数接口数据都是JSON格式content响应的二进制内容下载文件、图片时使用headers响应头信息获取文件类型、编码方式等信息encoding响应编码处理中文乱码时特别有用我平时最常用的判断逻辑是先看status_code如果不是200马上打印响应文本看具体报错如果是200就尝试用r.json()把数据解析成字典。但要注意r.json()只有在响应内容是合法JSON时才不会报错碰到接口返回了一堆HTML的情况再强行调用就会直接抛异常。很多人在这一步会犯的错误是刚学完get方法就急着写爬虫去抓别人网站的页面数据。这里我多说一句自动化办公的正当做法是处理自己有权访问的系统或者调用对方官方提供的开放接口千万别把requests用去做绕过权限或违反使用条款的事情。把握好这个边界技术用起来才踏实。3. 接口交互的核心流程从浏览器到requests代码3.1 先学会从开发者工具里抄接口很多系统根本没有现成的接口文档这时候最可靠的办法就是从浏览器开发者工具里把接口信息调试出来。操作流程很简单在浏览器里打开你要自动化的页面按下F12进入开发者工具。切换到Network标签页勾选Fetch/XHR类型。在页面上手动执行一次你要自动化的操作比如点一下查询按钮。在Network列表里找到那条对应的请求右键复制为cURL格式。把这个请求的关键信息整理成requests代码。这一步的核心是搞清楚三样东西请求地址是什么、请求方法是什么、请求参数和请求头是什么。我见过不少新手不看Network面板凭感觉猜参数名结果猜了一天都没对。其实接口地址和参数就明明白白躺在浏览器里你只要去抄作业就行。浏览器里复制出来的cURL命令比较长网上有现成的小工具能把它转成requests代码转换后再根据自己的需求精简。我最初也依赖过这类工具但后来建议还是手写几遍因为只有自己理解了每个参数的含义遇到接口变化时才懂得怎么调。3.2 POST请求从填表到提交数据办公自动化的另一半场景是提交数据比如提交审批、录入信息、发送内容这些动作在HTTP里对应的就是POST请求。requests的post方法和get差不多但多了一个参数选择的讲究# 方式一表单格式提交对应网页里普通的表单 r requests.post( http://192.168.1.10:8000/api/login, data{username: admin, password: 123456}, timeout5 ) # 方式二JSON格式提交对应前后端分离系统里最常见的格式 r requests.post( http://192.168.1.10:8000/api/report, json{start_date: 2025-01-01, end_date: 2025-01-31}, timeout5 )用data还是json主要看服务端接收什么格式。一般通过F12里看请求的Content-Type就知道如果是application/x-www-form-urlencoded就用data如果是application/json就传json参数。我踩过的坑是有些接口明明要JSON格式但用data传参后服务端读不到任何字段这时把data改成json就立刻通了。3.3 保持登录态session对象才是自动化的主角办公系统绝大多数需要登录如果你每次请求都要重新输账号密码那自动化就谈不上省心。requests神器之处在于提供session对象能够把cookie和登录状态保存下来后续所有请求都自动携带。session requests.Session() login_data {username: admin, password: 123456} # 登录接口 session.post(http://192.168.1.10:8000/api/login, datalogin_data) # 登录之后的接口请求不需要再手动管cookie r session.get(http://192.168.1.10:8000/api/report/list, timeout5) print(r.json())session的工作机制有点像浏览器保存了你的登录态你在这个session里发的每一个请求浏览器都会自动把属于这个域名的cookie带上。所以在自动化脚本里我强烈建议用session代替裸的requests.get否则只要遇到需要登录的接口你会被cookie问题折磨到怀疑人生。登录方式也有讲究。老系统通常是用账号密码加验证码新系统则可能用token。如果遇到验证码要么想办法接入打码平台要么锁定一个长期有效的token来使用。在我的办公自动化实践中很多内部系统都支持记住我或token认证能拿到token就尽量用token比每次都模拟登录流程要稳定得多。3.4 headers参数别让服务器一眼看穿你是脚本服务器能从请求头里分辨出你是真人还是代码最常见的识别标志就是User-Agent也就是浏览器版本信息。requests默认的UA是一串类似python-requests/2.31.0的字符串稍微正规一点的服务端都能识别出来。所以我会在请求里显式加上浏览器UA让脚本看起来更像正常访客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, Referer: http://192.168.1.10:8000/dashboard, } r session.get(http://192.168.1.10:8000/api/report/list, headersheaders, timeout5)这里也要提醒一句设置UA是为了让正常的办公脚本更稳定不是让你去绕过服务端的限制去抓不该抓的数据。合法合规的边界心里要有个数。4. 自动化办公实战三个可以直接抄的脚本4.1 批量查询物流把几十个单号丢进循环里之前有个做电商运营的朋友找我说每天要手动去查几十个快递单号的状态每个都要复制、粘贴、看结果一天下来少说半小时。我给他写了段requests脚本逻辑就三步准备单号列表循环调用物流查询接口把结果写入CSV。import time import csv import requests orders [SF1234567890, SF1234567891, SF1234567892] headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) } results [] for order_no in orders: resp requests.get( http://api.example.com/logistics/query, params{tracking_no: order_no}, headersheaders, timeout10 ) data resp.json() results.append([order_no, data.get(status, 未知), data.get(update_time, )]) time.sleep(0.5) with open(logistics_result.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([单号, 状态, 更新时间]) writer.writerows(results)这段代码里有两个细节值得说。一是time.sleep(0.5)这是故意放慢速度避免短时间密集请求把对方接口打爆也是尊重接口服务方的基本礼仪。二是写CSV时用了utf-8-sig编码如果直接写utf-8用Excel打开文件时中文很容易变成乱码这个坑我踩过好几次。真实环境里物流公司一般提供的是付费API或者需要你有合作商户号才能申请调用权限。处理公司自己的业务数据时先确认接口来源是否合法是入门自动化办公前就要建立的意识。4.2 用企业微信机器人每天自动推送日报定时推送日报是我自己每天都在用的一项自动化流程。每天早上脚本先把昨日数据统计出来然后通过企业微信群的机器人Webhook把报表内容推到群里全程不需要人动手。企业微信机器人Webhook的用法很简单就是往一个特定地址发送一段JSON消息import requests webhook_url https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key这里填你的key message_data { msgtype: text, text: { content: 日报昨日新增订单1234单销售额56789元。 } } resp requests.post(webhook_url, jsonmessage_data, timeout10) result resp.json() if result.get(errcode) 0: print(推送成功) else: print(推送失败:, result)这个场景最能体现requests和普通手动复制粘贴的差别只要脚本写好了它可以每天早上同一个时间把最新数据拉过来、组装成文案、发送出去一年365天不间断。定时部分可以用最原始的方式比如Windows的计划任务去执行Python脚本也可以直接在脚本里加个循环加sleep或者用schedule库来做。我更推荐用外部定时任务来触发脚本因为脚本崩溃了自己能重启日志排查也更方便。有两点需要特别留意Webhook地址相当于一个群聊的入口钥匙如果泄露到外网别人就可以往你的企业群里塞消息。所以包含Webhook地址的脚本千万不要随手传到公开的代码仓库里。另外所有消息内容在发送前要做合法性检查避免统计脚本出错时推送出去一条千疮百孔的日报。4.3 批量下载OA系统里的Excel报表再举一个更常见的场景登录后台系统筛选条件然后下载文件。以前手工操作时你要点开每一份报表、点下载、等浏览器下载、再重命名。用requests做的话核心思路是先保持登录态再直接请求下载接口最后把二进制内容写到本地文件。import requests session requests.Session() login_data {username: admin, password: 123456} session.post(http://oa.example.com/login, datalogin_data, timeout10) months [2025-01, 2025-02, 2025-03] for month in months: resp session.get( http://oa.example.com/report/download, params{month: month}, timeout30 ) filename f月度报表_{month}.xlsx with open(filename, wb) as f: f.write(resp.content) print(f{filename} 下载完成大小{len(resp.content)}字节)为什么这里用session而不是直接requests.get因为如果没有先登录session里就没有cookie下载接口大概率会返回一个跳转登录页的HTML。你下载下来的Excel打不开用文本编辑器打开一看全是登录页代码那时候就知道登录态没保持住的含义了。对于大文件下载把服务端整个文件都加载进内存再一次性写入不是好习惯。可以改成流式下载resp session.get(download_url, streamTrue, timeout60) with open(filename, wb) as f: for chunk in resp.iter_content(chunk_size8192): f.write(chunk)iter_content会按照你指定的块大小分批把内容写进文件内存占用小得多也不容易在下载一个大文件时把脚本拖死。我一般在处理超过200MB的文件时都会优先用这种流式写法。5. 常见问题与排查技巧实录5.1 脚本卡死不返回十有八九是没设timeout我发现新手写的requests脚本最常见的毛病就是所有请求都不带timeout参数。问题在于很多内部接口偶尔会假死既不应答也不报错如果你没设超时脚本就会一直等在那里前面消耗的时间和精力全部白费。timeout有两种解读既可以传一个数字表示整个请求的最大等待秒数也可以传一个元组分别设置连接服务器超时和读取数据超时。我更推荐用法是写连接超时和读取超时的组合resp requests.get(url, timeout(3.05, 10))3秒内连不上就直接放弃连接成功后10秒内没读到数据也放弃。这样脚本出了状况最多等十几秒而不是无限期卡住。所有生产环境的脚本都应该给每个请求都加上合理的timeout。5.2 接口返回403或418先检查User-Agent如果脚本访问某个接口返回403 Forbidden或者418 Im a teapot那很可能是服务端把你的请求识别成了非浏览器客户端。解决方式我在前面3.4节也讲过了给请求加上一个完整的浏览器UA大多数情况下就能解决。还有一类情况是服务端校验了Referer头你可以先在浏览器F12里看看正常请求的Referer是什么然后照着设置。注意请求头里的Referer只是告诉服务器我从哪个页面跳过来的这是正常的HTTP行为不属于什么隐蔽手段。5.3 接口返回的中文全是乱码出现乱码本质是编码方式不匹配。requests的r.text默认按响应头里的charset来解码如果服务端没在响应头里声明编码或者声明的编码和实际内容不一致中文就会变成一堆地乱码。我的排查步骤很简单先用r.encoding打印出当前Requests猜测用的编码再用r.apparent_encoding看看Requests基于内容本身分析出来的编码如果两者不一样就把r.encoding改成apparent_encoding再重新取一次r.textresp requests.get(url, timeout10) resp.encoding resp.apparent_encoding print(resp.text)这样做之后绝大多数乱码问题都能解决。如果是在写CSV或Excel还要注意保存文件时的编码这个我前面提过utf-8-sig比utf-8更适合给Excel用。5.4 公司内部系统的SSL证书报错访问自建的内部系统时经常会遇到一个奇怪的现象在浏览器里打开好好的requests一请求却抛SSLError。这是因为内网系统通常用的是自己签发的SSL证书浏览器默认信任了但requests出于安全考虑默认会严格校验证书。如果你确认这个系统是公司内部可信环境可以临时关闭证书校验并顺手关掉InsecureRequestWarning警告免得日志里刷屏import urllib3 import requests urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) resp requests.get(url, verifyFalse, timeout(5, 20))再说一次verifyFalse会让请求不再验证服务器证书的真实性存在被中间人攻击的风险所以只建议在公司内部可信网络里使用。如果是访问公网的服务还是应该尽量保持证书校验开启不要图省事全部关闭。5.5 其他三个高频率问题重定向、JSON解析失败、文件损坏先说重定向。有些接口在未登录时会把请求重定向到登录页但requests默认会自动跟随重定向所以你以为请求成功了实际拿到的是登录页内容。不想被带着走可以设置allow_redirectsFalse这样一旦遇到302、301就能立刻发现resp requests.get(url, allow_redirectsFalse, timeout10)再说JSON解析失败。r.json()抛出的JSONDecodeError通常意味着接口返回的不是JSON。我的排查习惯是打印resp.text的前200个字符看看返回内容到底是什么很多时候看一眼就知道是登录页、错误提示还是空字符串。最后是下载的文件打不开。这个我之前提过十有八九是你把页面内容当作了文件内容也就是登录态丢失。另外还有一种情况是服务端返回的其实是JSON格式的下载失败提示你把它保存成了.xlsx当然打不开。所以下载文件前最好检查一下响应头里的Content-Type确认是Excel、PDF之类的文件类型再写入。5.6 请求量大了循环再快也抵不过顺序等待如果自动化任务需要请求几百上千个接口用普通循环一个个发请求所有时间都会耗在等待网络上。requests本身是同步的一个请求不返回后面的就干等着。这时候我一般会引入线程池把请求并发出去from concurrent.futures import ThreadPoolExecutor urls [http://192.168.1.10:8000/api/data?id str(i) for i in range(100)] def fetch(url): return requests.get(url, timeout10).json() with ThreadPoolExecutor(max_workers10) as executor: results list(executor.map(fetch, urls))并发能显著提速但代价是会对目标服务造成更大的压力。我通常在批量任务里把并发数控制在5到10之间并且加上适当延时。说到底自动化的目的不是把别人服务器搞崩而是把自己的双手解放出来。6. 签字收工前我个人的几条使用习惯最后聊点代码之外的东西。我写requests脚本时间也不算短了像连接池、重试机制、日志记录这些话题展开能再写一篇长文但我最想强调的还是意识层面的几个习惯。第一任何接口请求在写进正式脚本前先把url、params、headers、请求体全部打印出来肉眼确认一遍。很多问题的根源就是你以为你发的是这个参数实际发出去的是另一个参数打印出来一目了然。第二把常用的请求封装成函数不要在每个脚本里都复制粘贴一大堆requests代码。我习惯为每个对接的系统单独建一个client.py文件里面用session统一管理登录态这样后续维护任何一个系统的脚本都很轻松。第三自动化脚本一定要有日志不管是打印到控制台还是写入文件至少要能回答它今天到底跑了没有、跑到哪一步挂了这两个问题。我经常看到有人囤了一堆自动化教程但在实际工作里依然天天手动下载报表。原因不是代码难而是总想等一个完美的方案再动手。其实requests这块你先从最简单的单个接口请求写起再迭代到批量、定时、推送每一个小目标都会实打实地帮你省下时间。等哪天真把工作流跑通的时候你会发现最有成就感的不是代码写了一千行而是你终于可以安心地去干那些机器替代不了的事了。

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

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

免费获取报价 →
↑