Your Airdrop

Posted on May 03, 2023Read on Mirror.xyz

撸毛GPT Alpha

众所周知,去年我做了不少精品撸毛教程,跟着我做的推友们应该都收获了不少op arb safe id等等。

做教程对我来说已经没什么乐趣和吸引力了,最近一个月我一直在专研一个更新的玩法——撸毛GPT

撸毛GPT会撸到电子羊吗

与现在市面上仅仅是用ai做几个脚本不同,我认为撸毛不应该只有交互,而是一整套从浏览、筛选项目开始,到寻找最佳交互路径最后才是执行交互的流程。过去我已经总结了一套十分有效的人工撸毛方法,从今年开始我会努力将这套方法智能化,用ai大幅提升效率和精准度,让我们的撸毛跃上新的台阶。

目前这个方法还在开发阶段,暂且称为撸毛GPT Alpha好了。

正文开始前,先做一个预警,这篇文章对于没代码基础的人可能会有点难,但是不用怕,坑我已经都帮你们踩过一遍了,认真做完,你的收获会远大于付出。

一、选择大于努力

虽然arb空投后,大家都在讨论执行力不够的问题。但是在我看来,执行力不够的主要原因应该是对项目认知的严重不足——如果你现在得知一个确定的消息,有一个项目现在参与每个钱包能赚5000u,还会存在执行力不够的问题吗?

选择和研究的过程远大于努力,只有在大脑中深度认可了某一个项目的潜在价值,才会有足够的动力和执行力去完成接下来的交互。

但是我们每天接触的项目这么多,如何确定哪些项目值得撸呢?看KOL瞎分析一通?还是相信、锻炼自己的能力?我的选择是DYOR--do your own research。

因此我把撸毛分为以下几个步骤:

1.研究、选择项目

2.研究交互路径

3.执行交互

以上三个步骤都可以通过ai大幅提升效率,在这篇文章中,我要介绍的是第一步——研究、选择项目,这一项工作的代号暂且叫做“撸毛GPT Phase 1 Alpha”,Phase 1指的是撸毛GPT的第一步--分析,alpha指的是项目的进展。

为了提升深度了解项目的效率,我在过去一个月的时间里完成了一套半自动的投研ai系统,可以帮助大家快速、深度地了解一个项目,经过我一段时间的试用,毫不夸张地说,看项目的效率至少缩短了5倍。

二、撸毛GPT Phase 1 Alpha原理简介

我把研究一个项目大体分为研究官网、blog、推特、相关人员推个及重要采访。对于一个融资上亿的大体量项目来说,在过去这至少需要花费十几个小时才能完成。ChatGPT出来后,我找到了一些更为高效的研究方案:

1、通过python爬虫获取以上提到的绝大部分信息并整合成一个PDF文件。

2、通过ChatPDF一类的工具让ai提取出我们需要的资料。

3、通过询问融资信息、项目方重点工作、未来规划、如何去中心化、空投等问题获取关键信息。

4、最后对项目是否值得参与做出自己的判断。

以上这些工作的原理很简单,通过python爬虫获取信息,然后使用chatpdf分析这些海量的数据。目前这些工作的进展都比较慢,所以大家看到的是一个半自动化的ai分析程序。

下面我会逐项分享分解这些工作。

三、工作分解

1.前期准备——ChatGPT、AutoGPT、ChatPDF和Python爬虫

对于许多人来说,编程是一个难以逾越的门槛,但是我想告诉大家,在此之前我也是一个只会写hello world的连门都没入的菜鸟,感谢ChatGPT,让我们这些麻瓜有了跨入另一个世界的可能性。现在,你只需要指挥ChatGPT就能完成绝大多数的工作。下面先对我们要使用的一些工具作简要的介绍:

ChatGPT的注册方法很多地方都介绍过了,这里就不再多说了。如果对我接下里的介绍不太理解或执行不了的时候,请直接咨询ChatGPT,他是一个比任何人都更耐心的绝佳助手。

注册后通过下面链接拿到GPT的api,以后很多地方都能用得着。

https://platform.openai.com/account/api-keys

AutoGPT是自动化的GPT工具,ChatGPT只能一问一答地与人交互,有大神开发了AutoGPT,只要设定一个合适的命令,就可以使用ChatGPT的API自己完成一个项目的研究,如图所示。

agentgpt.reworkd.ai 对venom分析的部分截图

rewokd是AutoGPT的网页版,目前还有一些不足,可以用作快速了解项目或者查漏补缺。

https://agentgpt.reworkd.ai/

ChatPDF则是一个基于chatgpt为pdf文档特化的一个应用,可以分析上传的文档并让用户以提问的形式回答文档中的内容,是一个非常方便的助手。

https://www.chatpdf.com/

ChatGPT和ChatPDF都十分建议购买付费版,一个月总共只需要25刀,就能获得最强的ai助手。

在爬取各种资料之前,我们首先需要安装python和python相关的库。

首先新建一个文件夹用于运行脚本的文件夹,比如”d:\lumaoGPT”。然后在下面的官网链接安装python。

python的命令有两个不同版本,分别是”python”和”python3”,取决于你安装的版本,下面都是以python3为例的。

https://www.python.org/downloads/

Python准备好后,我们还最好是使用一个编程工具,微软的Visual Studio Code很方便,对新人也挺友好的。

https://code.visualstudio.com/Download

下面我们会以最近比较火的中东土豪项目venom为例,介绍如何用撸毛gpt详细了解这个项目。

2.获取用户推文

接下来我们先做一件简单的事,爬取官方推特的资料。因为这件事有第三方的组织在做,所以暂时不需要使用爬虫。

https://www.vicinitas.io/free-tools/download-user-tweets

通过以上链接打开vicinitas的推特工具,输入venom的官推@VenomFoundation后点击search,vicinitas会爬取最近3200条推文,随后我们点击输出到excel保存下载,在之前建立好的文件夹(d:\lumaoGPT)中新建一个叫做”excel”的文件夹并把所有excel文件放进来。

用同样的方法把venom官推关注的另一个官推@VenomDev @Venom_network_ @VenomVentures 和创始人@MustafaKheriba 全部扒拉下来,放入excel文件夹。

下面我们通过一个python脚本把这些文件合并成一个pdf。

首先打开命令行工具,windows下按下win+r,输入cmd回车。mac中直接在运用程序里面找到终端并运行。然后进入lumaogpt的文件夹,运行以下指令安装相关的库文件

pip install pandas openpyxl reportlab

安装的同时,可以使用代码工具(比如vs code)或者记事本粘贴以下代码,文件名可以叫做mergeexcel.py(也可以是其他文件名,但后缀必须是.py)

import os
import glob
import re
import pandas as pd
import html
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.pagesizes import A3  # 导入A3页面大小

def txt_files_to_pdf(txt_files, pdf_file):
    doc = SimpleDocTemplate(pdf_file, pagesize=A3)  # 将页面大小更改为A3
    styles = getSampleStyleSheet()
    data_style = ParagraphStyle('Data', parent=styles['Normal'], fontName='Helvetica', fontSize=10)
    story = []
    for txt_file in txt_files:
        with open(txt_file, 'r', encoding='utf-8') as f:
            for line in f:
                clean_line = html.escape(line.strip())
                clean_line = re.sub('<[^<]+?>', '', clean_line)
                story.append(Paragraph(clean_line, data_style))
                story.append(Spacer(1, 5))
    doc.build(story)


def excel_to_txt(excel_file, txt_file, columns_to_keep=6):
    df = pd.read_excel(excel_file, engine='openpyxl')
    with open(txt_file, 'w', encoding='utf-8') as f:
        for _, row in df.iterrows():
            f.write(','.join([str(e) for e in row[:columns_to_keep]]) + '\n')


if __name__ == '__main__':
    input_folder = 'excel'  # 请将此路径替换为你的Excel文件所在的文件夹
    output_folder = 'excel'  # 请将此路径替换为你希望输出TXT和PDF文件的文件夹

    excel_files = glob.glob(os.path.join(input_folder, '*.xlsx'))
    txt_files = []

    for excel_file in excel_files:
        txt_file = os.path.join(output_folder, os.path.splitext(os.path.basename(excel_file))[0] + '.txt')
        excel_to_txt(excel_file, txt_file, columns_to_keep=6)
        txt_files.append(txt_file)

    pdf_file = os.path.join(output_folder, 'exceloutput.pdf')
    txt_files_to_pdf(txt_files, pdf_file)

    print(f'成功将 {len(txt_files)} 个TXT文件合并为PDF文件: {pdf_file}')

下载下来的excel文件如果直接转换成pdf的话,chatpdf会难以识别,这个脚本会把然后我们的excel首先转换成文本文件,再转换为pdf。

在命令行中运行python3 mergeexcel.py后会在excel文件夹获得一个叫做exceloutput.pdf的文件。

现在我们可以牛刀小试,看看爬虫的效果如何。打开chatpdf,上传我们合并后的pdf文件,然后可以让gpt机器人来综合分析我们的文件了,下面发个截图给大家展示一下效果。

3.获取官网、blog及相关内容

除了推特外,官网和blog是获取项目信息的重要渠道。官方blog往往会记录一些重大事件,许多项目的代币计划是在blog中被大家发现的,也有一些重要信息会隐藏在招聘文案中。所以我通过ChatGPT生成了一个抓取指定网页的脚本,可以获取任意指定网页的内容。

首先安装以下whhtmltopdf工具和一些pythone库

https://wkhtmltopdf.org/downloads.html

pip install requests PyPDF2 xhtml2pdf beautifulsoup4

然后制作以下脚本,我们将其命名为mergewebpage.py

import asyncio
from pathlib import Path
from PyPDF2 import PdfMerger, PdfReader
from xhtml2pdf import pisa
import requests
from io import BytesIO
from bs4 import BeautifulSoup

proxy = 'http://127.0.0.1:9090'
proxies = {
    'http': proxy,
    'https': proxy,
}

async def generate_pdf(url: str, output_path: Path, options: dict = None):
    """使用xhtml2pdf抓取指定的url并生成pdf文件"""
    loop = asyncio.get_event_loop()
    response = await loop.run_in_executor(None, requests.get, url, {'proxies': proxies})
    if response.status_code == 200:
        html = response.text
        soup = BeautifulSoup(html, 'lxml')
        for style_tag in soup.find_all('style'):
            style_tag.decompose()
        clean_html = str(soup)
        with open(output_path, 'wb') as f:
            pisa.CreatePDF(BytesIO(clean_html.encode()), f)
        print(f"Successfully saved {url} to {output_path.as_posix()}")
    else:
        print(f"Failed to fetch {url}")


async def main():
    urls = [
        'https://medium.com/@venom.foundation/venom-testnet-experience-a-robust-dapp-ecosystem-built-on-a-multi-blockchain-network-6b5aff35d49d?source=user_profile---------0----------------------------',
        'https://medium.com/@venom.foundation/understanding-the-venom-whitepaper-the-next-generation-blockchain-f85735a0d03d?source=user_profile---------1----------------------------',
        'https://medium.com/@venom.foundation/venom-february-2023-recap-building-bridges-with-strategic-partners-e31aee7c0c9a?source=user_profile---------2----------------------------',
        'https://medium.com/@venom.foundation/venom-foundation-and-hub71-partner-to-accelerate-growth-and-adoption-of-blockchain-technologies-cefc686928b?source=user_profile---------3----------------------------',
        'https://medium.com/@venom.foundation/what-are-testnets-and-how-do-they-work-42d93f392760?source=user_profile---------4----------------------------',
        'https://medium.com/@venom.foundation/venom-blockchain-partners-with-dao-maker-431bcd4b2728?source=user_profile---------5----------------------------',
        'https://medium.com/@venom.foundation/venom-architecture-90cffa66dc53?source=user_profile---------6----------------------------',
        'https://medium.com/@venom.foundation/venom-community-competition-17dbf03a1769?source=user_profile---------7----------------------------',
        'https://medium.com/@venom.foundation/what-is-asynchronous-blockchain-technology-3bf19617177a?source=user_profile---------8----------------------------',
        'https://medium.com/@venom.foundation/venom-introduction-ee65451015a2?source=user_profile---------9----------------------------',
        'https://medium.com/@venom.foundation/mportant-venom-foundation-does-not-distribute-venom-utility-tokens-prior-to-the-official-launch-b3ffe84326f9?source=user_profile---------10----------------------------',
        'https://medium.com/@venom.foundation/adgms-venom-foundation-and-dgc-sign-a-cybersecurity-cooperation-agreement-5ab3b82eef12?source=user_profile---------11----------------------------',
        'https://medium.com/@venom.foundation/venom-foundation-the-first-crypto-foundation-licensed-in-uaes-adgm-to-build-an-infinitely-52173892a9e8?source=user_profile---------12----------------------------'



    ]
    tasks = []
    pdf_folder = Path('pdfs')
    # 创建pdfs文件夹
    pdf_folder.mkdir(exist_ok=True)
    for i, url in enumerate(urls):
        # 为每个url创建一个Task
        task = asyncio.create_task(generate_pdf(url, pdf_folder / f'{i}.pdf'))
        tasks.append(task)
    # 等待所有Task完成
    await asyncio.gather(*tasks)

    # 合并所有的pdf文件
    merger = PdfMerger()
    pdf_files = sorted(list(pdf_folder.glob('*.pdf')))
    for pdf_file in pdf_files:
        with open(pdf_file, 'rb') as f:
            merger.append(PdfReader(f))

    # 保存合并后的pdf文件
    merged_pdf_file = pdf_folder / 'merged_web_pages.pdf'
    with open(merged_pdf_file, 'wb') as f:
        merger.write(f)

    print(f"Successfully saved merged pdf to {merged_pdf_file.as_posix()}")

if __name__ == '__main__':
    asyncio.run(main())

由于我们在内地,有些时候不能正常访问medium,所以加了一段使用vpn的代码

proxy = 'http://127.0.0.1:9090'
proxies = {
    'http': proxy,
    'https': proxy,
}

clashx的vpn地址

如图所示,每个vpn软件会有所不同,将自己的vpn代理地址粘贴到上面proxy的字段中就可以让python正常访问网络了。

我们把要抓取的链接放入下面代码段urls里面,主要用英文引号和逗号,最后一个链接不需要逗号。

async def main():
    urls = [
        'aa.com',
        'bb.xyz',
        'cc.io'
      
    ]

然后运行"python3 mergewebpage.py",会在pdfs文件夹里获得一个名为merged_web_pages.pdf的文件。

4.获取其他第三方网页

只有推特和官网不足以获取一个项目完整的画像,我们还需要更多的信息,比如在谷歌中搜索interview venom foundation,获得相关的采访。

以下是谷歌搜索的爬虫制作方法。

首先,完成以下准备工作:

1. 创建一个Google API Console项目:访问 Google API Console,创建一个新项目。

在搜索框中搜索并打开"Custom Search API",然后点击启用

2. 获取API密钥:在启用API后,转到“凭据”选项卡,创建API密钥。

记住复制密钥

3.创建一个属于自己的谷歌搜索:访问 Google自定义搜索引擎 页面,创建一个自定义搜索引擎。获取您的搜索引擎ID(cx)。

将js?cx=后面被我马赛克的内容复制下来,这个是你的引擎id

现在编辑一个名为”scrgoogle.py”的脚本。

import os
import requests
from xhtml2pdf import pisa
from PyPDF2 import PdfMerger
from concurrent.futures import ThreadPoolExecutor
from bs4 import BeautifulSoup

API_KEY = 'yourkey'
SEARCH_ENGINE_ID = 'yourid'
QUERY = 'search what'
proxy = 'http://127.0.0.1:9090'
proxies = {
    'http': proxy,
    'https': proxy,
}


def get_search_results(api_key, search_engine_id, query, start):
    url = f"https://www.googleapis.com/customsearch/v1?key={api_key}&cx={search_engine_id}&q={query}&start={start}"
    response = requests.get(url)
    return response.json()

def convert_html_to_pdf(html, output_filename):
    with open(output_filename, 'wb') as output_file:
        pisa_status = pisa.CreatePDF(html, dest=output_file)
    return not pisa_status.err

def download_html(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    response = requests.get(url, headers=headers)
    return response.text

def get_links_from_results(results):
    links = []
    for item in results['items']:
        links.append(item['link'])
    return links

def process_link(index, link):
    try:
        html_content = download_html(link)
        soup = BeautifulSoup(html_content, 'lxml')
        for style_tag in soup.find_all('style'):
            style_tag.decompose()
        clean_html = str(soup)
        pdf_filename = os.path.join(output_folder, f"output_{index}.pdf")
        if convert_html_to_pdf(clean_html, pdf_filename):
            print(f"PDF file '{pdf_filename}' created successfully for link: {link}")
            return pdf_filename
        else:
            print(f"An error occurred while generating the PDF file for link: {link}")
    except Exception as e:
        print(f"An error occurred while processing link: {link}. Error: {e}")


# Get search results
first_page_results = get_search_results(API_KEY, SEARCH_ENGINE_ID, QUERY, 1)
second_page_results = get_search_results(API_KEY, SEARCH_ENGINE_ID, QUERY, 11)

# Get links from search results
first_page_links = get_links_from_results(first_page_results)
second_page_links = get_links_from_results(second_page_results)
all_links = first_page_links + second_page_links

# Create 'google' folder if it doesn't exist
output_folder = 'google'
if not os.path.exists(output_folder):
    os.makedirs(output_folder)

# Download HTML, convert to PDF, and save PDF files in parallel
pdf_files = []
with ThreadPoolExecutor() as executor:
    futures = [executor.submit(process_link, index, link) for index, link in enumerate(all_links)]
    for future in futures:
        result = future.result()
        if result:
            pdf_files.append(result)

# Merge PDF files
merger = PdfMerger()
for pdf_file in pdf_files:
    merger.append(pdf_file)

merged_output_file = os.path.join(output_folder, 'googleoutput.pdf')
merger.write(merged_output_file)
merger.close()

print(f"All PDF files have been merged into '{merged_output_file}'")

# Clean up individual PDF files
for pdf_file in pdf_files:
    os.remove(pdf_file)

由于不同网页的格式略有不同,所以无法保证所有的网页都能被这个脚本转为pdf,有些可能会因为无法识别导致费时过长,所以这个脚本需要等待一段时间才能完成。

我们将api_key替换为刚才记下的api_key,search_engine_id也替换为刚才记下的字段,search_query即为我们要搜索的内容,此处可以根据自己的需要调整。

运行python3 scrgoogle.py,获得谷歌前2页的搜索结果。

5.合并PDF

目前为止,我们获得了推特、官网、谷歌三个渠道的pdf文件,现在我们可以把这些文件合并成一个pdf并交给chatpdf来分析。以往这个工作至少会花费我一整天的时间,有了这个半自动的撸毛GPT,至少节省了70%的时间。

下面是合并的脚本:

import PyPDF2
import os

# 将多个PDF文件合并为单个文件
def merge_pdfs(pdf_list, output_file):
    merger = PyPDF2.PdfMerger()
    for pdf in pdf_list:
        merger.append(pdf)
    merger.write(output_file)
    merger.close()

# 将PDF文件按页数分割为多个文件
def split_pdf_by_page(input_file, max_words_per_page):
    pdf_reader = PyPDF2.PdfReader(input_file)

    for page_num in range(len(pdf_reader.pages)):

        output_file = 'output_' + str(page_num + 1) + '.pdf'
        pdf_writer = PyPDF2.PdfWriter()
        page_obj = pdf_reader.pages[page_num]

        page_text = page_obj.extract_text()

        words_count = len(page_text.split())

        if words_count <= max_words_per_page:
            pdf_writer.add_page(page_obj)
            with open(output_file, 'wb') as f:
                pdf_writer.write(f)
        else:
            split_page_count = int(words_count / max_words_per_page) + 1
            start_idx = 0
            for i in range(split_page_count):
                end_idx = (i+1)*max_words_per_page
                if end_idx > words_count:
                    end_idx = words_count
                new_page_text = ' '.join(page_text.split()[start_idx:end_idx])
                new_page_obj = PyPDF2.pdf.PageObject.createBlankPage(None, page_obj.mediaBox.getWidth(), page_obj.mediaBox.getHeight())
                new_page_obj.mergePage(page_obj)
                new_page_obj.compressContentStreams()
                new_page_obj._data = new_page_obj._data.replace('/Parent 1 0 R', '') # 解决不同PDF阅读器显示的问题
                pdf_writer.add_page(new_page_obj)
                start_idx = end_idx

            with open(output_file, 'wb') as f:
                pdf_writer.write(f)

# 压缩PDF文件
def compress_pdf(input_file, output_file):
    pdf_reader = PyPDF2.PdfReader(input_file)
    pdf_writer = PyPDF2.PdfWriter()

    for page_num in range(len(pdf_reader.pages)):
        page_obj = pdf_reader.pages[page_num]
        pdf_writer.add_page(page_obj)
        pdf_writer._sweep_indirect_references(pdf_writer._root_object)
    with open(output_file, 'wb') as f:
        pdf_writer.write(f)


# 合并多个PDF文件
pdf_list = ['exceloutputput.pdf', 'googleoutput.pdf', 'merged_web_pages.pdf']
merged_file = 'merged_file.pdf'
merge_pdfs(pdf_list, merged_file)

我们把要合并的文件都放进脚本所在的文件夹,pdf_list中的是要合并的文件,合并后我们会得到一个名为merged_file.pdf的文件,上传到chatpdf后,我们来看看效果如何。

四、结语

到此为止,我们撸毛GPT Phase1 Alpha就算完成了。目前主要还有以下几个缺点:

1.没有ui,还是半自动阶段。我的设想中,未来应该会做出一个自动化的操作界面。

2.阅读PDF的GPT工具能力有限,我花了大量的时间使用了包括chatpdf,chatdoc,gpt4-pdf-chatbot-langchain,bhaskatripathi在内的各类工具,目前最好用的chatpdf能力也十分有限,期待未来会有更好用更适合币圈的pdf阅读工具。

今年除了撸毛以外,我还希望继续把剩下两个阶段的撸毛GPT给做完,到时候再给大家汇报进展。

fly to da moon

0基础写代码不易,如果觉得这篇文章对你有帮助,就来mint一下吧