Python 原生爬虫教程: requests 第三方库

以下是关于 Python 爬虫中requests库的详细教程,包含基础用法、高级技巧和最佳实践:

一、requests 库简介

requests是 Python 中最流行的 HTTP 请求库,相比原生的urllib更简洁易用。它支持:

  • 处理各种 HTTP 请求(GET/POST/PUT/DELETE 等)
  • 自动处理 URL 编码、JSON 解析
  • 会话保持(自动管理 Cookie)
  • 超时设置、代理、SSL 验证等高级功能

安装方式

bash

pip install requests

二、基础请求方法

1. GET 请求

python

import requests

# 发送简单GET请求
response = requests.get('https://api.github.com/users/octocat')

# 获取响应状态码
print(f"状态码: {response.status_code}")  # 200表示成功

# 获取JSON响应
data = response.json()  # 自动解析JSON
print(f"用户名: {data['login']}")
print(f"关注者: {data['followers']}")

# 带参数的GET请求
params = {'q': 'python', 'page': 1}
response = requests.get('https://api.example.com/search', params=params)
# 实际请求URL会自动编码为: https://api.example.com/search?q=python&page=1
2. POST 请求

python

# 发送表单数据(Content-Type: application/x-www-form-urlencoded)
data = {'name': 'John', 'age': 30}
response = requests.post('https://api.example.com/submit', data=data)

# 发送JSON数据(Content-Type: application/json)
json_data = {'title': '爬虫测试', 'body': '这是测试内容'}
response = requests.post('https://api.example.com/posts', json=json_data)

# 上传文件
files = {'file': open('example.txt', 'rb')}
response = requests.post('https://api.example.com/upload', files=files)

三、响应处理

1. 获取响应内容

python

# 获取文本内容
html = response.text  # 自动解码(根据响应头的charset)

# 获取二进制内容(如图像、文件)
with open('image.jpg', 'wb') as f:
    f.write(response.content)  # 字节形式的响应内容

# 获取原始响应(未解码)
raw_response = response.raw
# 需要手动读取: content = raw_response.read()
2. 响应头和 Cookie

python

# 获取响应头
headers = response.headers
print(f"服务器: {headers['Server']}")  # 不区分大小写
print(f"内容类型: {headers.get('Content-Type')}")  # 推荐使用get()避免KeyError

# 获取Cookie
cookies = response.cookies
print(f"Session ID: {cookies.get('session_id')}")
3. 状态码和异常处理

python

# 检查请求是否成功
if response.status_code == 200:
    print("请求成功")
elif response.status_code == 404:
    print("资源不存在")
else:
    print(f"未知状态码: {response.status_code}")

# 更简洁的检查方法
response.raise_for_status()  # 如果状态码不是200,抛出HTTPError异常

# 完整的异常处理示例
try:
    response = requests.get('https://www.example.com', timeout=5)
    response.raise_for_status()  # 检查状态码
except requests.exceptions.HTTPError as e:
    print(f"HTTP错误: {e}")
except requests.exceptions.Timeout:
    print("请求超时")
except requests.exceptions.ConnectionError:
    print("连接错误")
except requests.exceptions.RequestException as e:
    print(f"其他错误: {e}")

四、高级用法

1. 自定义请求头

模拟浏览器行为,避免被网站识别为爬虫:

python

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
}

response = requests.get('https://www.example.com', headers=headers)
2. 会话保持(Session)

用于保持登录状态或跨请求共享 Cookie:

python

# 创建会话对象
session = requests.Session()

# 登录请求(设置Cookie)
login_data = {'username': 'test', 'password': '123456'}
session.post('https://example.com/login', data=login_data)

# 后续请求会自动携带之前的Cookie
response = session.get('https://example.com/dashboard')
print("登录后页面内容:", response.text)
3. 超时设置和代理

python

# 设置连接超时和读取超时(单位:秒)
response = requests.get('https://example.com', timeout=(3, 10))
# 3秒内必须建立连接,10秒内必须读取到数据

# 使用代理服务器
proxies = {
    'http': 'http://proxy.example.com:8080',
    'https': 'http://proxy.example.com:8080',
}
response = requests.get('https://example.com', proxies=proxies)
4. 流式响应(处理大文件)

python

# 下载大文件,避免一次性加载到内存
url = 'https://example.com/large_file.zip'
with requests.get(url, stream=True) as r:
    r.raise_for_status()
    with open('large_file.zip', 'wb') as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)

五、实战示例:爬取豆瓣电影 Top250

python

import requests
from bs4 import BeautifulSoup  # 需要额外安装: pip install beautifulsoup4

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

for start in range(0, 250, 25):  # 每页25条,共10页
    url = f'https://movie.douban.com/top250?start={start}'
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        items = soup.select('.item')
        
        for item in items:
            title = item.select_one('.title').text
            rating = item.select_one('.rating_num').text
            print(f"电影名称: {title}, 评分: {rating}")
    else:
        print(f"请求失败,状态码: {response.status_code}")

六、最佳实践

  1. 设置合理的请求间隔

    python

    import time
    time.sleep(1)  # 每次请求后休眠1秒,避免频繁请求
    
  2. 使用 Session 对象

    • 提高性能(复用连接)
    • 自动处理 Cookie
  3. 完善的异常处理

    python

    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print(f"请求出错: {e}")
        # 可添加重试逻辑
    
  4. 随机 User-Agent

    python

    import random
    
    user_agents = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
        'Mozilla/5.0 (Linux; Android 10; Pixel 4)'
    ]
    headers = {'User-Agent': random.choice(user_agents)}
    

七、常见问题

  1. SSL 验证失败

    python

    response = requests.get('https://example.com', verify=False)  # 禁用SSL验证
    # 注意:生产环境建议不要这样做,应修复证书问题
    
  2. 处理重定向

    python

    response = requests.get('http://example.com', allow_redirects=False)  # 禁用重定向
    print(f"重定向地址: {response.headers.get('Location')}")
    

  3. 处理 JSONP

    python

    import json
    
    response = requests.get('https://example.com/api?callback=jQuery123')
    jsonp_data = response.text
    # 提取JSON部分: 去除回调函数名和括号
    json_data = jsonp_data[jsonp_data.find('(')+1:jsonp_data.rfind(')')]
    data = json.loads(json_data)
    

    掌握requests库后,你可以轻松处理各种 HTTP 请求。后续可以结合BeautifulSouplxml等库进行 HTML 解析,或使用Scrapy框架构建更复杂的爬虫系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值