爬虫笔记1:pycharm通过requests模块实现1简单爬虫2输入关键词获取搜索到的网页数据

'# 爬虫笔记1:pycharm通过requests模块实现1简单爬虫2输入关键词获取搜索到的网页数据

一、背景与问题

在数据驱动的软件开发中,爬虫技术是获取互联网数据的重要手段。传统开发场景中,手动抓取数据需要频繁切换浏览器、记录URL、筛选内容,效率低下。通过requests模块实现的爬虫,能够自动化完成网络请求、数据解析和存储,大大提升开发效率。

然而,实际开发中常遇到以下问题:

  1. 基础请求无法获取数据(如反爬虫机制)
  2. 无法处理分页数据
  3. 网络异常处理不完善
  4. 多参数组合查询时URL构造错误
  5. 数据格式解析失败

二、基本原理

HTTP协议是爬虫工作的核心,requests模块封装了完整的HTTP请求流程:

  1. 连接建立:通过TCP协议建立与服务器的连接
  2. 请求发送:构造包含请求头(headers)、参数(params)、正文(body)的HTTP请求
  3. 响应接收:获取服务器返回的HTTP状态码、响应头、响应体
  4. 数据解析:将响应体中的HTML/XML/JSON等格式数据转换为结构化数据

requests模块的关键技术点:

  • 会话管理:通过Session对象保持连接复用
  • 异常处理:封装了超时、连接错误等异常类型
  • 请求方法:支持GET/POST/PUT/DELETE等HTTP方法
  • 请求头控制:可自定义User-Agent、Referer等字段

三、环境准备

1. 安装依赖

pip install requests

2. PyCharm配置

  • 创建新项目:File → New Project
  • 添加Python解释器:Preferences → Project: Interpreter
  • 安装requests库:在终端执行pip install requests

3. 网络环境

  • 确保网络连接正常
  • 部分网站可能需要配置代理:

    proxies = {
      'http': 'http://10.10.1.10:3128',
      'https': 'http://10.10.1.10:1080'
    }

四、核心实现

1. 基础请求示例

import requests

# 发送GET请求
response = requests.get('https://httpbin.org/get', params={'key': 'value'}, headers={'User-Agent': 'Mozilla/5.0'})

# 打印响应内容
print(response.status_code)       # 输出HTTP状态码
print(response.headers)           # 输出响应头
print(response.text)              # 输出响应体内容
print(response.json())            # 解析JSON格式响应

关键代码解释:

  • params参数用于构建查询字符串(URL编码)
  • headers参数模拟浏览器请求头
  • response.json()自动处理JSON格式的响应体

2. 带参数的搜索请求

def search_web(keyword):
    url = 'https://api.example.com/search'
    payload = {
        'q': keyword,
        'count': 10,
        'type': 'web'
    }
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'Accept-Language': 'en-US'
    }
    
    try:
        response = requests.get(url, params=payload, headers=headers, timeout=5)
        response.raise_for_status()  # 检查HTTP错误
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"请求异常: {e}")
        return None

关键代码解释:

  • params参数自动进行URL编码
  • raise_for_status()检查4xx/5xx错误
  • timeout参数防止长时间等待
  • response.json()处理JSON响应

3. 分页数据处理

def get_pagination_data(base_url, page_size=10, max_pages=5):
    all_data = []
    for page in range(1, max_pages+1):
        params = {'page': page, 'size': page_size}
        response = requests.get(base_url, params=params, timeout=5)
        if response.status_code == 200:
            all_data.extend(response.json()['items'])
        else:
            break
    return all_data

关键代码解释:

  • 使用循环处理多页数据
  • 每页数据通过params参数传递
  • 响应数据合并到all_data列表中
  • 简单的错误处理机制

五、完整案例

1. 百度搜索结果爬取案例

import requests
import time

def baidu_search(keyword, max_results=10):
    base_url = 'https://api.baidu.com/search'
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'Referer': 'https://www.baidu.com/',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    
    results = []
    for i in range(1, max_results+1):
        params = {
            'q': keyword,
            'pn': i,  # 页码参数
            'rn': 10, # 每页结果数
            'ie': 'utf8'
        }
        
        try:
            response = requests.get(base_url, params=params, headers=headers, timeout=10)
            if response.status_code == 200:
                data = response.json()
                results.extend(data['results'])
            else:
                print(f"请求失败,状态码: {response.status_code}")
                break
        except requests.exceptions.RequestException as e:
            print(f"请求异常: {e}")
            break
        time.sleep(1)  # 防止请求过快
    
    return results

运行示例:

if __name__ == '__main__':
    keywords = input("请输入搜索关键词: ")
    results = baidu_search(keywords)
    print(f"共获取到{len(results)}条结果")

关键点分析:

  1. 使用百度API进行搜索,实际开发中需申请API密钥
  2. 页码参数pn和每页结果数rn的组合控制分页
  3. 使用time.sleep(1)控制请求频率,避免被封禁
  4. 异常处理机制确保程序稳定性

六、源码解析

1. requests.get()的内部机制

def get(url, **kwargs):
    return request('GET', url, **kwargs)
  • 会话管理:自动创建Session对象
  • 适配器机制:使用HTTPAdapter处理不同协议
  • 连接池:复用TCP连接提高效率

2. Session对象的使用

session = requests.Session()
session.headers.update({'User-Agent': 'CustomAgent'})
response = session.get('https://example.com')
  • 保持会话状态(如cookies)
  • 提升连接复用效率
  • 支持自定义headers和cookies

3. 异常处理机制

try:
    response = requests.get('https://example.com', timeout=5)
except requests.exceptions.Timeout:
    print("请求超时")
except requests.exceptions.ConnectionError:
    print("连接错误")
except requests.exceptions.HTTPError as e:
    print(f"HTTP错误: {e.response.status_code}")

七、进阶使用

1. 使用Session复用连接

session = requests.Session()
session.headers.update({
    'User-Agent': 'Mozilla/5.0',
    'Accept-Language': 'en-US'
})
response1 = session.get('https://example.com')
response2 = session.get('https://another-example.com')

2. 处理复杂headers

headers = {
    'User-Agent': 'Mozilla/5.0',
    'Accept': 'text/html,application/xhtml+xml',
    'Accept-Encoding': 'gzip',
    'Accept-Language': 'en-US,en;q=0.9'
}

3. 使用cookies

cookies = {
    'session_id': '123456',
    'user_token': 'abcdef'
}
response = requests.get('https://example.com', cookies=cookies)

八、性能与工程实践

1. 性能优化方案

优化策略说明
连接复用使用Session对象保持连接
并发处理使用concurrent.futures或asyncio进行并发
缓存机制使用redis缓存常见请求结果
压缩传输设置Accept-Encoding: gzip

2. 异常处理规范

def safe_request(url):
    try:
        return requests.get(url, timeout=5)
    except requests.exceptions.RequestException as e:
        print(f"请求异常: {e}")
        return None

3. 安全风险分析

  1. IP封禁:频繁请求可能导致被封禁
  2. 反爬虫机制:网站可能使用验证码、JavaScript渲染
  3. 数据泄露:未加密的请求可能暴露敏感信息
  4. 法律风险:违反网站的robots.txt协议

九、常见问题与踩坑

1. 常见错误及解决办法

错误类型错误示例解决方案
User-Agent缺失requests.exceptions.HTTPError: 403 Forbidden设置合理的User-Agent
超时异常requests.exceptions.Timeout调整timeout参数或增加重试机制
SSL证书错误requests.exceptions.SSLError使用verify=False或安装证书

2. 分页处理错误

# 错误示例
params = {'page': 1, 'size': 10}
response = requests.get(url, params=params)

问题:未处理分页参数的递增逻辑,导致无法获取后续页数据

3. 请求参数拼接错误

# 错误示例
url = 'https://api.example.com/search'
params = {'q': 'python', 'page': 2, 'size': 10}
response = requests.get(url, params=params)

问题:未正确处理URL编码,导致参数解析错误

十、最佳实践

1. 推荐方案

  1. 使用Session对象:保持连接复用,提高效率
  2. 合理设置headers:模拟真实浏览器行为
  3. 异常处理机制:确保程序健壮性
  4. 参数校验:防止非法输入导致错误
  5. 日志记录:记录请求和响应信息便于调试

2. 推荐目录结构

project/
├── config/                # 配置文件
├── utils/                # 工具函数
│   └── requests_utils.py
├── core/                 # 核心逻辑
│   └── crawler.py
├── tests/                # 测试用例
└── main.py               # 启动文件

3. 推荐代码规范

  • 使用requests.Session()保持连接
  • 所有请求必须包含User-Agent
  • 使用timeout参数控制请求时间
  • 所有异常必须有对应的处理逻辑

十一、总结

通过requests模块实现的简单爬虫,是数据采集的基础工具。在实际开发中,需要充分理解HTTP协议原理,合理使用Session对象,设置合理的headers,处理异常情况,并注意安全风险。

本方案适用于:

  • 数据采集需求明确的场景
  • 需要批量处理数据的场景
  • 需要自动化获取数据的场景

但不适用于:

  • 需要处理动态加载内容的场景(需使用Selenium)
  • 需要处理复杂反爬机制的场景
  • 需要处理大量数据的场景(需结合数据库)

在开发过程中,要始终遵循合法合规的原则,尊重网站的robots.txt协议,合理控制请求频率,避免对服务器造成过大负担。

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日