You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Python requests请求DuckDuckGo时的异常搜索问题

解决DuckDuckGo搜索含特殊字符查询返回无结果的问题

我之前也碰到过一模一样的情况——DuckDuckGo对自动化请求的检测相当严格,尤其是当查询里同时包含引号、星号这类特殊字符时,很容易被判定为非人类请求,直接返回空结果页面。下面是几个亲测有效的解决思路:

1. 模拟真实浏览器的完整请求头

requests库默认的请求头太"朴素"了,一眼就能被识别出是程序发起的请求。你需要补上浏览器会携带的关键头字段,比如User-AgentAcceptAccept-Language,同时用会话保持Cookie,模拟真实用户的访问流程。

示例代码:

import requests
from urllib.parse import quote

query = '"*example"'
encoded_query = quote(query)
url = f"https://duckduckgo.com/html/?q={encoded_query}&kl=us-en"

# 模拟Chrome浏览器的请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Referer": "https://duckduckgo.com/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}

# 先访问主页初始化会话并获取Cookie,再发起搜索请求
session = requests.Session()
session.get("https://duckduckgo.com/", headers=headers)
response = session.get(url, headers=headers)

print(response.text)

2. 使用DuckDuckGo官方API(最推荐)

直接爬HTML页面本质上是"逆向"面向用户的界面,很容易触发反爬。而DuckDuckGo提供了专门的程序化搜索API,稳定性高,还能返回结构化的JSON数据,完全不需要担心反爬问题。

示例代码:

import requests
from urllib.parse import quote

query = '"*example"'
url = f"https://api.duckduckgo.com/?q={quote(query)}&format=json&kl=us-en"

response = requests.get(url)
search_results = response.json()

# 查看核心搜索结果
print("摘要内容:", search_results.get("Abstract", "无摘要"))
print("相关主题:", [topic["Text"] for topic in search_results.get("RelatedTopics", [])])

这个API不需要复杂的请求头,返回的数据结构清晰,唯一的小缺点是结果数量可能比HTML页面少,但绝大多数场景下完全够用。

3. 确保URL编码的规范性

不要手动拼接URL中的查询字符串,一定要用标准的URL编码工具处理特殊字符。urllib.parse.quote()会自动处理双引号、星号这类字符,避免因为编码错误导致DuckDuckGo无法正确解析你的查询。

比如:

from urllib.parse import quote
query = '"*example"'
print(quote(query))  # 输出:%22%2Aexample%22

为什么浏览器能正常访问?

浏览器发起请求时会自动携带完整的请求头、会话Cookie,甚至会有一些浏览器特有的字段,DuckDuckGo会判定这是人类用户的正常操作;而Python requests默认的请求缺少这些关键信息,被反爬机制拦截后返回了伪装的"无结果"页面。

内容的提问来源于stack exchange,提问作者Jakob Greenfeld

火山引擎 最新活动