如何抓取 ChatGPT:输入提示,获取回复
你可能听说过用 ChatGPT 来抓取互联网内容。但如何抓取 LLM 本身呢?当然,你不可能直接入侵服务器,然后把它“大脑”里的东西都扒出来。但你可以抓取 ChatGPT 对你输出的回复。事实上,你可以自动化整个过程——包括输入提示。我们准备了两种方法,帮你轻松实现这一点。
为什么要抓取 ChatGPT 的回复?
你叔叔之所以信任 ChatGPT 的数据,是因为谷歌为了让搜索功能获得更多收益而做出的各种改动,让谷歌变得越来越令人厌烦。但 ChatGPT 提供的信息确实很有意思。你可以尝试抓取人工智能对以下问题的回答:
- 追踪您在 ChatGPT 中的提及: 过去,您的在线曝光度很大程度上取决于谷歌搜索结果页面 (SERP)。但随着用户转向 ChatGPT 进行搜索,这种情况正在迅速改变。现在,要了解您的产品排名如何,您需要了解 ChatGPT 认为它排名如何。通过程序化抓取 ChatGPT,您可以快速测试其在各种与您实际情况相关的提示中的排名。
- 密切关注竞争对手: 你的产品并非唯一出现在 ChatGPT 上的产品——如果真是如此,你也不会读到这篇文章了。但通过抓取 ChatGPT 上关于你所在领域或特定竞争产品的回答,你可以深入了解竞争对手为了出现在 AI 回复中而使用的策略。
- 针对人工智能进行优化: SEO就像解读鸟的内脏:查看搜索结果页面(SERP),比较排名靠前的内容和排名靠后的内容。ChatGPT的原理与之类似。大规模抓取这类数据能让你更清楚地了解你的产品或服务需要做些什么才能在人工智能眼中获得更高的排名。
- 形状人工智能训练: 也许你有一个本地模型需要维护?通过建立自动化的 GPT 回复抓取流程,你可以快速将其回复与 ChatGPT 的输出进行比较,并迅速发现问题所在。
方法一:从零开始构建 ChatGPT 爬虫
本方法将向您展示如何从零开始构建一个简单的 ChatGPT 爬虫。它使用了一个 无头浏览器 (很遗憾,这是必要的)打开一个未登录的页面,输入提示,并以 Markdown 格式下载输出。
为了抓取 ChatGPT 的回复,我们将使用 Python。我们的示例假设您的系统上已经安装了 Python。
整个过程将在命令行中完成。对于 Windows 用户来说,命令行界面通常被称为…… CMD(命令提示符)对于 Mac 或 Linux 用户来说,这将是 终端.
预赛
我们的脚本需要以下库和工具才能运行:
- 迷彩狐狸: 一款基于 Firefox 的开源反检测浏览器。
- Markdownify: 将输出转换为 Markdown 格式的工具。
- 代理: 它们是可选的。但如果您计划扩大网络爬虫的规模,则需要它们。 代理服务器 避免受到速率限制。
发现顶级代理服务提供商——经过彻底的测试和排名,以帮助您选择。
要安装 Camoufox,请先打开命令行。然后:
- 对于 Windows 系统,请输入以下命令:
camoufox fetch
- 对于 Mac 用户,请输入以下命令:
python3 -m camoufox fetch
- 对于 Linux 系统,请输入以下命令:
python -m camoufox fetch
- 对于全新安装的 Linux 系统,您可能还需要安装以下依赖项。
- 在基于 Debian 的发行版上:
sudo apt install -y libgtk-3-0 libx11-xcb1 libasound2
- 在基于 Arch 的发行版上:
sudo pacman -S gtk3 libx11 libxcb cairo libasound alsa-lib
要安装 Markdownify,请打开命令行。然后输入:
pip install markdownify
代码整合
看完完整的 Python 代码示例后,你应该将其下载并保存为 chatgpt_scraper.py.
首先,我们导入要使用的工具:Camoufox、Markdownify 和日志记录功能。我们还设置了…… 询问 将会输入到 ChatGPT 中。
from camoufox.sync_api import Camoufox
from markdownify import markdownify
import logging
query = "What are the top three dog breeds?"
此 输出文件 该行代码指定了包含抓取响应的文本文件的名称。多次运行代码会覆盖此文件,因此请务必保存所有需要保留的数据。
output_file = "output_md.txt"
这些行分别用于输入代理服务器的 URL、代理用户名和密码。
我们还设置了 60 秒的超时限制。
proxy_server = "XXX"
proxy_uname = "YYY"
proxy_pass = "ZZZ"
timeout = 60_000
以下定义了 CSS 选择器,从页面 URL 开始。这些选择器将用于检测文本输入窗口、提交查询的按钮以及显示响应结果的部分。
url = "https://chatgpt.com/"
selector_textarea = "div#prompt-textarea"
selector_submit = "button#composer-submit-button"
selector_response = "div.markdown"
我们还设置了日志记录——如果在抓取过程中出现任何问题,这将有助于我们找出原因。
logging.basicConfig(filename="chatgpt_scraper.log", level=logging.DEBUG)
logger = logging.getLogger(__name__)
这里是访问 ChatGPT、抓取页面并返回结果的代码。首先,我们尝试访问该页面,并设置日志消息以防访问失败。
def scrape(url: str, page: Camoufox) -> None:
try:
response = page.goto(
url,
wait_until="domcontentloaded",
timeout=timeout)
if response and not response.ok:
logger.warning(f"Page returned status code: {response.status}")
现在,代码使用我们定义的选择器:
- 在 ChatGPT 窗口中找到文本输入框。
- 填写查询语句。
- 找到提交按钮。
- 单击按钮。
- 等待回应。
- 查找并提取响应。
此外,系统还会生成相应的消息通知您任何故障情况。
textarea_elem = page.locator(selector_textarea)
if not textarea_elem:
raise Exception("Textarea element not found.")
textarea_elem.fill(query)
submit_button = page.locator(selector_submit)
if not submit_button:
raise Exception("Submit button not found")
submit_button.click()
page.wait_for_load_state("networkidle", timeout=timeout)
response_elem = page.locator(selector_response)
if not response_elem:
raise Exception(f"Response element with selector '{selector_response}' not found")
response_text = response_elem.text_content()
接下来,我们将抓取的数据设置为输出,然后将其转换为 Markdown 格式并保存为文件。此外,我们还设置了相应的错误日志记录。
print ("Output: ")
print (response_text)
response_md = markdownify(response_elem.inner_html())
print ("Markdown:")
print (response_md)
if not response_text:
logger.warning("Response element is empty")
write_output(response_md)
except Exception as e:
logger.error(f"Scrape failed: {str(e)}", exc_info=True)
最后,这是Camoufox的运行配置。代理登录功能就是在这里实际使用的。
此 无头 = 真 这行代码设置 Camoufox 以无头模式运行。你可以将其设置为 假 如果你想亲眼看看它的实际效果。
def main() -> None:
with Camoufox(geoip=True,
proxy={
"server": proxy_server,
"username": proxy_uname,
"password": proxy_pass,
},
headless = True,
) as browser:
page = browser.new_page()
scrape(url, page)
browser.close()
if __name__ == "__main__":
main()
完成的代码示例
综上所述,抓取 ChatGPT 回复的完整代码如下所示。请记住将其保存为 chatgpt_scraper.py.
from camoufox.sync_api import Camoufox
from markdownify import markdownify
import logging
query = "What are the top three dog breeds?"
output_file = "output_md.txt"
proxy_server = "XXX"
proxy_uname = "YYY"
proxy_pass = "ZZZ"
timeout = 60_000
url = "https://chatgpt.com/"
selector_textarea = "div#prompt-textarea"
selector_submit = "button#composer-submit-button"
selector_response = "div.markdown"
logging.basicConfig(filename="chatgpt_scraper.log", level=logging.DEBUG)
logger = logging.getLogger(__name__)
def write_output(response_md: str) -> None:
try:
with open (output_file, "w") as f:
f.write(response_md)
except Exception as e:
logger.error(f"Write failed. Error: {str(e)}", exc_info=True)
def scrape(url: str, page: Camoufox) -> None:
try:
response = page.goto(
url,
wait_until="domcontentloaded",
timeout=timeout)
if response and not response.ok:
logger.warning(f"Page returned status code: {response.status}")
textarea_elem = page.locator(selector_textarea)
if not textarea_elem:
raise Exception("Textarea element not found.")
textarea_elem.fill(query)
submit_button = page.locator(selector_submit)
if not submit_button:
raise Exception("Submit button not found")
submit_button.click()
page.wait_for_load_state("networkidle", timeout=timeout)
response_elem = page.locator(selector_response)
if not response_elem:
raise Exception(f"Response element with selector '{selector_response}' not found")
response_text = response_elem.text_content()
print ("Output: ")
print (response_text)
response_md = markdownify(response_elem.inner_html())
print ("Markdown:")
print (response_md)
if not response_text:
logger.warning("Response element is empty")
write_output(response_md)
except Exception as e:
logger.error(f"Scrape failed: {str(e)}", exc_info=True)
def main() -> None:
# Setting up basic camoufox, no need for anything fancy to unblock ChatGPT yet.
# https://camoufox.com/python/usage/
# Setting it up with a rotating proxy
with Camoufox(geoip=True,
proxy={
"server": proxy_server,
"username": proxy_uname,
"password": proxy_pass,
},
headless = True, #False to see the browser in operation.
) as browser:
page = browser.new_page()
# Beggining the scrape in the scrape() function
scrape(url, page)
# Closing the browser
browser.close()
if __name__ == "__main__":
main()
编写自己的爬虫的优缺点
这就是编写 ChatGPT 回复爬虫代码的方法。但是,这种方法并非唯一,而且也并非完美无缺。
| 优点 | 缺点 |
| 低廉: 如果你懂编程,那它基本上就是免费的。 | 准入门槛高: 并非人人都会编程,而且掌握编程也并非易事。尽管LLM非常有用,但对于大规模应用而言,它们仍然不够完善。 |
| 无尽的定制: 再说一遍,如果你懂编程,你就可以把你的爬虫程序设计成你想要的任何样子。 | 可扩展性低: 你需要为每个想要抓取数据的网站编写一个抓取程序,这是一项艰巨的任务。 |
| 完全控制: 当你掌控代码时,你就不再受制于编写代码的人。 | 访问限制: 如今的网站可以包含各种各样的 机器人防护措施,例如 Cloudflare 还有登录墙。你需要自己想办法绕过它们。 |
| 反应速度: 一旦出现任何问题,您都可以立即对您的爬虫程序进行故障排除。 | 维护如果目标发生变化导致脚本出错,那么修复脚本的任务就落在你身上了。 |
方法二:使用商业爬虫抓取 ChatGPT
当然,只要有点胆量和编程技能,你完全可以自己抓取 ChatGPT 的内容。但是,你仍然需要代理服务器,以及绕过 Cloudflare 和其他 ChatGPT 可能设置的限制。 这并非一项简单的任务。
另一种方法是使用现成的网络爬虫API。正如我们在对比表中所述,编写自己的代码有很多缺点,而现成的爬虫程序则不存在这些问题。
为了说明这一点,我将使用 Decodo毕竟,在我们测试ChatGPT抓取工具时,该提供商的表现确实非常出色,取得了一些最佳结果。 我们针对 2025 年网络爬虫 API 报告测试了该服务。它还为此目标提供了一个专用 API,简化了设置过程。
使用商用刮刀的好处
- 易于设置: 我们的示例设置描述了进入 但是 只需在命令行输入几行代码,一切就绪。但实际情况可能并非如此——即使在 Mac 系统上,安装 Camoufox 也可能遇到问题。另一方面,预先编写好的爬虫程序接受简单的标准化 API 调用。此外,它们还附带一个可立即访问的测试环境,用于生成代码和提取响应(尽管规模有限)。
- 内置选项: 许多产品允许您自定义位置、设备,以及是否允许 ChatGPT 使用网络搜索。它们还支持多种输出格式,包括 JSON、Markdown、XHR 或纯 HTML。
- 更具可扩展性: 该爬虫程序会自动处理无头浏览器、反机器人系统和代理服务器。您只需负责发送 API 调用和存储结果即可。
如何使用商业版 ChatGPT 爬虫工具
1. 创建账户 以及 订阅 至 Decodo.
2. 前往爬虫 API 测试环境,您可以在那里调整爬虫设置:
- 输入提示(我重复使用了“排名前三的犬种是什么?”);
- 选择输出格式(本例中为 Markdown);
- 打开或关闭 ChatGPT 的网页搜索功能;
- 设置地理位置和设备类型。
点击 右,您可以切换格式选项卡 Python 立即获取代码。
3. 您现在可以点击 咨询我们 看看代码是否有效 复制代码 开始将其用于您自己的用途。
4. 将代码粘贴到文字处理软件中,并以 .py 扩展名保存。我将其命名为“chatgpt_scraper.py”,就像第一个示例中一样。
5。 打开 命令行工具导航至文件所在位置,然后输入 python3 chatgpt_scraper.py > response.txt.
- 附加的 > response.txt 每次运行代码时,都会在同一文件夹中创建 response.txt 文件,并将抓取的响应保存到该文件中。
- 绝大部分储备使用 >> response.txt 如果你希望每次运行代码时都更新文件而不是覆盖它。
完整代码示例
以下是我们在代码编写示例中使用的相同提示符的代码示例——不包括我们的授权数据:
import requests
url = "https://scraper-api.decodo.com/v2/scrape"
payload = {
"target": "chatgpt",
"prompt": "What are the top three dog breeds?",
"search": True,
"markdown": True
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "XXX"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)