Python爬虫开发:requests库高级用法与实战案例
2026/7/23 16:07:27 网站建设 项目流程

1. 项目概述

今天咱们来聊聊Python爬虫开发中requests库的那些高级用法。作为一名爬虫工程师,requests库可以说是日常开发中最常用的工具之一。但很多朋友可能只停留在简单的get/post请求层面,其实requests还有很多强大的功能值得挖掘。

这篇文章将重点介绍requests库的几个高级应用场景:JSON解析、SSL认证、代理设置、超时控制、异常处理以及文件上传。同时还会分享如何搭建代理池、Django获取客户端IP,以及两个实战案例——视频网站和新闻网站的爬取。

2. requests高级用法详解

2.1 JSON数据解析

在爬虫开发中,我们经常需要处理API返回的JSON数据。requests提供了非常便捷的JSON解析方法:

import requests data = { 'keyword': '北京', 'pageIndex': 1, 'pageSize': 10 } response = requests.post('http://example.com/api/stores', data=data) # 方法1:手动解析JSON字符串 import json result = json.loads(response.text) # 方法2:直接使用response.json() result = response.json() # 直接返回字典对象 print(result['data'][0]['storeName'])

注意:使用response.json()时,如果响应内容不是合法的JSON格式,会抛出json.decoder.JSONDecodeError异常。

2.2 SSL证书验证

当访问HTTPS网站时,可能会遇到SSL证书验证问题:

# 忽略SSL证书验证(不推荐生产环境使用) response = requests.get('https://example.com', verify=False) # 关闭SSL警告 import urllib3 urllib3.disable_warnings() # 指定自定义证书路径(适合企业级应用) response = requests.get('https://example.com', cert=('/path/to/cert.pem', '/path/to/key.pem'))

SSL证书验证是保证通信安全的重要机制,在测试环境可以临时关闭验证,但在生产环境应该配置正确的证书。

2.3 代理设置

代理是爬虫开发中绕不开的话题,requests设置代理非常简单:

proxies = { 'http': 'http://proxy.example.com:8080', 'https': 'http://secureproxy.example.com:8090' } response = requests.get('http://target.com', proxies=proxies)

代理类型主要分为:

  • 透明代理:服务端可以获取真实客户端IP
  • 匿名代理:服务端知道使用了代理,但不知道真实IP
  • 高匿代理:服务端无法检测到代理使用

2.4 超时设置

合理的超时设置可以避免程序长时间挂起:

# 连接超时和读取超时都设为3秒 response = requests.get('http://example.com', timeout=3) # 分别设置连接超时和读取超时 response = requests.get('http://example.com', timeout=(2, 5)) # 连接2秒,读取5秒

2.5 异常处理

完善的异常处理能让爬虫更健壮:

from requests.exceptions import RequestException, Timeout try: response = requests.get('http://example.com', timeout=1) response.raise_for_status() # 检查HTTP状态码 except Timeout: print("请求超时") except RequestException as e: print(f"请求出错: {e}")

2.6 文件上传

使用requests上传文件也很简单:

files = {'file': open('example.pdf', 'rb')} response = requests.post('http://upload.example.com', files=files)

3. 代理池搭建实战

3.1 代理池架构

一个完整的代理池通常包含以下组件:

  1. 爬取模块:从免费代理网站抓取代理IP
  2. 存储模块:使用Redis存储代理IP
  3. 检测模块:定期验证代理可用性
  4. API模块:提供获取代理的接口

3.2 使用开源代理池

推荐使用jhao104/proxy_pool这个开源项目:

# 克隆项目 git clone https://github.com/jhao104/proxy_pool.git # 安装依赖 pip install -r requirements.txt # 配置Redis连接 # 修改setting.py中的DB_CONN # 启动调度程序 python proxyPool.py schedule # 启动API服务 python proxyPool.py server

3.3 代理池使用示例

import requests # 获取随机代理 proxy = requests.get("http://localhost:5010/get/").json() proxies = { "http": f"http://{proxy['proxy']}", "https": f"http://{proxy['proxy']}" } # 使用代理发送请求 try: response = requests.get("http://target.com", proxies=proxies, timeout=5) print(response.text) except Exception as e: print(f"请求失败: {e}") # 将失效代理删除 requests.get(f"http://localhost:5010/delete/?proxy={proxy['proxy']}")

4. Django获取客户端IP

在Django中获取客户端真实IP需要考虑多种情况:

# settings.py ALLOWED_HOSTS = ['*'] # views.py from django.http import HttpResponse def get_client_ip(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] # 获取第一个IP else: ip = request.META.get('REMOTE_ADDR') return HttpResponse(ip)

常见HTTP头中的IP相关信息:

  • REMOTE_ADDR:直接客户端IP
  • HTTP_X_FORWARDED_FOR:经过代理时的IP链
  • HTTP_CLIENT_IP:客户端IP(不太可靠)

5. 实战案例:视频网站爬取

以某视频网站为例,展示如何爬取视频资源:

import requests import re # 1. 获取视频列表页 list_url = "https://www.pearvideo.com/category_1" response = requests.get(list_url) video_ids = re.findall(r'video_(\d+)', response.text) # 2. 获取每个视频的真实地址 for vid in video_ids: # 伪造Referer headers = { 'Referer': f'https://www.pearvideo.com/video_{vid}' } # 获取视频信息 info_url = f"https://www.pearvideo.com/videoStatus.jsp?contId={vid}" info = requests.get(info_url, headers=headers).json() # 解析真实视频地址 fake_url = info["videoInfo"]["videos"]["srcUrl"] real_url = fake_url.replace(fake_url.split('/')[-1].split('-')[0], f'cont-{vid}') # 下载视频 video_data = requests.get(real_url, stream=True) with open(f'{vid}.mp4', 'wb') as f: for chunk in video_data.iter_content(1024): f.write(chunk)

关键点:

  1. 注意反爬机制,需要设置Referer
  2. 视频地址需要二次处理才能得到真实地址
  3. 大文件下载使用stream模式

6. 实战案例:新闻网站爬取

使用BeautifulSoup解析新闻页面:

import requests from bs4 import BeautifulSoup url = "https://news.example.com" response = requests.get(url) soup = BeautifulSoup(response.text, 'lxml') news_list = [] for item in soup.select('.news-item'): title = item.select_one('.title').text.strip() link = item.select_one('a')['href'] time = item.select_one('.time').text # 处理相对链接 if not link.startswith('http'): link = url + link news_list.append({ 'title': title, 'link': link, 'time': time }) # 存储到数据库 import pymysql conn = pymysql.connect(host='localhost', user='root', password='123456', db='news') try: with conn.cursor() as cursor: sql = "INSERT INTO news (title, link, publish_time) VALUES (%s, %s, %s)" for news in news_list: cursor.execute(sql, (news['title'], news['link'], news['time'])) conn.commit() finally: conn.close()

7. 常见问题与解决方案

7.1 请求频率过高被限制

解决方案:

  1. 使用代理池轮换IP
  2. 添加随机延迟
  3. 设置合理的请求头(User-Agent等)
import time import random time.sleep(random.uniform(0.5, 1.5)) # 随机延迟

7.2 验证码识别

应对方案:

  1. 使用第三方验证码识别服务
  2. 人工打码
  3. 尝试绕过验证码(修改Cookie等)

7.3 数据动态加载

处理方法:

  1. 分析Ajax请求接口
  2. 使用Selenium等浏览器自动化工具
  3. 解析JavaScript代码

7.4 数据存储优化

建议:

  1. 使用批量插入提高数据库写入效率
  2. 考虑使用消息队列解耦爬取和存储
  3. 定期清理无效数据

8. 爬虫开发最佳实践

  1. 遵守robots.txt:检查目标网站的爬虫协议
  2. 设置合理的请求间隔:避免给服务器造成过大压力
  3. 错误重试机制:对临时性错误进行自动重试
  4. 日志记录:详细记录爬取过程,方便排查问题
  5. 数据去重:使用BloomFilter等高效去重算法
# 重试装饰器示例 import time from functools import wraps def retry(max_retries=3, delay=1): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): retries = 0 while retries < max_retries: try: return func(*args, **kwargs) except Exception as e: retries += 1 if retries == max_retries: raise time.sleep(delay) return wrapper return decorator @retry(max_retries=5, delay=2) def fetch_url(url): response = requests.get(url, timeout=5) response.raise_for_status() return response.text

9. 性能优化技巧

  1. 连接复用:使用Session对象复用TCP连接
  2. 异步请求:配合aiohttp实现异步爬取
  3. 分布式爬取:使用Scrapy-Redis等框架
  4. 缓存机制:对不变的数据进行缓存
# 使用Session提高性能 session = requests.Session() # 第一次请求会建立TCP连接 response = session.get('http://example.com') # 后续请求复用已有连接 response2 = session.get('http://example.com/page2')

10. 法律与道德考量

  1. 尊重版权:不要爬取受版权保护的内容
  2. 隐私保护:不要收集和存储个人隐私信息
  3. 服务条款:遵守目标网站的使用条款
  4. 数据安全:妥善保管爬取的数据

爬虫开发不仅是个技术活,还需要考虑法律和道德层面的问题。在开始爬取前,务必确认你的行为是合法合规的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询