Agent轻松通-P2:执行一个简单的Agent

欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。

1 引言

本篇,我们将使用LangChain来搭建Agent,LangChain为我们处理了ReAct循环、工具调用、提示词模板化和输出解析等大量繁琐的底层工作,让我们能专注于核心逻辑。

本篇将演示网络搜索与网页抓取工具,将LLM(DeepSeek)、搜索工具和特制的提示词组装成一个可执行的Agent。给它一个研究任务,观察它的“思考-行动”过程。

tools是Agent的力量源泉。ReAct是Agent的灵魂。

2 环境准备

  • duckduckgo-search:一个免费易用的搜索引擎库
    其他的都是老熟人了(等下就是)。
pip install langchain langchain-community duckduckgo-search beautifulsoup4

3 定义我们的工具箱 (Toolbox)

  • LangChain的@tool注解
    @tool 装饰器用于将 Python 函数标记为一个“工具”,供 LLM(如 GPT、Grok)在需要外部功能时调用。工具可以是任何函数,例如搜索、计算、API 调用等。
    它会自动从函数的文档字符串 (docstring) 中提取出对工具的描述。

所以,我们必须清晰地告诉Agent “什么时候使用这个工具”和“输入应该是什么格式”。这是引导Agent正确行为的关键!

example:

定义工具

@tool
def search_tool(query: str) -> str:
    """
    当需要在线搜索最新信息、查找文章链接或回答关于时事的问题时,使用此工具。
    输入应该是一个精确的搜索查询语句。
    例如:'LangChain Agents'
    """
    print(f"\n>> 调用搜索工具,查询:'{query}'")
    # DuckDuckGoSearchRun 是 LangChain 内置的一个简单搜索工具
    from langchain_community.tools import DuckDuckGoSearchRun
    search = DuckDuckGoSearchRun()
    return search.run(query)


@tool
def scrape_website_tool(url: str) -> str:
    """
    当需要从一个给定的网页URL中获取详细文本内容时,使用此工具。
    输入必须是一个有效的URL。
    例如:'https://www.promptingguide.ai/zh/techniques/react'
    """
    print(f"\n>> 调用提取工具,提取 URL:'{url}' 上的文本")
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 移除脚本和样式元素
        for script_or_style in soup(["script", "style"]):
            script_or_style.decompose()        
        
        # 获取文本并进行基本清理
        text = soup.get_text()
        lines = (line.strip() for line in text.splitlines())
        chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
        text = '\n'.join(chunk for chunk in chunks if chunk)
        
        # 为了避免内容过长,我们只返回前4000个字符
        return text[:4000]
        
    except requests.RequestException as e:
        print(f"请求URL {url} 时出错: {e}")
        return f"{url}抓取失败: {e}"
    

# 定义工具列表
tools = [
    search_tool,
    scrape_website_tool
]


4 创建并执行Agent

我们需要使用LangChain的Agent Executor来链接LLM和工具箱tools。

并且在构建AgentExecutor示例对象的时候,设置verbose=True,以打印出Agent完整的思考链,便于我们观察和调试。

完整example

import os
from dotenv import load_dotenv

from langchain.tools import tool
import requests
from bs4 import BeautifulSoup


from langchain_deepseek import ChatDeepSeek
from langchain import hub
from langchain.agents import create_react_agent, AgentExecutor


# 1. 加载环境变量
# 这会从 .env 文件中加载 DEEPSEEK_API_KEY
load_dotenv()

# 检查API密钥是否已设置
def get_deepseek_key():
    key = os.getenv('DEEPSEEK_API_KEY')
    if key is None:
        raise ValueError("DEEPSEEK_API_KEY not found in environment variables.")
    return key

# 2.定义工具

@tool
def search_tool(query: str) -> str:
    """
    当需要在线搜索最新信息、查找文章链接或回答关于时事的问题时,使用此工具。
    输入应该是一个精确的搜索查询语句。
    例如:'LangChain Agents'
    """
    print(f"\n>> 调用搜索工具,查询:'{query}'")
    # DuckDuckGoSearchRun 是 LangChain 内置的一个简单搜索工具
    from langchain_community.tools import DuckDuckGoSearchRun
    search = DuckDuckGoSearchRun()
    return search.run(query)


@tool
def scrape_website_tool(url: str) -> str:
    """
    当需要从一个给定的网页URL中获取详细文本内容时,使用此工具。
    输入必须是一个有效的URL。
    例如:'https://www.promptingguide.ai/zh/techniques/react'
    """
    print(f"\n>> 调用提取工具,提取 URL:'{url}' 上的文本")
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 移除脚本和样式元素
        for script_or_style in soup(["script", "style"]):
            script_or_style.decompose()        
        
        # 获取文本并进行基本清理
        text = soup.get_text()
        lines = (line.strip() for line in text.splitlines())
        chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
        text = '\n'.join(chunk for chunk in chunks if chunk)
        
        # 为了避免内容过长,我们只返回前4000个字符
        return text[:4000]
        
    except requests.RequestException as e:
        print(f"请求URL {url} 时出错: {e}")
        return f"{url}抓取失败: {e}"
    

# 定义工具列表
tools = [
    search_tool,
    scrape_website_tool
]

# 3.LLM 初始化
def create_deepseek_llm():
    api_key = get_deepseek_key()
    if not api_key:
        raise ValueError("没有ds key")
    return ChatDeepSeek(
        model = "deepseek-chat",
        # temperature=0 表示我们希望Agent的思考过程尽可能稳定和可复现
        temperature=0, 
        max_tokens=None,
        timeout=None,
        max_retries=2,
        api_key=api_key
    )

# 4.获取ReAct提示词模板
# LangChain Hub是一个存放高质量提示词模板的社区
# "hwchase17/react" 是ReAct框架的官方标准提示词
prompt = hub.pull("hwchase17/react")
print("--- 打印ReAct提示词模板,检查格式 ---")
print(prompt) 


# 5.创建Agent
agent = create_react_agent(create_deepseek_llm(), tools, prompt)

# 6.创建Agent执行器
# Agent Executor负责实际运行ReAct循环,调用工具并获取观察结果
# verbose=True 会打印出Agent完整的思考链,非常便于我们观察和调试
agent_executor = AgentExecutor(agent=agent,tools = tools,verbose = True)

if __name__ == "__main__":
    print("\n--- 开始执行Agent ---")
    
    # 提出我们的研究问题
    question = "对比Java和Python在构建LLM应用中的优劣势,并列出各自的主流框架。"
    
    # 使用.invoke()方法来运行Agent
    response = agent_executor.invoke({"input": question})
    
    # 打印最终的输出结果
    print("\n--- Agent执行完毕 ---")
    print("最终答案:")
    print(response['output'])

这段代码可以执行并返回有完整的ReAct循环:Thought—>Action—>Observation—>Thought。
同时,也展示了一个入门级问题——“LLM的行为与Agent执行器的期望不匹配”。

ValueError: An output parsing error occurred. In order to pass this error back to the agent and have it try again, pass `handle_parsing_errors=True` to the AgentExecutor. This is the error: Could not parse LLM output: 

5 Agent注意事项

5.1 ReAct模板

ReAct提示词模板和普通模板存在结构上的差别,一般Prompt结构可以划分为六要素。

ReAct提示词模板算是特殊模板,强化了“规范思考过程和输出格式”,是一种“教学式”或“引导式”的模板。

它不要求LLM直接给答案,而是通过提供示例(Thought, Action, Observation的例子),来教会LLM一种思考和行动的“格式”或“流程”。它的目标是让LLM学会如何分解任务、使用工具,并以特定的结构化方式输出它的下一步计划。

在example中,我们的ReAct模板是:

input_variables=['agent_scratchpad', 'input', 'tool_names', 'tools'] input_types={} partial_variables={} metadata={'lc_hub_owner': 'hwchase17', 'lc_hub_repo': 'react', 'lc_hub_commit_hash': 'd15fe3c426f1c4b3f37c9198853e4a86e20c425ca7f4752ec0c9b0e97ca7ea4d'} template='Answer the following questions as best you can. You have access to the following tools:\n\n{tools}\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: {input}\nThought:{agent_scratchpad}'

翻译一下是:

输入变量 = ['agent_scratchpad', 'input', 'tool_names', 'tools']
输入类型 = {}
部分变量 = {}
元数据 = {'lc_hub_owner': 'hwchase17', 'lc_hub_repo': 'react', 'lc_hub_commit_hash': 'd15fe3c426f1c4b3f37c9198853e4a86e20c425ca7f4752ec0c9b0e97ca7ea4d'}
模板 = ' 尽可能最佳地回答以下问题。你可以使用以下工具:\n\n {tools}\n\n 使用以下格式:\n\n 问题:你必须回答的输入问题 \n 思考:你应该始终思考该做什么 \n 动作:要采取的动作,必须是 [{tool_names}] 中的一个 \n 动作输入:动作的输入 \n 观察:动作的结果 \n...(这个思考 / 动作 / 动作输入 / 观察可以重复 N 次)\n 思考:我现在知道最终答案了 \n 最终答案:原始输入问题的最终答案 \n\n 开始!\n\n 问题:{input}\n 思考:{agent_scratchpad}'

模板的核心=引导示例+严格输出格式限制

  • 核心示例:
    • 看,这是第一个例子: 当问题是A时,你应该先Thought: …,然后Action: …,然后你会得到Observation: …,接着你再Thought: …,直到最后给出Final Answer: …。
    • 看,这是第二个例子: 当问题是B时,你的思考和行动流程是这样的…
  • 输出格式: 极其严格! 你必须严格按照Thought: …和Action: …的格式来输出你的下一步计划,或者用Final Answer: …来输出最终答案。绝对不能一次性输出所有内容。

5.2 LLM的行为与Agent执行器的期望不匹配

在example中,我们期望的是Agent中的LLM每一次只返回一个步骤(一个Thought或者Observation)。而我们的LLM一次返回了所有内容,包含了所有的思考、行动、观察、最终答案。

这样导致了一个后果,AgentExecutor的输出解析器 (Output Parser),无法解析DeepSeek返回的那个“过于完整”的响应。

可以通过以下方式进行调整

5.2.1 让Agent学会处理解析错误

我们可以告诉AgentExecutor:“如果你遇到了解析错误,不要直接崩溃。把这个错误信息包装一下,作为一次‘观察结果’反馈给LLM,让它自己意识到格式错了,然后重新生成一次。”

这需要在创建AgentExecutor时,加入一个参数 handle_parsing_errors=True。

# 修改前
# agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 修改后
agent_executor = AgentExecutor(
    agent=agent, 
    tools=tools, 
    verbose=True, 
    handle_parsing_errors=True  # <--- 添加这个参数
)

5.2.2 在提示词中明确约束

我们可以在提示词中更强硬地命令LLM,让它一次只输出一个步骤。但这需要修改从hub拉取下来的prompt对象,相对复杂一些,我们可以在掌握方案一之后再尝试。

在我们的example中,使用handle_parsing_errors=True处理了错误,但是会导致LLM思考的上下文被污染,导致上下文出现Final Answer(理论上应该只出现一次),进而导致LLM思考异常,多次输出Final Answer。
因此,我们要修改我们的ReAct模板。

LangChain的默认hwchase17/react提示词模板对于某些模型来说,约束力可能不够强。

这里不得不提一句,DeepSeek有很强的“一步到位”倾向,这个ReAct模板调的头疼。

使用高度定制化、强约束、本地化的ReAct提示词模板

  1. 明确的禁令 (Explicit Prohibitions): 直接用加粗、大写等方式,告诉模型“禁止”做什么。
  2. 单一任务原则 (Single Task Principle): 强调每一步只做一件事。
  3. 格式的绝对权威 (Format Absoluteness): 反复重申必须、严格、只能遵循给定的格式。

同时,要注意中文与英文解析不同,提示词模板(Prompt Template)和输出解析器(Output Parser)要适配。
且不同ReAct解析器能解析的单词也不一样,比如对于默认的ReAct解析器,我想使用下列格式就不行:

Thought: [一些思考]
Action:
```json
{
  "action": "search_tool",
  "action_input": "..."
}

其无法解析action与action_input,报错

Invalid Format: Missing 'Action Input:' after 'Action:'Thought

最终ReAct模板如下:

template = """
**指令:**
你是一个能够调用工具的智能助手。请严格按照以下格式,一步一步地回答问题。
**绝对禁止** 一次性输出所有步骤和最终答案。你**必须**一次只输出一个“思考”或“最终答案”区块。

**可用工具列表:**
{tools}

**输出格式要求:**
你的输出**必须严格**遵循以下两种格式之一:

**格式一:当你需要使用工具时**
Thought:[这里是你的思考过程,分析你需要做什么,决定使用哪个工具]
Action: [这里是你要调用的工具名称,必须是 {tool_names} 中的一个]
Action Input: [这里是传递给工具的输入参数]

**格式二:当你已经知道最终答案时,必须只包含'Final Answer'**

Thought:[这里是你总结性的思考,确认你已拥有足够信息来回答问题]
Final Answer:[这里是你对原始问题的最终回答]

**重要提醒:**

- 每一次返回,“Thought”+“Action”,要么是“Thought”+“Final Answer”。绝对不能两者都包含。
- “Final Answer”使用中文回答

**开始执行任务!**

**问题:** {input}  
**思考过程日志:**  
{agent_scratchpad}
"""

完整example如下,还增加了一个计数器,用于显示Thought轮次:

import os
from dotenv import load_dotenv

from langchain.tools import tool
import requests
from bs4 import BeautifulSoup
from typing import Any, Dict, List

from langchain_deepseek import ChatDeepSeek
from langchain import hub
from langchain.agents import create_react_agent, AgentExecutor
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction
from langchain.prompts import PromptTemplate
from langchain_community.tools import DuckDuckGoSearchRun

# 1. 加载环境变量
# 这会从 .env 文件中加载 DEEPSEEK_API_KEY
load_dotenv()

# 检查API密钥是否已设置
def get_deepseek_key():
    key = os.getenv('DEEPSEEK_API_KEY')
    if key is None:
        raise ValueError("DEEPSEEK_API_KEY not found in environment variables.")
    return key

# 2.定义工具

@tool
def search_tool(query: str) -> str:
    """
    当需要在线搜索最新信息、查找文章链接或回答关于时事的问题时,使用此工具。
    输入应该是一个精确的搜索查询语句。
    例如:'LangChain Agents'
    """
    print(f"\n>> 调用搜索工具,查询:'{query}'")
    # DuckDuckGoSearchRun 是 LangChain 内置的一个简单搜索工具
    search = DuckDuckGoSearchRun()
    return search.run(query)


@tool
def scrape_website_tool(url: str) -> str:
    """
    当需要从一个给定的网页URL中获取详细文本内容时,使用此工具。
    输入必须是一个有效的URL。
    例如:'https://www.promptingguide.ai/zh/techniques/react'
    """
    print(f"\n>> 调用提取工具,提取 URL:'{url}' 上的文本")
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 移除脚本和样式元素
        for script_or_style in soup(["script", "style"]):
            script_or_style.decompose()        
        
        # 获取文本并进行基本清理
        text = soup.get_text()
        lines = (line.strip() for line in text.splitlines())
        chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
        text = '\n'.join(chunk for chunk in chunks if chunk)
        
        # 为了避免内容过长,我们只返回前4000个字符
        return text[:4000]
        
    except requests.RequestException as e:
        print(f"请求URL {url} 时出错: {e}")
        return f"{url}抓取失败: {e}"
    

# 定义工具列表
tools = [
    search_tool,
    scrape_website_tool
]

# 3.LLM 初始化
def create_deepseek_llm():
    api_key = get_deepseek_key()
    if not api_key:
        raise ValueError("没有ds key")
    return ChatDeepSeek(
        model = "deepseek-chat",
        # temperature=0 表示我们希望Agent的思考过程尽可能稳定和可复现
        temperature=0, 
        max_tokens=None,
        timeout=None,
        max_retries=2,
        api_key=api_key
    )

# ==============================================================================
# --- (新增) 自定义回调处理器,用于打印思考轮次 ---
# ==============================================================================
class IterationCounterCallback(BaseCallbackHandler):
    """一个在每次Agent行动前打印轮次的回调处理器"""
    
    def __init__(self):
        self.iteration_count = 0

    def on_agent_action(
        self,
        action: AgentAction,
        *,
        run_id: Any,
        parent_run_id: Any = None,
        **kwargs: Any,
    ) -> Any:
        """在Agent执行一个行动时被调用。"""
        # 我们将这个事件作为新一轮思考的开始
        self.iteration_count += 1
        print(f"\n--- 🤔 思考轮次: {self.iteration_count} ---")


# 4.获取ReAct提示词模板
# LangChain Hub是一个存放高质量提示词模板的社区
# "hwchase17/react" 是ReAct框架的官方标准提示词
# 我们不再从hub拉取,而是手动定义一个包含更强约束的模板
template = """
**指令:**
你是一个能够调用工具的智能助手。请严格按照以下格式,一步一步地回答问题。
**绝对禁止** 一次性输出所有步骤和最终答案。你**必须**一次只输出一个“思考”或“最终答案”区块。

**可用工具列表:**
{tools}

**输出格式要求:**
你的输出**必须严格**遵循以下两种格式之一:

**格式一:当你需要使用工具时**
Thought:[这里是你的思考过程,分析你需要做什么,决定使用哪个工具]
Action: [这里是你要调用的工具名称,必须是 {tool_names} 中的一个]
Action Input: [这里是传递给工具的输入参数]

**格式二:当你已经知道最终答案时,必须只包含'Final Answer'**

Thought:[这里是你总结性的思考,确认你已拥有足够信息来回答问题]
Final Answer:[这里是你对原始问题的最终回答]

**重要提醒:**

- 每一次返回,“Thought”+“Action”,要么是“Thought”+“Final Answer”。绝对不能两者都包含。
- “Final Answer”使用中文回答

**开始执行任务!**

**问题:** {input}  
**思考过程日志:**  
{agent_scratchpad}
"""

# 使用我们自定义的模板创建一个PromptTemplate对象
prompt = PromptTemplate.from_template(template)

# prompt = hub.pull("hwchase17/react")
print("--- 打印ReAct提示词模板,检查格式 ---")
print(prompt) 


# 5.创建Agent
agent = create_react_agent(create_deepseek_llm(), tools, prompt)

# 6.创建Agent执行器
# Agent Executor负责实际运行ReAct循环,调用工具并获取观察结果
# verbose=True 会打印出Agent完整的思考链,非常便于我们观察和调试
agent_executor = AgentExecutor(agent=agent,tools = tools,verbose = True,handle_parsing_errors=True)

if __name__ == "__main__":
    print("\n--- 开始执行Agent ---")
    
    # 提出我们的研究问题
    question = "对比Java和Python在构建LLM应用中的优劣势,并列出各自的主流框架。"
    
    # 创建我们的回调处理器实例
    iteration_counter = IterationCounterCallback()
    
    # 使用.invoke()方法来运行Agent,通过config传入回调处理器
    response = agent_executor.invoke(
            {"input": question},
            config={"callbacks": [iteration_counter]} # 挂载回调处理器
        )
    
    # 打印最终的输出结果
    print("\n--- Agent执行完毕 ---")
    print("最终答案:")
    print(response['output'])
<think>嗯,我现在需要帮用户分析这段robots.txt的代码。首先,我得回忆一下robots.txt的基本结构。它主要是用来指导网络爬虫哪些页面可以访问,哪些不可以。每个User-agent后面跟着Allow和Disallow指令,对吧? 用户提供的代码看起来分成几个部分。首先是针对Baiduspider的,然后是对其他爬虫的设置,最后是配符User-agent: *。我需要逐一检查每个User-agent对应的规则是否正确。 首先看Baiduspider的部分。这里Allow: / 应该是允许访问根目录,但接下来有几个Disallow的路径,比如/pcdutu、/pcdutu/p_list等。这些路径可能是不想让百度爬虫抓取的。不过这里有个疑问,Allow: / 是允许整个网站,但后面又Disallow特定路径,这样是否有效?应该是有效的,因为后面的Disallow会覆盖前面的Allow吗?或者robots.txt的规则是顺序无关的,以更具体的路径为准? 然后其他爬虫,比如Googlebot、MSNBot等,都是Allow: /,也就是允许访问整个网站。看起来用户希望这些搜索引擎可以抓取所有内容,而只对百度爬虫做了限制。 最后User-agent: * 也就是所有其他爬虫,Disallow: /,也就是禁止所有访问。这部分需要注意,常这个配符会覆盖之前没提到的爬虫,但这里之前的各个爬虫都有明确的Allow,所以应该没问题。不过要确认是否有重复的User-agent被覆盖的情况。 另外,检查语法是否正确。每个User-agent后面是否都有对应的规则,指令是否正确。比如Allow和Disallow后面是否有正确的路径。比如Disallow的路径是否正确,有没有拼写错误。例如,/search/detailidlsimipic这个路径是否有问题?可能需要用户确认是否存在这个路径。 还有,Baiduspider-image是百度图片爬虫,这里也允许了所有,但主Baiduspider却有一些Disallow。可能需要确认是否图片爬虫和其他百度爬虫的区分是否正确。 用户可能想知道这段代码的效果是什么。总结来说,就是允许大部分主流爬虫(Google、Bing、搜狗等)抓取整个网站,但限制百度爬虫访问特定目录,同时禁止其他未指定的爬虫访问任何内容。 有没有可能存在的问题呢?比如,Disallow的路径是否应该以斜杠开头,这里看起来是的。另外,是否有重复的User-agent定义?比如Baiduspider和其他百度相关的爬虫是否会被配符影响?但在这里,Baiduspider和其他百度爬虫都有明确的Allow,所以配符的Disallow不会影响到它们,因为User-agent的匹配是精确优先的。 总的来说,这段robots.txt的配置主要是限制百度主爬虫抓取某些路径,同时允许其他搜索引擎全面抓取,并屏蔽其他未被明确允许的爬虫。需要确保被Disallow的路径确实不需要被百度收录,否则可能会影响网站在百度搜索中的可见性。</think>以下是对该robots.txt文件的逐步分析: $$robots.txt \text{分析流程图}$$ \begin{tikzpicture} \node[draw] (start) at (0,0) {开始解析}; \node[draw] (ua) at (0,-2) {解析User-agent字段}; \node[draw] (baidu) at (-3,-4) {Baiduspider规则组}; \node[draw] (others) at (3,-4) {其他爬虫规则组}; \node[draw] (wildcard) at (0,-6) {配符规则组}; \draw[->] (start) -- (ua); \draw[->] (ua) -- node[left]{匹配百度} (baidu); \draw[->] (ua) -- node[right]{匹配Googlebot等} (others); \draw[->] (ua) -- node{默认处理} (wildcard); \end{tikzpicture} $$ 一、**文件结构解析** 1. 包含6个独立规则组,按优先级排序: - 特定爬虫规则(Baiduspider) - 其他11个指定爬虫规则 - 配符规则(*) 2. **路径匹配规则**: - 所有路径均以`/`开头,符合标准语法 - 路径含多级目录,如`/pcdutu/p_list` 二、**百度爬虫专项控制** 1. **特殊限制路径**: ```plaintext Disallow: /pcdutu // 禁止目录 Disallow: /pcdutu/p_list // 禁止子目录 Disallow: /n/pc_list // 动态列表页 Disallow: /n/pc_search // 搜索功能 Disallow: /search/detailidlsimipic // 特定详情页 ``` 2. **策略分析**: - 过`Allow: /`开放全站访问权限 - 使用5个`Disallow`精准拦截敏感路径 - 防止百度抓取:重复列表页、搜索功能、特定详情页 三、**其他爬虫开放策略** 1. **覆盖主流搜索引擎**: ```plaintext Googlebot(谷歌) MSNBot(必应) Sogou系列(搜狗) YoudaoBot(有道) yisouspider(神马) ChinasoSpider(中国搜索) ``` 2. **权限设置**: - 全部使用`Allow: /`授予全站访问权限 - 无任何限制条款,支持深度抓取 四、**安全防护机制** 1. **配符规则**: ```plaintext User-agent: * Disallow: / ``` - 拦截所有未明确列出的爬虫 - 防止恶意爬虫消耗服务器资源 五、**潜在优化建议** 1. **路径验证建议**: - 检查`/search/detailidlsimipic`路径有效性 - 确认`/n/pc_list`是否需要完全屏蔽 2. **百度子爬虫处理**: - `Baiduspider-image`单独设置`Allow: /` - 确保图片资源能被正常收录 3. **版本控制建议**: - 增加注释行(如:`# Version 2023`) - 使用Sitemap声明(如:`Sitemap: https://example.com/sitemap.xml`) 该配置体现了精准的访问控制策略,在保障主流搜索引擎收录的同时,有效保护敏感数据。建议定期使用Google Search Console和百度站长工具验证规则有效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tataCrayon|啾啾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值