当前位置: 首页 > news >正文

Python新手也能跑的三个爬虫:查高校排名、扒编程题、批量存网页图

本文还有配套的精品资源,点击获取

简介:三个轻量级Python爬虫脚本,全部基于requests和BeautifulSoup4实现,不装浏览器、不配环境,Python 3.6+解压即用。大学排名.py直接解析网页HTML表格,实时打印国内主流高校排名结果,并附带运行效果截图‘大学排名运行结果.jpg’方便比对;下载题目.py专攻在线编程题库页面,自动提取题目标题和描述文本,整理成结构清晰的纯文本文件PATest.txt;下载图片.py遍历页面所有img标签,按出现顺序命名(1.jpg、2.jpg…),自动保存到本地‘下载的图片’文件夹。每个脚本都带逐行中文注释,关键步骤有说明,错误处理简单明确。资源包里包含完整可运行结构:源码文件、依赖声明requirements.txt、示例输出图、测试文本,以及预设的‘大学排名’‘下载题目’‘下载图片’等空目录,开箱就能调试验证功能是否正常。适合刚学完基础语法、想动手练爬虫的新手过渡到实战。

1. 这不是“教爬虫”,是给你递了一把能拧螺丝的扳手

你刚学完print("Hello World"),又啃完了for循环和字典嵌套,心里痒痒想干点“真事”——但一搜“Python爬虫教程”,满屏都是Selenium启动浏览器、ChromeDriver版本对不上、pip install报错二十行、User-Agent随机化还要配fake_useragent……最后关掉页面,默默打开《Python编程:从入门到实践》第12章,翻了三遍还是没敢运行那个带requests.get()的例子。

别急。这组脚本,就是专为这个“卡在入门最后一厘米”的你写的。

它不讲 HTTP 状态码原理,不展开robots.txt法律边界,不分析反爬策略演进史;它只做三件事:查高校排名、扒编程题、存网页图。每个功能都对应一个.py文件,每个文件都控制在 80 行以内,全部用requests发请求、BeautifulSoup4解析 HTML,零浏览器、零配置、零环境冲突。你解压后双击运行(或终端敲python 大学排名.py),3 秒内就能看到控制台刷出清华、北大、浙大的名字和分数——不是“理论上可以”,是此刻就能看见结果

关键词里写的“bs4实战”,不是指“用 BeautifulSoup 做个 demo”,而是指:你马上要亲手解析真实网页<table>标签里的<tr><td>嵌套结构,要手动定位<div class="problem-title">下的<h2>文本,要从<img src="...">里抠出带https:///static/img/的完整 URL。这些不是抽象概念,是你要一行行读、一行行改、一行行调试的真实 DOM 节点。资源包里那张大学排名运行结果.jpg,不是装饰,是你运行后第一眼该去比对的“答案页”;那个空着的下载的图片文件夹,不是占位符,是你五分钟后会看到1.jpg2.jpg3.jpg自动塞进去的实打实成果。

它适合谁?适合你电脑上刚装好 Python 3.8、还没碰过pip以外命令的新手;适合你被ImportError: No module named 'bs4'卡住半小时、最后靠室友远程投屏才解决的初学者;适合你只想“先跑通一个,再琢磨为什么”的实干派。这不是爬虫课的期末考卷,这是你工具箱里第一把能拧紧螺丝的扳手——它不炫技,但绝不滑丝。

2. 整体设计思路:为什么只用 requests + bs4?为什么三个脚本各自独立?

2.1 工具链极简主义:拒绝“为了爬而爬”的技术堆砌

新手最常踩的坑,不是写不出代码,而是选错了起点。很多教程一上来就推Scrapy框架,理由是“企业级”“高性能”;或者强推Selenium,理由是“能渲染 JS”。但现实是:你想查个软科中国大学排名,目标页面是纯静态 HTML 表格;你想下载 PAT(中国计算机学会编程能力测试)题库的题目描述,源码里<div class="problem-content">标签早已把文本明文写死;你想保存某技术博客的配图,所有<img>src属性都是绝对路径或相对路径,根本不需要执行 JS 动态加载。

这时候硬上Selenium,等于为了拧一颗 M3 螺丝,先买台 CNC 加工中心——不仅成本高(启动浏览器慢、内存占用大、安装依赖多),还徒增故障点(ChromeDriver 版本错配、无头模式黑屏、元素等待超时)。而requests + BeautifulSoup4组合,就像一把精钢镊子:轻、准、快。requests负责干净利落地拿到原始 HTML 字节流,bs4负责像翻书一样逐层展开 DOM 树。它不模拟人,只解析文;不追求“像人一样点”,只专注“把字儿揪出来”。

提示:本方案明确放弃lxml作为 bs4 解析器(尽管它更快),默认使用html.parser。因为lxml需额外pip install lxml,而html.parser是 Python 标准库内置,Python 3.6+ 开箱即用。牺牲一点解析速度(对百行 HTML 几乎无感),换来的是真正的“零配置”。

2.2 功能解耦:三个脚本 = 三个可验证的原子能力

新手学习最怕“一锅炖”——一个脚本里混着发请求、解析表格、存数据库、发邮件。一旦报错,你分不清是网络问题、解析逻辑错、还是路径写错了。所以这三个脚本,严格遵循“单一职责”:

  • 大学排名.py:只做一件事——从指定 URL 抓取 HTML → 定位<table>→ 提取<tr>行 → 读取<td>单元格文本 → 格式化打印到控制台。它不存文件、不画图、不联网查其他数据,输出就是屏幕上的文字列表。
  • 下载题目.py:只做一件事——抓取题库页面 HTML → 找到所有题目容器<div class="problem-item">→ 从中提取<h2>标题和<div class="description">描述 → 按序拼成纯文本块 → 写入PATest.txt。它不处理图片、不登录、不提交答案,输出就是一个.txt文件。
  • 下载图片.py:只做一件事——抓取任意网页 HTML → 遍历所有<img>标签 → 提取src属性值 → 判断是否为有效 URL(含http或以/开头)→ 拼接完整 URL(若为相对路径)→ 下载二进制内容 → 以1.jpg2.jpg命名保存到下载的图片/文件夹。它不识别图片内容、不压缩、不分类,输出就是一串有序编号的.jpg文件。

这种拆分,让调试变得极其简单:运行大学排名.py报错?一定是 HTML 结构变了或网络不通;下载题目.py生成的PATest.txt为空?一定是 CSS 选择器写错了或页面结构更新了;下载图片.py文件夹里只有1.jpg?大概率是前几张图片 URL 是data:image/png;base64,...这种内联 Base64,脚本已主动跳过(后面详解)。每个脚本都是一个独立的“能力单元”,你可以单独练熟一个,再碰下一个,毫无认知负担。

2.3 目录结构即教学逻辑:空文件夹不是摆设,是你的实验沙盒

资源包里的目录树,不是随意组织的,而是刻意设计的学习路径:

├── 大学排名/ # 专门存放大学排名相关文件(脚本、截图、未来可扩展的CSV) ├── 下载题目/ # 专门存放题目文本(PATest.txt)、题库页面HTML备份 ├── 下载图片/ # 专门存放下载的图片(1.jpg, 2.jpg...),脚本自动创建 ├── 下载的图片/ # 脚本实际保存图片的目标文件夹(注意中文名!) ├── 大学排名.py ├── 下载题目.py ├── 下载图片.py ├── requirements.txt └── 大学排名运行结果.jpg

关键细节在于:下载的图片/是脚本硬编码的保存路径(含中文),而下载图片/是你手动建的、用于存放PATest.txt的目录。这种命名差异,强迫你注意到“脚本里写的路径”和“你看到的文件夹名”必须一致——这是新手常犯的路径错误根源。当你第一次运行下载图片.py,它会自动创建下载的图片/文件夹(如果不存在),然后往里塞图。你不需要提前建,但必须理解:脚本的os.makedirs('下载的图片', exist_ok=True)这行代码,就是在为你铺路。同理,大学排名/下载题目/是预留的“升级接口”——等你熟悉了,可以把大学排名.py改成导出 CSV,把文件存进大学排名/;可以把下载题目.py加上自动备份原 HTML 的功能,存进下载题目/。目录结构本身,就是一张渐进式学习地图。

3. 核心细节解析与实操要点:逐行读懂,更要懂“为什么这么写”

3.1大学排名.py:如何从 HTML 表格里“挖”出有效数据?

我们以软科中国大学排名(假设 URL 为https://www.shanghairanking.cn/rankings/bcur/2023)为例。打开网页源码,你会看到核心数据藏在一个<table>里,结构类似:

<table class="rk-table"> <thead> <tr><th>排名</th><th>学校名称</th><th>总分</th></tr> </thead> <tbody> <tr><td>1</td><td>清华大学</td><td>952.3</td></tr> <tr><td>2</td><td>北京大学</td><td>937.1</td></tr> </tbody> </table>

大学排名.py的核心逻辑,就是精准定位这个<table>,然后一层层“剥洋葱”:

# 第一步:发请求,获取HTML response = requests.get(url, timeout=10) response.raise_for_status() # 关键!HTTP错误码直接抛异常,不静默失败 soup = BeautifulSoup(response.text, 'html.parser') # 第二步:找表格(这里用class定位,比直接找table更稳妥) table = soup.find('table', class_='rk-table') # 注意:class_ 下划线是bs4语法! if not table: print("⚠️ 未找到排名表格,请检查网页结构是否变化") exit(1) # 第三步:找所有数据行(跳过<thead>,只取<tbody>里的<tr>) rows = table.select('tbody tr') # select()用CSS选择器,比find_all('tr')更直观 # 第四步:遍历每一行,提取<td>文本 for i, row in enumerate(rows[:10], 1): # 只取前10名,避免刷屏 tds = row.find_all('td') if len(tds) >= 3: # 确保有足够列(排名、校名、分数) rank = tds[0].get_text(strip=True) # .get_text(strip=True) 去除换行和空格 name = tds[1].get_text(strip=True) score = tds[2].get_text(strip=True) print(f"{i:2d}. {name:<12} | 排名:{rank:>3} | 总分:{score}")

为什么这么写?经验之谈:

  • response.raise_for_status()不是可选项。新手常忽略 HTTP 错误(如 403 Forbidden、404 Not Found),脚本静默返回空soup,后续find()全是None,最后报AttributeError却找不到源头。加这一行,错误立刻暴露在请求环节。
  • class_='rk-table'中的下划线class_是 bs4 强制要求(因为class是 Python 关键字)。新手复制网上代码时若漏掉_,会直接语法报错。脚本里必须显式写出,形成肌肉记忆。
  • table.select('tbody tr')优于table.find_all('tr')。因为<thead>里的<tr>是表头,不是数据行。用 CSS 选择器tbody tr精准过滤,避免把“排名”“学校名称”当数据打印出来。
  • enumerate(rows[:10], 1)1是起始序号。控制台输出1.2.0.1.更符合人类阅读习惯,且[:10]限流防止长列表刷屏——这是对新手终端体验的尊重。
  • get_text(strip=True)strip=True至关重要。网页<td>里常有\n\t和空格,不清理会导致“ 清华大学 ”这种带空格的字符串,影响后续清洗或比较。

注意:脚本中预设的 URL 是一个稳定公开的测试页(非真实软科链接,避免法律风险)。实际使用时,你只需修改url = "你的目标URL"这一行。资源包里的大学排名运行结果.jpg,就是用这个预设 URL 运行后截的图,你运行后对比,一眼可知是否成功。

3.2下载题目.py:如何从复杂嵌套中“拎”出标题和描述?

以一个典型编程题页面为例,HTML 结构往往更深:

<div class="problem-list"> <div class="problem-item"># 找到所有题目容器 items = soup.select('div.problem-item') # 用CSS选择器一次抓全 if not items: print("⚠️ 未找到题目容器,请检查页面结构或URL") exit(1) # 遍历每个容器 for idx, item in enumerate(items, 1): # 从当前item里找标题(h2标签) title_tag = item.select_one('h2.problem-title') title = title_tag.get_text(strip=True) if title_tag else f"[无标题_{idx}]" # 从当前item里找描述(.problem-content下的所有<p>文本拼接) content_div = item.select_one('.problem-content') if content_div: # 获取所有<p>标签的文本,用两个换行分隔 paragraphs = [p.get_text(strip=True) for p in content_div.find_all('p')] description = "\n\n".join(paragraphs) else: description = "[无描述]" # 写入文件(追加模式,避免覆盖) with open('PATest.txt', 'a', encoding='utf-8') as f: f.write(f"=== 题目 {idx} ===\n") f.write(f"标题:{title}\n") f.write(f"描述:\n{description}\n\n")

为什么这样设计?避坑指南:

  • soup.select('div.problem-item')是核心。新手易犯错误是soup.find_all('div', class_='problem-item'),但若页面有多个不同 class 的 div,可能匹配不准。CSS 选择器div.problem-item更精确,且select()返回列表,天然支持遍历。
  • item.select_one('h2.problem-title')中的select_one()很关键。它确保每个题目只取第一个标题(避免重复),且返回None而非空列表,方便用if title_tag else判断。若用find_all(),需判断len()>0,代码冗长。
  • 描述部分用"\n\n".join(paragraphs)而非"".join(paragraphs)。因为<p>是段落标签,自然换行是语义的一部分。合并时保留段间距,生成的PATest.txt才可读。
  • with open(..., 'a')用追加模式('a')而非写入模式('w')。这是血泪教训:新手调试时反复运行脚本,若用'w',每次都会清空之前内容,最后只剩最后一个题。'a'保证每次运行都累加,方便验证。

提示:PATest.txt文件名中的PAT是“Programming Ability Test”缩写,非特指某平台。脚本不绑定任何具体网站,你只需把目标题库页面的 URL 填进去,修改 CSS 选择器(如把.problem-title换成.title-h2),就能复用。

3.3下载图片.py:如何安全地批量下载,避开“假链接”和“防盗链”?

网页图片的src属性五花八门:绝对 URL(https://example.com/1.jpg)、相对 URL(/images/logo.png)、协议相对(//cdn.example.com/icon.svg)、Base64 内联(data:image/png;base64,iVBOR...)、甚至 JavaScript 动态生成(src="javascript:void(0)")。下载图片.py的策略是:只下确定能用的,果断跳过可疑的

# 找所有img标签 img_tags = soup.find_all('img') if not img_tags: print("⚠️ 页面未找到任何<img>标签") exit(1) # 创建保存目录 os.makedirs('下载的图片', exist_ok=True) downloaded_count = 0 for idx, img in enumerate(img_tags, 1): src = img.get('src', '').strip() if not src: continue # 跳过src为空的img # 跳过data:image开头的Base64(无法直接下载) if src.startswith('data:image/'): continue # 构建完整URL if src.startswith(('http://', 'https://')): full_url = src elif src.startswith('//'): # 协议相对URL parsed = urlparse(url) full_url = f"{parsed.scheme}:{src}" else: # 相对路径,如 /images/1.jpg 或 images/2.png full_url = urljoin(url, src) # 尝试下载 try: img_response = requests.get(full_url, timeout=15) img_response.raise_for_status() # 猜测文件扩展名(从Content-Type或URL后缀) content_type = img_response.headers.get('content-type', '') if 'jpeg' in content_type or 'jpg' in content_type: ext = '.jpg' elif 'png' in content_type: ext = '.png' elif 'gif' in content_type: ext = '.gif' else: # 退而求其次,从URL后缀猜 ext = os.path.splitext(src)[1].lower() or '.jpg' # 保存文件 filename = f"下载的图片/{idx}{ext}" with open(filename, 'wb') as f: f.write(img_response.content) downloaded_count += 1 print(f"✅ 已下载:{filename} ({len(img_response.content)//1024} KB)") except Exception as e: print(f"❌ 下载失败 {full_url}:{type(e).__name__}") print(f"\n🎉 总计成功下载 {downloaded_count} 张图片")

为什么这样处理?实战心得:

  • 坚决跳过data:image/:这是新手最容易卡住的地方。看到<img src="data:image/png;base64,...">,本能想“这是图片啊,得下!”,但 Base64 是编码后的字符串,不是 URL。requests.get()对它会直接报错。脚本主动continue,避免中断。
  • urljoin()是相对路径救星requests不会自动补全相对路径。urljoin('https://a.com/page/', '/img/1.jpg')返回'https://a.com/img/1.jpg',而urljoin('https://a.com/page/', 'img/2.png')返回'https://a.com/page/img/2.png'。不用自己拼字符串,安全可靠。
  • 扩展名智能猜测:不硬编码.jpg。先看响应头Content-Type(服务器告诉你是啥),再 fallback 到 URL 后缀。这样https://cdn.com/logo(无后缀)也能根据image/svg+xml正确存为.svg
  • timeout=15try/except包裹下载:图片服务器响应慢或临时不可达很常见。设超时避免卡死,except Exception捕获所有网络异常(ConnectionError,Timeout,InvalidURL),单个失败不影响整体流程。打印具体错误类型(type(e).__name__),比except:更利于排查。
  • 文件名用idx而非src:避免src="/images/user%20avatar.jpg"这种含空格、特殊字符的 URL 导致保存失败。统一用1.jpg2.jpg,简洁可控。

注意:脚本默认不处理防盗链(Referer)。真实场景中,有些网站会检查Referer头,拒绝非本站来源的请求。本脚本暂不加入headers={'Referer': url},因为:1)多数教育类、文档类网站无此限制;2)加了反而可能触发其他反爬;3)新手应先掌握基础流程,防盗链属于进阶技巧。若你遇到大量403,再针对性添加 Referer 即可。

4. 实操过程与核心环节实现:从解压到结果,每一步都可验证

4.1 环境准备:真的只需要三步

别被“Python环境”吓住。只要你电脑上装了 Python(确认方法:终端输入python --versionpython3 --version,显示3.6+即可),接下来就是三步:

第一步:解压资源包
- 下载 ZIP 包,右键“解压到当前文件夹”(Windows)或双击(macOS)。
- 解压后,你会看到大学排名.py等文件平铺在文件夹里,以及下载的图片/这个空文件夹。

第二步:安装依赖(仅一次)
- 打开终端(Windows:CMD 或 PowerShell;macOS/Linux:Terminal)。
-cd进入解压后的文件夹(例如cd Downloads/Python爬虫新手包)。
- 运行:
bash pip install -r requirements.txt
requirements.txt内容极简:
requests==2.31.0 beautifulsoup4==4.12.2
这会安装指定版本的requestsbs4。版本锁定是为了避免新版本引入不兼容变更(比如 bs4 4.13 某些方法行为微调)。如果你已装过,pip会提示“已满足要求”,直接跳过。

第三步:运行任一脚本
- 在同一终端窗口,运行:
bash python 大学排名.py
- 你会看到控制台快速刷出类似:
1. 清华大学 | 排名:1 | 总分:952.3 2. 北京大学 | 排名:2 | 总分:937.1 3. 浙江大学 | 排名:3 | 总分:925.8 ...
- 同时,对比资源包里的大学排名运行结果.jpg,内容应完全一致。这就是你的第一个“成功信号”。

提示:若报错ModuleNotFoundError: No module named 'requests',说明pip install没成功。请检查是否在正确目录下运行,或尝试python -m pip install requests beautifulsoup4(强制用当前 Python 的 pip)。

4.2 修改目标 URL:把脚本变成你的工具

三个脚本的 URL 都写在文件顶部,形如:

# 大学排名.py 第5行 url = "https://example.com/rankings.html" # ← 修改这里! # 下载题目.py 第6行 url = "https://example.com/problem-set" # ← 修改这里! # 下载图片.py 第7行 url = "https://example.com/blog-post" # ← 修改这里!

如何找真实 URL?手把手教你:

  1. 打开目标网页(如你想扒的编程题库页面)。
  2. 右键 → “查看网页源代码”(Chrome/Firefox)。
  3. Ctrl+F(Windows)或Cmd+F(macOS),搜索<table>(查排名)、<div class="problem(扒题目)、<img(存图片)
  4. 确认源码里确实有你要的数据(不是 JS 渲染出来的)。
  5. 复制浏览器地址栏的完整 URL,粘贴替换脚本里的url = "..."

关键验证点:
- 查排名:源码里必须有<table>标签,且包含<tr><td>
- 抓题目:源码里必须有<div class="xxx">包裹<h2><p>
- 存图片:源码里<img>src必须是真实路径(不是src="javascript:void(0)")。

如果源码里找不到数据,说明页面是 JS 渲染的(如 React/Vue 应用),此时requests无法获取,需要Selenium——但这已超出本套件范围。本套件只服务“静态 HTML”场景,明确边界,不画大饼。

4.3 调试技巧:当脚本没按预期工作时,怎么快速定位?

新手调试的黄金法则:把“黑盒”变“透明盒”。不要猜,要亲眼看见中间结果。

技巧一:打印原始 HTML 片段
大学排名.pysoup = BeautifulSoup(...)后,加一行:

print("前500字符HTML:", response.text[:500])

运行后,你会看到真实的 HTML 开头。如果连<table>都没有,说明请求没拿到正确页面(可能是重定向、404、或网站反爬返回了错误页)。

技巧二:打印解析结果
table = soup.find(...)后,加:

print("找到的table:", table is not None) if table: print("table前100字符:", str(table)[:100])

如果table is not NoneFalse,说明find()失败,CSS 选择器写错了,回去检查网页源码的 class 名。

技巧三:用soup.prettify()看结构
在解析后,加:

with open('debug.html', 'w', encoding='utf-8') as f: f.write(soup.prettify())

运行后,会生成debug.html文件。用浏览器打开它,就能像看正常网页一样,高亮查看<table>在哪、<div class="problem-item">是否存在、<img>src是什么——这是最直观的 DOM 检查方式。

技巧四:逐行注释法
如果某段逻辑报错,把for循环里的内容注释掉,只留print(idx),确认循环能跑;再放开一行,加print(tds),确认find_all('td')有结果……像搭积木一样,一层层验证。

实操心得:我第一次用这套脚本扒某高校官网时,大学排名.py一直打印“未找到表格”。用prettify()生成debug.html打开一看,原来官网把排名放在<div id="ranking-list">里,用<ul><li>列表展示,不是<table>!我立刻把soup.find('table', class_='...')改成soup.select('#ranking-list li'),再调整get_text()逻辑,5 分钟搞定。调试不是玄学,是“看见”。

4.4 运行效果与输出物详解

每个脚本的输出,都是可立即验证的实体:

脚本输出位置输出内容如何验证
大学排名.py控制台(Terminal)格式化文本列表,含排名、校名、分数对照大学排名运行结果.jpg,逐行比对
下载题目.py当前目录PATest.txt纯文本文件,含=== 题目 1 ===标题:...描述:...用记事本/VS Code 打开,检查是否有乱码(应为 UTF-8)、段落是否清晰
下载图片.py当前目录下载的图片/文件夹1.jpg,2.jpg,3.jpg打开文件夹,双击任意一张图,确认能正常显示

特别注意下载的图片/文件夹:
- 它是脚本自动创建的,无需你手动建。
- 文件名是纯数字1.jpg,不包含原始 URL 中的复杂路径(如user-avatar-2023-v2.jpg),避免中文、空格、特殊字符导致保存失败。
- 图片大小在控制台有显示(如124 KB),帮你快速识别是否下载了空文件(0 KB)或小图标(<1 KB)。

5. 常见问题与排查技巧实录:那些我没写在注释里的坑

5.1 常见问题速查表

问题现象可能原因排查步骤解决方案
大学排名.py运行后只打印“未找到排名表格”1. 目标网页结构已变(class名改了)
2. URL 错误(404)
3. 网站反爬返回了非HTML内容
1. 用浏览器打开 URL,右键“查看源代码”,搜<table>
2. 在脚本里加print(response.status_code)
3. 加print(response.text[:200])看返回内容
1. 更新soup.find('table', class_='新class名')
2. 检查 URL 拼写
3. 若返回的是登录页 HTML,说明需登录,本脚本不支持
下载题目.py生成的PATest.txt是空的1. CSS 选择器不匹配(.problem-item写错)
2. 页面实际用<article>而非<div>
1. 用soup.select('div.problem-item')后加print(len(items))
2. 用soup.find_all(['div', 'article'], class_=...)宽泛匹配
1. 在浏览器源码中精确复制 class 名(注意空格、连字符)
2. 用soup.select('article.problem-item')尝试
下载图片.py下载的图片打不开/是空白1. 图片 URL 是data:image/(已被跳过)
2. 服务器返回了 403(防盗链)
3. 文件扩展名猜错了(如.jpg实际是.png
1. 查看控制台是否打印“跳过 data:image”
2. 检查下载失败日志是否含403
3. 用file 1.jpg(macOS/Linux)或属性查看(Windows)确认真实格式
1. 本脚本设计如此,无需处理
2. 在requests.get()中添加headers={'Referer': url}
3. 手动重命名文件(如1.jpg1.png
运行时报UnicodeEncodeError: 'gbk' codec can't encode character(Windows)Windows 默认终端编码是 GBK,但网页是 UTF-8在脚本开头加:
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
已在资源包脚本中内置此修复(针对 Windows 用户)
pip install报错PermissionError权限不足(尤其 macOS/Linux)运行pip install --user -r requirements.txt--user参数将包安装到用户目录,无需 sudo

5.2 独家避坑技巧:来自真实踩坑现场

技巧一:“先看后爬”原则
永远先手动打开目标 URL,右键“查看网页源代码”,搜索你要的数据关键词(如“清华大学”、“A+B Format”、“<img”)。如果源码里没有,requests就不可能拿到。这是 90% 失败的根源。不要幻想“代码能变魔术”。

技巧二:timeout参数不是摆设
我曾因没设timeout,脚本卡在某个失效的图片 URL 上长达 2 分钟。后来所有requests.get()都加上timeout=10(DNS 解析+连接+读取总时长),并配合try/except,让失败变“可预期”。

技巧三:os.makedirs(..., exist_ok=True)是你的朋友
新手常因忘记建下载的图片/文件夹而报错FileNotFoundErrorexist_ok=Truemakedirs在文件夹存在时不报错,不存在时自动创建——一行代码,省去所有路径焦虑。

技巧四:用print()替代“我以为”
不要想当然认为soup.find('table')一定有结果。在关键节点后加print(f"找到 {len(rows)} 行"),让程序替你说话。调试的本质,是让隐藏状态显性化。

技巧五:版本锁定requirements.txt
requests2.32 版本移除了某些旧参数,若你用新版本运行老脚本,可能报错。资源包里的requirements.txt锁定已验证版本,确保“解压即用”。升级前,务必本地测试。

5.3 进阶扩展建议:当你跑通第一个脚本后

这套脚本是起点,不是终点。跑通后,你可以轻松升级:

  • 导出 Excel:在大学排名.py末尾,用pandas.DataFrame(data).to_excel('rankings.xlsx')替代print()
  • 自动重试:给requests.get()for i in range(3): try: ... break except: time.sleep(1),应对偶发网络抖动。
  • 并发下载图片:用concurrent.futures.ThreadPoolExecutor并行下载,速度提升 3-5 倍(需加锁写文件)。
  • GUI 界面:用tkinter包一层,让用户点按钮选 URL、点按钮运行,告别终端。

但请记住:先让一把扳手拧紧一颗螺丝,再考虑买电钻。这三个脚本的价值,不在于它们多强大,而在于它们足够小、足够确定、足够让你在 5 分钟内获得正向反馈。这种“我能行”的感觉,比任何理论都珍贵。

6. 最后分享一个小技巧:如何用这组脚本,悄悄提升你的工程素养

很多人学爬虫,只盯着“数据怎么拿”,却忽略了更重要的东西:可维护性、可读性、可协作性。而这组脚本,其实在无声地示范这些。

你看大学排名.py的注释,不是写“发送HTTP请求”,而是写“# 用requests获取网页HTML,设置10秒超时防卡死”;下载图片.pyurljoin()的调用,旁边注释是“# 用urljoin安全拼接相对路径,避免手动字符串拼接出错”。这些注释,不是解释 Python 语法,而是在传递一种工程师思维:每一个函数调用,都要清楚它的目的、它的风险、它的替代方案为何不选。

再看目录结构:下载的图片/是脚本硬编码的路径,下载图片/是你手动管理的目录。这种“代码路径”和“人工路径”的分离,其实在教你环境隔离——脚本只负责生成,你负责归档和备份。未来你把它集成到更大项目里,下载的图片/可以指向云存储桶,而下载图片/仍是你本地的整理区。

还有requirements.txt。它不只是一行pip install命令,它是这个项目的“DNA 身份证”。三年后你重装系统,只要pip install -r requirements.txt,就能还原出今天一模一样的运行环境。这叫可重现性,是专业开发的基石。

所以,当你运行python 下载图片.py,看到1.jpg落进文件夹时,你收获的不仅是图片,更是对“确定性”的掌控感。这种感觉,会从爬虫延伸到你写的每一个脚本、每一个函数、每一个项目。它不声不响,但足够扎实。

现在,去解压那个 ZIP 包吧。打开终端,敲下python 大学排名.py。三秒后,清华、北大、浙大的名字会出现在你眼前——不是幻觉,不是教程里的假设,是此刻,你亲手启动的、真实世界的数据流。

本文还有配套的精品资源,点击获取

简介:三个轻量级Python爬虫脚本,全部基于requests和BeautifulSoup4实现,不装浏览器、不配环境,Python 3.6+解压即用。大学排名.py直接解析网页HTML表格,实时打印国内主流高校排名结果,并附带运行效果截图‘大学排名运行结果.jpg’方便比对;下载题目.py专攻在线编程题库页面,自动提取题目标题和描述文本,整理成结构清晰的纯文本文件PATest.txt;下载图片.py遍历页面所有img标签,按出现顺序命名(1.jpg、2.jpg…),自动保存到本地‘下载的图片’文件夹。每个脚本都带逐行中文注释,关键步骤有说明,错误处理简单明确。资源包里包含完整可运行结构:源码文件、依赖声明requirements.txt、示例输出图、测试文本,以及预设的‘大学排名’‘下载题目’‘下载图片’等空目录,开箱就能调试验证功能是否正常。适合刚学完基础语法、想动手练爬虫的新手过渡到实战。


本文还有配套的精品资源,点击获取

http://www.gsyq.cn/news/1510620.html

相关文章:

  • SDU软件学院创新实训(六)
  • 延安市手表回收包包回收哪家店更好,2026甄选以下5家店铺排名前5 - 谊识预商务
  • 第7章:Retriever 检索器——从相似度搜索到精准召回
  • 2026江苏商户及市民高频选择的 5 家食品检测第三方机构实地测评整理 - 科信检测
  • VMware Workstation Pro 17免费激活终极指南:5000+密钥库的完整解决方案
  • 2026茂名市家里卫生间漏水、阳台漏水、楼顶漏水、阳台漏水、地下室渗水、阳光房漏水各种房屋漏水情况不用愁!本地防水补漏公司为您排忧解难!质保可查、售后无忧。 - 企业资讯
  • Motrix下载管理器:如何通过3个关键配置让下载速度翻倍
  • Barlow字体:54种样式如何解决现代设计的三大核心问题?
  • AI开发者管控实战:认知沙盒与意图锚点设计
  • 京东E卡绑定,京东滑块t30,京东滑块,京东验证码
  • DS4Windows:让PS5手柄在PC上重获新生的终极解决方案
  • 深入解析Kinetis K20 MCU:从Cortex-M4内核到外设选型实战指南
  • 高考残疾考生有特殊的作答方式,系统怎么处理他们的答案
  • 2026白银企业高频选择的 5 家高分子检测第三方机构实地测评整理 - 鉴安检测
  • MPC8540 PowerQUICC III:DMA、PCI与RapidIO协同设计解析
  • 2026宝鸡本地人认可的 5 家户外广告设施检测机构实地测评汇总+市民高频选择 - 中安检测集团
  • 多维聚合与数据操作:从SQL GROUP BY到空间智能计算
  • 成都市手表回收包包回收哪家店更好,2026甄选以下5家店铺排名前5 - 谊识预商务
  • NXP S32G GoldBox车载网关开发实战:从硬件解析到软件部署
  • 第8章:QueryEngine 查询引擎——把检索结果变成答案
  • 如何用3个步骤让Figma界面瞬间变中文?FigmaCN插件深度解析
  • 2026百色商户及市民高频选择的 5 家食品检测第三方机构实地测评整理 - 科信检测
  • 终极指南:如何一键备份你的QQ空间青春回忆
  • Manim数学动画引擎:5分钟学会制作专业级数学可视化视频
  • 办公被频繁弹窗打扰?教你关掉 Office 自动弹出的 AI 助手
  • Android Studio中文语言包终极指南:3步告别英文界面,提升开发效率30%
  • 富士Micrex-F系列PLC编程软件PC Programmer安装包(含中英文双语支持)
  • 革命性英雄联盟智能助手Seraphine:一站式战绩分析与BP优化解决方案
  • LinkSwift:九大网盘直链下载助手的终极使用指南
  • 第十四章 异常