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

Python Requests 爬虫案例

Python Requests 爬虫案例

  1. 爬取小说网站
  2. 分页爬取小说网站
  3. 豆瓣电影评论
  4. 下载婚纱图片
  5. 百度图片

案例1 爬取小说网站

步骤:

  1. 爬取网页,保存html文件到本地 crawl_html.py
  2. 解析本地html文件内容,保存解析内容到本地文本文件 parse_html
#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
crawl_html.py
抓取笔趣阁小说《诡秘之主》第一章,保存为本地 txt
"""import requests
from pathlib import Path# 1. 目标页面
# url = "https://www.xbiquge.la/10/10489/2946624.html"
url = "https://www.1b0112db.xyz/book/64813/1.html"# 2. 浏览器 UA,防最简单反爬
headers = {"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ""AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/114.0 Safari/537.36")
}# 3. 发送 GET 请求
resp = requests.get(url, headers=headers, timeout=10)
# 4. 网络异常统一处理
resp.raise_for_status()  # 若状态码不是 200,直接抛异常
resp.encoding = resp.apparent_encoding  # 自动推断网页编码(防止乱码)# 5. 保存原始 html(调试友好)
Path("debug.html").write_text(resp.text, encoding="utf-8")# 6. 打印前 300 字符观察
print(resp.text[:300])
#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
parse_html.py
抓取笔趣阁小说《诡秘之主》第一章,保存为本地 txt
"""
from bs4 import BeautifulSoup
from pathlib import Path# 1. 读取上节课保存的 html
html = Path("debug.html").read_text(encoding="utf-8")# 2. 创建 soup 对象;lxml 解析器速度快 uv add lxml
soup = BeautifulSoup(html, "lxml")
# Python 内置的 html.parser(无需额外安装)
# soup = BeautifulSoup(html, "html.parser")# 3. 找标题(h1 标签)
title = soup.find("h1").get_text(strip=True)
print("章节标题:", title)# 4. 找正文 div(class='content' 为假设)
content_div = soup.find("div", id="chaptercontent")
# paragraphs = [p.get_text(strip=True) for p in content_div.find_all("p")]
paragraphs = [p.get_text(strip=True) for p in content_div]
paragraphs = {item for item in paragraphs if item != ""}# 5. 合并段落并写文件
Path(f"{title}.txt").write_text("\n".join(paragraphs), encoding="utf-8")
print("保存完成,共", len(paragraphs), "段")

运行顺序:

python crawl_html.py
python parse_html.py

案例2 分页爬取小说网站

分页爬取小说网站某部小说,每个网页为该小说的一个章节。

分页爬取网页即可得到该小说的全部章节。

解析每个页面,把小说内容保存到本地文本文件中

#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
crawl_paging.py
抓取笔趣阁小说《诡秘之主》第一章,保存为本地 txt
"""
import randomimport requests
from pathlib import Pathfrom bs4 import BeautifulSoup
from trio import sleep# 目标页面
base_url = "https://www.90feaa.cfd/"
url = base_url + "/book/64813/1.html"# 浏览器 UA,防最简单反爬
headers = {"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ""AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/139.0.0.0 Safari/537.36")
}def crawl_html(url):# 发送 GET 请求resp = requests.get(url, headers=headers, timeout=10)# 网络异常统一处理resp.raise_for_status()  # 若状态码不是 200,直接抛异常resp.encoding = resp.apparent_encoding  # 自动推断网页编码(防止乱码)# 返回网页文本return resp.textdef parse_page(html):# 创建 soup 对象;lxml 解析器速度快 uv add lxmlsoup = BeautifulSoup(html, "lxml")# 找标题(h1 标签)title = soup.find("h1").get_text(strip=True)print("章节标题:", title)# 找正文 div(class='content' 为假设)content_div = soup.find("div", id="chaptercontent")paragraphs = [p.get_text(strip=True) for p in content_div]paragraphs = {item for item in paragraphs if item != ""}# 合并段落并写文件Path(f"{title}.txt").write_text("\n".join(paragraphs), encoding="utf-8")print("保存完成,共", len(paragraphs), "段")# 判断有没有下一页 如果有下一页 继续读取pb_next = soup.find("a", id="pb_next")if pb_next:href_url = pb_next['href']new_html = crawl_html(base_url + href_url)parse_page(new_html)if __name__ == '__main__':html = crawl_html(url)parse_page(html)

案例3 豆瓣电影评论

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
douban.py
爬取豆瓣电影 Top250 并存 CSV
"""import csv
import time
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm  # 进度条# 1. 基础配置
BASE_URL = "https://movie.douban.com/top250"
HEADERS = {"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ""AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/139.0.0.0 Safari/537.36")
}
PAGE_SIZE = 25  # 每页 25 条记录
MAX_PAGE = 10  # 共 250 条def fetch_one_page(start):"""start: 本页起始索引(0,25,50...)返回 BeautifulSoup 对象"""params = {"start": start}resp = requests.get(BASE_URL, headers=HEADERS, params=params, timeout=10)resp.raise_for_status()resp.encoding = "utf-8"return BeautifulSoup(resp.text, "lxml")def parse_one_page(soup):"""解析单页,返回 list[dict]"""items = soup.select("div.item")  # 25 个 itemdata = []for item in items:title = item.select_one("span.title").get_text(strip=True)rating = item.select_one("span.rating_num").get_text(strip=True)quote_tag = item.select_one("p.quote")quote = quote_tag.get_text(strip=True) if quote_tag else ""data.append({"title": title, "rating": rating, "quote": quote})return datadef main():all_rows = []# 2. 循环 10 页for idx in tqdm(range(MAX_PAGE), desc="抓取进度"):soup = fetch_one_page(idx * PAGE_SIZE)all_rows.extend(parse_one_page(soup))# 3. 礼貌延时time.sleep(1.5)# 4. 写 CSVwith open("douban_top250.csv", "w", encoding="utf-8-sig", newline="") as f:writer = csv.DictWriter(f, fieldnames=["title", "rating", "quote"])writer.writeheader()writer.writerows(all_rows)print("已保存 douban_top250.csv,共", len(all_rows), "条")if __name__ == "__main__":main()

案例4 下载婚纱图片

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
wedding.py
爬取堆糖网 婚礼分类 婚纱照片 并下载
"""
# 导入必要库
import os  # 用于文件路径操作
import requests  # 用于发送网络请求
from bs4 import BeautifulSoup# 保存图片的文件夹名称
SAVE_DIR = "婚纱""""创建保存图片的文件夹,若已存在则不操作"""
if not os.path.exists(SAVE_DIR):os.makedirs(SAVE_DIR)print(f"创建图片保存文件夹: {SAVE_DIR}")
else:print(f"图片保存文件夹已存在: {SAVE_DIR}")
# 请求地址
url = 'https://www.duitang.com/category/'# 请求头
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
}
# 表单数据
form_data = {'cat': 'wedding'
}print('正在爬取,请稍等...')
# 发送请求 获取服务器响应
# 请求方式:GET POST PUT PATCH DELETE OPTION
response = requests.get(url=url, headers=headers, params=form_data)# 输出HTTP状态码
print(response.status_code)
# 输出服务器响应字符串
# print(response.text)
html = response.text
print('页面获取完成,正在解析...')
# 创建解析器
soup = BeautifulSoup(html, 'html.parser')
# 元素查找
# 获取页面中所有的img标签
imgs = soup.find_all('img')
print('解析完成正在下载...')
count = 0
for img in imgs:# print(img)print(img.get('src'))img_file = requests.get(img.get('src'))count += 1file_name = '图片' + str(count) + '.png'with open(file=f'{SAVE_DIR}/{file_name}', mode='wb') as f:f.write(img_file.content)

案例5 百度图片

  1. 向百度图片 API 接口请求想要的图片类型
  2. 解析返回的json数据,解析出图片下载地址
  3. 下载图片
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
baidu_images.py
1. 向百度图片 API 接口请求想要的图片类型
2. 解析返回的json数据,解析出图片下载地址
3. 下载图片
"""# 导入必要库
import requests  # 用于发送网络请求
import os  # 用于文件路径操作
import time  # 用于设置请求间隔,避免过快请求
import json  # 用于解析API返回的JSON数据
from urllib.parse import quote  # 用于URL编码# -------------------------- 配置参数 --------------------------
# 搜索关键词(已URL编码)
# KEYWORD = quote("古风美女")  # 将"古风美女"转为URL编码格式
# print(KEYWORD)
KEYWORD = "古风美女"  # 搜索关键字
# 保存图片的文件夹名称
SAVE_DIR = "ancient_beauty_images"
# 爬取页数(每页约30张图)
MAX_PAGE = 20
# 请求头(模拟浏览器行为,避免被识别为爬虫)
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36","Referer": "https://image.baidu.com/",  # 模拟从百度图片页面跳转"Connection": "keep-alive"
}
# 百度图片API接口(通过分析网络请求获取)
API_URL = "https://image.baidu.com/search/acjson"# -------------------------- 工具函数 --------------------------
def create_save_dir():"""创建保存图片的文件夹,若已存在则不操作"""if not os.path.exists(SAVE_DIR):os.makedirs(SAVE_DIR)print(f"创建图片保存文件夹: {SAVE_DIR}")else:print(f"图片保存文件夹已存在: {SAVE_DIR}")def download_image(img_url, save_path):"""下载单张图片并保存到本地:param img_url: 图片的URL:param save_path: 本地保存路径:return: 下载成功返回True,失败返回False"""try:# 发送请求获取图片数据(设置超时时间10秒)response = requests.get(url=img_url,headers=HEADERS,timeout=10,stream=True  # 流式下载,适合大文件)# 检查请求是否成功(状态码200表示成功)if response.status_code == 200:# 写入图片文件(二进制模式)with open(save_path, "wb") as f:for chunk in response.iter_content(chunk_size=1024):  # 分块写入if chunk:f.write(chunk)print(f"下载成功: {save_path}")return Trueelse:print(f"下载失败(状态码异常): {img_url},状态码: {response.status_code}")return Falseexcept Exception as e:print(f"下载失败(发生错误): {img_url},错误: {str(e)}")return False# -------------------------- 主爬取逻辑 --------------------------
def crawl_images():"""爬取百度图片API并下载图片"""create_save_dir()  # 确保保存文件夹存在# 循环爬取多页for page in range(MAX_PAGE):print(f"\n开始爬取第 {page + 1} 页...")# 构造API请求参数(pn为起始位置,每页30张图)params = {"tn": "resultjson_com",  # 固定参数,标识返回JSON格式"logid": "1193833708646682469",  # 日志ID(可从浏览器请求中复制)"ipn": "rj",  # 固定参数"ct": "201326592",  # 固定参数"is": "",  # 预留参数"fp": "result",  # 固定参数"queryWord": KEYWORD,  # 搜索关键词(URL编码后)"cl": "2",  # 固定参数"lm": "-1",  # 固定参数"ie": "utf-8",  # 编码格式"oe": "utf-8",  # 编码格式"adpicid": "",  # 预留参数"st": "-1",  # 固定参数"z": "",  # 预留参数"ic": "0",  # 固定参数"hd": "",  # 预留参数"latest": "",  # 预留参数"copyright": "",  # 预留参数"word": KEYWORD,  # 搜索关键词(URL编码后)"s": "",  # 预留参数"se": "",  # 预留参数"tab": "",  # 预留参数"width": "",  # 预留参数"height": "",  # 预留参数"face": "0",  # 预留参数(是否人脸)"istype": "2",  # 固定参数"qc": "",  # 预留参数"nc": "1",  # 固定参数"fr": "",  # 预留参数"expermode": "",  # 预留参数"force": "",  # 预留参数"pn": page * 30,  # 起始位置(每页30张,第n页从n*30开始)"rn": "30",  # 每页返回数量"gsm": hex(page * 30)[2:],  # 十六进制起始位置(去掉0x前缀)"1690083455624": ""  # 时间戳参数(可从浏览器请求中复制)}try:# 发送请求获取图片列表数据response = requests.get(url=API_URL,headers=HEADERS,params=params,timeout=15)# 解析JSON数据(注意:百度API返回的JSON可能包含多余字符,需处理)# 去除JSON前可能的干扰字符(如")]}'")json_data = response.text.lstrip(")]}'")data = json.loads(json_data)# data = response.json()# 提取图片URL列表(循环处理每张图)for i, img_info in enumerate(data.get("data", [])):# 过滤无效数据(无图片URL的条目)if not img_info.get("middleURL"):continue# 获取图片URL(middleURL为中等尺寸图片,可替换为hoverURL/objURL等)img_url = img_info["middleURL"]# 生成保存文件名(页面_序号.jpg)img_name = f"page_{page + 1}_img_{i + 1}.jpg"save_path = os.path.join(SAVE_DIR, img_name)# 下载图片download_image(img_url, save_path)# 每下载一张图,暂停0.5秒,避免请求过于频繁time.sleep(0.5)# 每页爬取完成后,暂停2秒再爬取下一页time.sleep(2)except Exception as e:print(f"第 {page + 1} 页爬取失败,错误: {str(e)}")continue  # 继续爬取下一页# -------------------------- 程序入口 --------------------------
if __name__ == "__main__":print("开始爬取百度图片-古风美女...")crawl_images()print("\n爬取结束!图片已保存至:", os.path.abspath(SAVE_DIR))
http://www.xdnf.cn/news/19167.html

相关文章:

  • 面试问题详解十二:Qt 多线程同步:QMutex讲解
  • SystemVerilog学习【七】包(Package)详解
  • FFmpeg音视频处理解决方案
  • 【GaussDB】在逻辑复制中剔除指定用户的事务
  • 【C++】C++ const成员函数与取地址操作符重载
  • 【Leetcode hot 100】21.合并两个有序链表
  • Flutter MVVM+provider的基本示例
  • ceph配置集群
  • VGG改进(6):基于PyTorch的VGG16-SE网络实战
  • “我店模式“当下观察:三方逻辑未变,三大升级重构竞争力
  • 详解常见的多模态大模型指令集构建
  • vue表格底部添加合计栏,且能跟主表同时滑动
  • 「鸿蒙系统的编程基础」——探索鸿蒙开发
  • 机器视觉学习-day12-图像梯度处理及图像边缘检测
  • REST API 是无状态的吗,如何保障 API 的安全调用?
  • 中科院人机交互科研分享-田丰
  • OpenCV 轮廓分析实战:从检测到形状匹配的完整指南
  • 【后端】云服务器用nginx配置域名访问前后端分离项目
  • SpringBoot防止重复提交(2)
  • docker 部署Skywalking
  • 干掉抽取壳!FART 自动化脱壳框架与 Execute 脱壳点解析
  • OpenCV DNN 模块完全指南:从理论基础到实战应用 —— 图像分类与目标检测的深度学习实现(含 Python/C++ 代码与性能分析)
  • 一站式可视化运维:解锁时序数据库 TDengine 的正确打开方式
  • 微信小程序长按识别图片二维码
  • 【C语言】字符函数与字符串函数实战:用法原理 + 模拟实现
  • 零、2025 年软件设计师考试大纲
  • Citrix 零日漏洞自五月起遭积极利用
  • Redis-基数统计、位图、位域、流
  • LangChain.js 实战与原理:用 LCEL 构建可维护的 RAG / Agent 系统(含 4 套 30+ 行代码)
  • 大语言模型生成的“超龄劳动者权益保障制度系统化完善建议(修订版)”