用Selenium实现一个免费的Web搜索API服务
- 一、引言:为什么我们需要这个工具?
- 二、核心思路:模拟人类,获取数据
- 三、分步实现
- 1、搭建搜索服务端(`server.py`)
- 2、创建客户端(`client.py`)
- 四、如何运行?
- 1. 启动服务端
- 2. 测试客户端
- 五、实际应用:集成到AI智能体
- 示例:在LangChain中使用
- 五、结语
一、引言:为什么我们需要这个工具?
在AI智能体(Agents)飞速发展的今天,让它们能够“联网思考”已成为刚需。想象一下,你的AI助手不仅能回答训练数据中的问题,还能实时获取最新的新闻、股价、科研成果——这就像给盲人恢复了视力。
然而,现实很骨感:主流的搜索API服务(如Google Search API、Bing Search API等)往往需要付费注册,有的还有严格的调用限制。对于个人开发者、学生或小型项目来说,这些门槛可能让人望而却步。
本文将介绍如何利用Selenium(一个流行的浏览器自动化工具)搭建一个完全免费的Web搜索API服务,让你的AI智能体也能轻松获取实时网络信息。
二、核心思路:模拟人类,获取数据
我们的解决方案基于一个简单而有效的想法:如果AI不能直接调用搜索API,那我们就让它“像人一样使用浏览器”。
具体流程如下:
- 使用Selenium启动一个“隐形”的浏览器(无头模式)
- 访问Bing的Copilot搜索页面
- 从页面中提取、整理搜索结果
- 通过一个简单的Web API将结果返回给调用者
这种方法绕过了官方API的限制,直接与搜索引擎的公开界面交互,实现了“曲线救国”。
环境搭建参考
三、分步实现
1、搭建搜索服务端(server.py)
服务端的核心是一个Flask Web应用,它接收搜索请求,用Selenium执行搜索,然后返回结果。
importdatetimefromtqdmimporttqdmimportosimporttimeimportjsonimportrefromseleniumimportwebdriverfromselenium.webdriver.support.waitimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECfromselenium.webdriver.common.byimportByfromselenium.webdriver.chrome.optionsimportOptionsimporturllib.parsefromflaskimportFlask,jsonify,requestfromflask_corsimportCORSimporttraceback app=Flask(__name__)CORS(app)# 允许跨域请求# 设置Chrome选项chrome_options=Options()chrome_options.add_argument('--headless')# 无头模式,可选chrome_options.add_argument('--disable-gpu')# 禁用GPU加速chrome_options.add_argument('--no-sandbox')chrome_options.add_argument('--enable-features=AllowSoftwareGLFallbackDueToCrashes,AllowSwiftShaderFallback')chrome_options.add_argument('--enable-unsafe-swiftshader')chrome_options.add_argument('--disable-dev-shm-usage')chrome_options.add_argument('--disable-blink-features=AutomationControlled')chrome_options.add_experimental_option("excludeSwitches",["enable-automation"])chrome_options.add_experimental_option('useAutomationExtension',False)chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')chrome_options.add_argument('--disable-extensions')# 禁用扩展chrome_options.add_argument('--disable-infobars')# 禁用信息栏prefs={'profile.managed_default_content_settings.images':2,# 2 表示禁止加载图片}chrome_options.add_experimental_option('prefs',prefs)defget_result(wait,driver):combined_texts=[]combined_text=""# Bing的搜索结果放在iframe中,需要切换进去driver.switch_to.default_content()iframes=driver.find_elements(By.TAG_NAME,"iframe")try:fori,iframeinenumerate(iframes):src=iframe.get_attribute('src')ifsrc.startswith("https://www.bing.com/search"):driver.switch_to.frame(iframe)wait.until(EC.presence_of_all_elements_located((By.XPATH,"//div[contains(@class, 'answer_container')]")))answer_elements=driver.find_elements(By.XPATH,"//div[contains(@class, 'answer_container')]")ifanswer_elements:forelementinanswer_elements:span_elements=element.find_elements(By.TAG_NAME,"span")ifspan_elements:span_texts=[span.textforspaninspan_elementsifspan.text.strip()]combined_text='\n'.join(span_texts)combined_texts.append(combined_text)combined_text="\n".join(combined_texts).replace("查看所有链接","")except:passreturncombined_textdefsearch_impl(key_world="介绍一下中国的首都"):driver=webdriver.Chrome(options=chrome_options)wait=WebDriverWait(driver,5)key_world_url_encoded=urllib.parse.quote(key_world)url=f"https://www.bing.com/copilotsearch?q={key_world_url_encoded}"t0=time.time()driver.delete_all_cookies()driver.get(url)foriinrange(30):combined_text=get_result(wait,driver)print(len(combined_text))iflen(combined_text)>4:breaktime.sleep(1)t1=time.time()output_data={"success":True,"message":combined_text,"query":key_world,"duration":t1-t0,"url":driver.current_url,"page_title":driver.title}driver.quit()returnoutput_data@app.route("/search",methods=["POST"])defsearch():try:data=request.get_json()ifnotdata:returnjsonify({"success":False,"message":"params invalid"}),400key_world=data.get("query")body=search_impl(key_world)returnjsonify(body),200exceptExceptionase:traceback.print_exc()returnjsonify({"success":False,"message":f"服务器内部错误:{str(e)}"}),500if__name__=="__main__":app.run(host="0.0.0.0",port=5000,debug=True)为什么要用无头模式?
- 服务器通常没有图形界面
- 减少资源消耗,运行更高效
- 避免弹出浏览器窗口干扰其他进程
为什么需要等待机制?
- 网络速度和服务器响应时间不确定
- 页面元素需要时间加载完成
- 避免在内容加载前就尝试提取(会导致空结果)
2、创建客户端(client.py)
客户端是一个简单的Python脚本,用于测试我们的搜索服务。
importrequestsimportjsondefsend_search_request(query,timeout=30):""" 发送搜索请求 Args: query: 查询字符串 timeout: 超时时间(秒) Returns: 响应结果或错误信息 """url="http://localhost:5000/search"try:response=requests.post(url,json={"query":query},headers={"Content-Type":"application/json"},timeout=timeout)response.raise_for_status()# 如果状态码不是200,抛出异常# 尝试解析JSON响应try:returnresponse.json()exceptjson.JSONDecodeError:return{"text":response.text,"status_code":response.status_code}exceptrequests.exceptions.Timeout:return{"error":"请求超时"}exceptrequests.exceptions.ConnectionError:return{"error":"连接失败,请检查服务是否启动"}exceptrequests.exceptions.RequestExceptionase:return{"error":f"请求异常:{str(e)}"}# 使用示例if__name__=="__main__":result=send_search_request("获取最新的AI咨询")print(json.dumps(result,indent=2,ensure_ascii=False))四、如何运行?
1. 启动服务端
打开终端,运行:
python server.py如果一切正常,你会看到类似下面的输出:
* Serving Flask app 'server' * Debug mode: on * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://[你的IP地址]:50002. 测试客户端
在另一个终端中,运行:
python client.py输出
{"duration":4.231590747833252,"message":"。GPT Image 1.5 在图像生成中实现详细特征保留与光线精准渲染\n。GPT\nImage\n1.5\n在图像生成中实现详细特征保留与光线精准渲染\n。\nAnthropic Claude系列:发布Claude Opus 4.6与Claude Cowork,支持百万token上下文、代码编译及零日漏洞自发现能力\nAnthropic\nClaude系列\n:发布Claude\nOpus\n4.6与Claude\nCowork,支持百万token上下文、代码编译及零日漏洞自发现能力\n。\n通义千问 Qwen 系列:开源 Qwen3-TTS、Qwen3-Coder-Next、Qwen3-VL-Embedding,覆盖语音生成、编程与多模态检索场景\n通义千问\nQwen\n系列\n:开源\nQwen3-TTS、Qwen3-Coder-Next、Qwen3-VL-Embedding,覆盖语音生成、编程与多模态检索场景\n。\n多模态与视频AI:可灵AI 3.0和2.6版本实现音画同步、自动分镜控制,PixVerse V5.5可在几秒内生成导演级多镜头短片\n多模态与视频AI\n:可灵AI\n3.0和2.6版本实现音画同步、自动分镜控制,PixVerse\nV5.5可在几秒内生成导演级多镜头短片\n。美团LongCat系列与Vidi2显著提升视频编辑和理解能力\n。美团LongCat系列与Vidi2显著提升视频编辑和理解能力\n。\n端侧与嵌入式AI:MiniMax、智谱GLM系列、阿里通义Fun-Audio-Chat、腾讯混元3D Studio 支持本地计算,提升端侧推理效率,支持音乐、语音、文本、图像等多模态任务\n端侧与嵌入式AI\n:MiniMax、智谱GLM系列、阿里通义Fun-Audio-Chat、腾讯混元3D\nStudio\n支持本地计算,提升端侧推理效率,支持音乐、语音、文本、图像等多模态任务\n。\n行业企业与融资动态\n港股上市与融资:MiniMax、智谱AI纷纷启动或完成港股IPO,融资数额达数十亿港元,推动全球化布局与算力扩展\n港股上市与融资\n:MiniMax、智谱AI纷纷启动或完成港股IPO,融资数额达数十亿港元,推动全球化布局与算力扩展\n。\nAI创业与投资:xAI完成200亿美元E轮融资,Meta、迪士尼、亚马逊、英伟达等加码投入AI应用及硬件\nAI创业与投资\n:xAI完成200亿美元E轮融资,Meta、迪士尼、亚马逊、英伟达等加码投入AI应用及硬件\n。国内新型AI公司如DeepWisdom、Vidu、Kimi、Luma AI、RockFlow等也完成战略融资\n。国内新型AI公司如DeepWisdom、Vidu、Kimi、Luma\nAI、RockFlow等也完成战略融资\n。\n开源社区发展:面壁智能、Mistral AI、阿里Qwen、谷歌Gemini 3 Flash等项目开源,推动算法、模型和工具的全民可用性\n开源社区发展\n:面壁智能、Mistral\nAI、阿里Qwen、谷歌Gemini\n3\nFlash等项目开源,推动算法、模型和工具的全民可用性\n。\nAI应用趋势\n办公与生产力:AgentOS、扣子2.0、MiniMax Agent 2.0、ChatExcel等智能体平台,实现办公自动化、代码协作和科研辅助\n办公与生产力\n:AgentOS、扣子2.0、MiniMax\nAgent\n2.0、ChatExcel等智能体平台,实现办公自动化、代码协作和科研辅助\n。\n多模态交互与智能助手:蚂蚁“灵光”、京东AI购、Meta WorldGen、OpenAI购物研究等,推动AI在现实生活场景的便利化应用\n多模态交互与智能助手\n:蚂蚁“灵光”、京东AI购、Meta\nWorldGen、OpenAI购物研究等,推动AI在现实生活场景的便利化应用\n。\n个性化与自动化生成:AI视频、音乐、图像、3D内容生成实现自动化与定制化生产,支持多语言、角色扮演及场景复现\n个性化与自动化生成\n:AI视频、音乐、图像、3D内容生成实现自动化与定制化生产,支持多语言、角色扮演及场景复现\n。\n推荐获取平台\nAI工具集:实时更新产业新闻、融资动态、产品发布,覆盖多模态、智能体及工具类AI应用\nAI工具集\n:实时更新产业新闻、融资动态、产品发布,覆盖多模态、智能体及工具类AI应用\n。\nAIbase.cn:每日AI日报、热点资讯及产品数据库,内容专业全面\nAIbase.cn\n:每日AI日报、热点资讯及产品数据库,内容专业全面\n。\nAI日报:每天3分钟掌握最新AI模型、行业动态及前沿技术\nAI日报\n:每天3分钟掌握最新AI模型、行业动态及前沿技术\n。\n用户可根据兴趣选择平台,结合社群或订阅功能获取\n实时资讯与深度分析\n。这些平台适用于技术研究、行业分析、投资决策及产品应用探索。","page_title":"获取最新的AI咨询","query":"获取最新的AI咨询","success":true,"url":"https://www.bing.com/copilotsearch?q=%E8%8E%B7%E5%8F%96%E6%9C%80%E6%96%B0%E7%9A%84AI%E5%92%A8%E8%AF%A2"}五、实际应用:集成到AI智能体
现在你有了一个可用的搜索API,可以轻松地将它集成到各种AI框架中:
示例:在LangChain中使用
fromlangchain.toolsimportTooldefsearch_tool(query:str)->str:"""调用我们的本地搜索服务"""result=send_search_request(query)ifresult.get("success"):returnresult.get("message","未找到相关信息")returnf"搜索失败:{result.get('error','未知错误')}"# 创建工具实例search_tool_instance=Tool(name="Web搜索",func=search_tool,description="用于搜索最新的网络信息")# 将工具添加到你的AI智能体中五、结语
通过这个项目,你不仅获得了一个免费的搜索API,更重要的是理解了如何通过自动化工具解决实际开发中的限制。这种"模拟用户行为"的思路可以应用于许多其他场景,如自动化测试、数据采集、监控报警等。
技术的本质是创造可能性。当现有方案受限时,像这样创造性地组合工具,往往能开辟出新的道路。
提示:请合理使用此工具,尊重目标网站的robots.txt协议,避免给服务器造成过大压力。本文仅供学习交流使用。