首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >强化学习驱动的智能限速:动态请求间隔的终极方案

强化学习驱动的智能限速:动态请求间隔的终极方案

原创
作者头像
jackcode
发布于 2025-06-03 04:12:56
发布于 2025-06-03 04:12:56
9000
代码可运行
举报
文章被收录于专栏:爬虫资料爬虫资料
运行总次数:0
代码可运行
爬虫代理
爬虫代理

项目背景

在高并发、多线程的数据采集场景中,设置固定的请求间隔已不再适用于复杂的网站管理机制。一方面,间隔太短容易触发封禁;另一方面,间隔太长则影响效率。因此,本文引入强化学习(Reinforcement Learning, RL)思想,让“采集调度器”具备动态适应能力:它会根据反馈(如访问成功率、响应时间)自动调整请求频率,实现高效与安全的平衡。

数据目标

我们将使用关键词搜索京东商品,提取排名前10个搜索结果中的以下信息:

  • 商品名称
  • 商品价格
  • 商品规格(如内存、颜色等)
  • 商品链接

这些数据将以结构化形式存储为分类字典,并最终展示分析结果。

技术选型

技术

用途

requests + BeautifulSoup

发起请求并解析网页

强化学习策略函数(简化版 Q-learning)

动态调整请求间隔

爬虫代理

避免 IP 被封禁

用户设置

模拟真实浏览器行为

pandas

存储与分析数据

模块实现

1. 环境准备

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import time
import random
import requests
from bs4 import BeautifulSoup
import pandas as pd
from collections import defaultdict

2. 强化学习智能限速策略(简化版 Q-learning)

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
class DynamicRateLimiter:
    def __init__(self, intervals=[1, 2, 3], alpha=0.5, gamma=0.9, epsilon=0.1):
        self.q_table = {i: 0.0 for i in intervals}
        self.intervals = intervals
        self.alpha = alpha
        self.gamma = gamma
        self.epsilon = epsilon
        self.last_action = random.choice(intervals)

    def choose(self):
        # ε-贪婪策略
        if random.random() < self.epsilon:
            self.last_action = random.choice(self.intervals)
        else:
            self.last_action = max(self.q_table, key=self.q_table.get)
        return self.last_action

    def feedback(self, reward):
        old_value = self.q_table[self.last_action]
        self.q_table[self.last_action] = old_value + self.alpha * (reward + self.gamma * max(self.q_table.values()) - old_value)

3. 请求函数(用户设置)

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def get_headers_and_cookies():
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
    }
    cookies = {
        "TrackID": "1XXXXXXXXXXXXXXX",  # 示例Cookie,可使用浏览器F12复制
    }
    return headers, cookies
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def get_proxies():
    # 爬虫代理配置(参考亿牛云示例)
    proxy_host = "proxy.16yun.cn"
    proxy_port = "3100"
    proxy_user = "16YUN"
    proxy_pass = "16IP"
    
    proxy_meta = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    proxies = {
        "http": proxy_meta,
        "https": proxy_meta,
    }
    return proxies

4. 商品搜索请求并解析前10项

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def search_jd(keyword, limiter):
    base_url = f"https://search.jd.com/Search?keyword={keyword}&enc=utf-8"
    headers, cookies = get_headers_and_cookies()
    proxies = get_proxies()

    while True:
        wait_time = limiter.choose()
        time.sleep(wait_time)

        try:
            response = requests.get(base_url, headers=headers, cookies=cookies, proxies=proxies, timeout=10)
            if response.status_code == 200:
                limiter.feedback(1)  # 成功,正向奖励
                return response.text
            else:
                limiter.feedback(-1)  # 失败,负向奖励
        except Exception as e:
            print(f"请求失败: {e}")
            limiter.feedback(-1)

5. 页面解析与数据存储

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def parse_products(html):
    soup = BeautifulSoup(html, "html.parser")
    items = soup.select("li.gl-item")
    results = []

    for item in items[:10]:  # 只处理前10个
        title_tag = item.select_one("div.p-name em")
        price_tag = item.select_one("div.p-price i")
        link_tag = item.select_one("div.p-name a")

        title = title_tag.text.strip() if title_tag else "N/A"
        price = price_tag.text.strip() if price_tag else "N/A"
        link = "https:" + link_tag.get("href") if link_tag else "N/A"

        spec = title.split(" ")[:2]  # 简化为前两项关键词
        results.append({
            "商品名称": title,
            "价格": price,
            "规格": " / ".join(spec),
            "链接": link
        })
    return results

6. 主函数与运行逻辑

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def main():
    keyword = "笔记本电脑"
    limiter = DynamicRateLimiter()
    html = search_jd(keyword, limiter)
    product_list = parse_products(html)

    df = pd.DataFrame(product_list)
    df.to_csv("jd_top10_products.csv", index=False, encoding="utf-8-sig")
    print("已保存数据:")
    print(df)

if __name__ == "__main__":
    main()

数据展示(Top10商品示例)

运行结果(示意):

商品名称

价格

规格

链接

联想 小新Pro16 锐龙版

4899元

联想 / 小新Pro

惠普 光影精灵9

5899元

惠普 / 光影精灵

...

...

...

...


总结

本项目展示了一个具有“自适应限速能力”的数据采集架构,突破传统静态策略,在应对反爬环境中更具弹性。强化学习思想让程序自主判断并优化策略,有效降低了请求失败率,提高了数据采集效率。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目背景
  • 数据目标
  • 技术选型
  • 模块实现
    • 1. 环境准备
    • 2. 强化学习智能限速策略(简化版 Q-learning)
    • 3. 请求函数(用户设置)
    • 4. 商品搜索请求并解析前10项
    • 5. 页面解析与数据存储
    • 6. 主函数与运行逻辑
  • 数据展示(Top10商品示例)
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档