如何将Selenium-Webdriver爬虫API接入scrape.py并结合LangChain实现AI调用?代码调试求助
解决方案:调试Scrape.py并对接Selenium与LangChain
咱们一步步拆解你的问题,先修复scrape.py里的核心问题,再把它和LangChain做好对接,满足你抓取任意网站并生成标准化数据的需求:
一、修复Scrape.py的核心问题
你的现有代码只抓取了页面<p>标签的文本,导致后续的HTML提取、清理函数完全没发挥作用,还丢失了大量页面信息。另外固定时长的sleep也不够灵活,我帮你调整了核心逻辑,保留你原有的SSL配置:
import ssl ssl._create_default_https_context = ssl._create_unverified_context import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) from dotenv import load_dotenv from selenium.webdriver import Remote, ChromeOptions as Options from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection from os import environ from time import sleep from bs4 import BeautifulSoup import os import traceback load_dotenv() # 禁用SSL验证的自定义连接类 class NoSSLConnection(ChromiumRemoteConnection): def _get_connection_manager(self): return urllib3.PoolManager(cert_reqs='CERT_NONE') def scrape_website(website): print("启动Chrome浏览器...") AUTH = environ.get('AUTH', '**********') if not AUTH: raise Exception("缺少AUTH凭证") print('正在连接浏览器...') server_addr = f'https://{AUTH}@brd.superproxy.io:9515' connection = NoSSLConnection(server_addr, 'goog', 'chrome') driver = Remote(connection, options=Options()) def cdp(cmd, params={}): return driver.execute('executeCdpCommand', { 'cmd': cmd, 'params': params, })['value'] try: print('已连接!启动检查会话...') frames = cdp('Page.getFrameTree') frame_id = frames['frameTree']['frame']['id'] inspect = cdp('Page.inspect', {'frameId': frame_id}) print(f"检查会话:{inspect['url']}") sleep(2) # 缩短无意义的等待 print(f"正在导航至{website}...") driver.get(website) print('等待验证码解决...') result = driver.execute('executeCdpCommand', { 'cmd': 'Captcha.waitForSolve', 'params': {'detectTimeout': 10000}, }) print(f"验证码状态:{result['value']['status']}") # 优化:等待页面完全加载(替代固定sleep) driver.execute_script("return document.readyState === 'complete'") sleep(3) # 给动态内容留加载时间 print('正在抓取页面完整内容...') # 改为获取页面完整HTML,方便后续LLM处理 page_html = driver.page_source return page_html except Exception as e: print(f"抓取错误:{e}") traceback.print_exc() # 打印详细堆栈,方便调试 return "" finally: driver.quit() # ------------------------减少提交给LLM的字符数/批次以获取有效响应---------------------------------------- # 提取HTML主体内容的函数 def extract_body_content(html_content): if not html_content: return "" soup = BeautifulSoup(html_content, "html.parser") body_content = soup.body if body_content: return str(body_content) return "" # 清理提取的HTML主体内容的函数 def clean_body_content(body_content): if not body_content: return "" soup = BeautifulSoup(body_content, "html.parser") # 移除更多无关内容,减少噪声 for element in soup(["script", "style", "noscript", "iframe", "header", "footer"]): element.extract() cleaned_content = soup.get_text(separator="\n") cleaned_content = "\n".join( line.strip() for line in cleaned_content.splitlines() if line.strip() ) return cleaned_content # 优化:按段落拆分,避免硬截断句子影响LLM理解 def split_dom_content(dom_content, max_length = 6000): chunks = [] current_chunk = "" # 按空行分割段落,保证语义完整 for paragraph in dom_content.split("\n\n"): if len(current_chunk) + len(paragraph) + 2 <= max_length: # +2是换行符长度 current_chunk += paragraph + "\n\n" else: if current_chunk: chunks.append(current_chunk.strip()) current_chunk = paragraph + "\n\n" if current_chunk: chunks.append(current_chunk.strip()) return chunks
调整说明:
- 把原有的
<p>标签抓取改为获取完整页面HTML,让后续的清理、拆分函数真正发挥作用 - 替换固定
sleep(10)为更合理的等待逻辑:先等待页面readyState完成,再加短时间等待动态内容 - 清理函数中新增移除
header、footer等无关内容,减少LLM处理的噪声 - 优化拆分逻辑,按段落分割而非硬截断,避免语义断裂
- 新增堆栈打印,方便快速定位调试错误
二、对接Selenium爬虫与LangChain
现在爬虫能输出干净的分批次内容,接下来对接LangChain的AI调用,生成你需要的标准化CRM/竞品数据。这里以竞品数据为例,给出核心对接代码:
from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.chains import LLMChain # 初始化LLM(根据你的.env配置调整模型) llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-16k") # 定义标准化输出的Prompt(可替换为CRM数据的提取规则) prompt_template = ChatPromptTemplate.from_messages([ ("system", "你是专业的竞品分析专员,需要从给定内容中提取以下标准化竞品数据:品牌名称、核心产品、定价策略、目标用户群体、核心竞争优势。信息缺失时标注为'未提及'。"), ("user", "请处理以下网站内容:\n{content}") ]) # 创建处理链 chain = LLMChain(llm=llm, prompt=prompt_template) def process_with_langchain(scraped_content): # 1. 处理抓取到的HTML body_content = extract_body_content(scraped_content) cleaned_content = clean_body_content(body_content) if not cleaned_content: return "未抓取到有效内容" # 2. 拆分内容批次 content_chunks = split_dom_content(cleaned_content) # 3. 逐批次处理并收集结果 batch_results = [] for i, chunk in enumerate(content_chunks): print(f"处理第{i+1}批次内容...") response = chain.run(content=chunk) batch_results.append(response) # 4. 合并批次结果,生成统一标准化报告 merge_prompt = ChatPromptTemplate.from_messages([ ("system", "请把以下多批次的分析结果整合成一份格式统一、无重复的标准化竞品报告。"), ("user", "多批次结果:\n{results}") ]) merge_chain = LLMChain(llm=llm, prompt=merge_prompt) final_result = merge_chain.run(results="\n\n".join(batch_results)) return final_result # 调用示例 if __name__ == "__main__": target_website = "https://example.com" # 替换为你要抓取的网站 scraped_html = scrape_website(target_website) standardized_data = process_with_langchain(scraped_html) print("标准化竞品数据:\n", standardized_data)
对接说明:
- 先将爬虫输出的HTML处理为干净文本,再拆分适配LLM的token限制
- 用自定义Prompt约束AI输出格式,确保生成的是你需要的标准化数据
- 多批次处理后再做一次整合,避免结果碎片化
三、调试关键提示
- 参考代码差异处理:如果Claude给的参考代码用了本地浏览器而非远程代理,你可以保留自己的
NoSSLConnection类,只替换抓取逻辑部分,不用全盘替换 - Token适配:如果使用小模型(如gpt-3.5-turbo),可将
max_length调整为4000左右,确保每个批次的token数在模型限制内 - 错误定位:如果爬虫持续报错,重点检查AUTH凭证是否有效、远程代理连接是否正常
内容的提问来源于stack exchange,提问作者KLJOM
相关产品推荐
相关产品推荐

