ChatGPT+Google Colab批量抓取NBER工作论文(0基础+代码+Prompt)

img

作者: 张家星
邮箱: zhangjx@stu.zuel.edu.cn

本推文提供

  • 批量抓取NBER工作论文信息的Python代码
  • 获得正确代码的ChatGPT Prompt过程
  • 本文适用于完全不会爬虫的新手
    • 无需下载Python
    • 手动更改0行代码
    • 云端迅速得到结果
  • 抛砖引玉,欢迎讨论!

【本文内容较多,可以参照目录选择性阅读】

目录

  • \1. 目的
  • \2. 工具
    • 2.1 ChatGPT
    • 2.2 Google Colab
    • 2.3 GPT+Colab
  • \3. 代码
    • 3.1完整代码
    • 3.2代码详解
  • \4. Prompt 全过程
  • 写在后面

1. 目的

NBER Working Paper是由美国国家经济研究局(NBER)发布的一系列学术论文,旨在分享和讨论经济学领域中的前沿研究成果。

本篇推文的目的是【批量抓取NBER工作论文中的题目、作者、摘要等信息】

未来有待完善之处

  1. 通过调用开源大模型,抓取后直接翻译为中文,并形成markdown格式文件,方便形成公众号推文。
  2. 同时下载好pdf格式的论文
  3. 只下载本周最新的论文
  4. 进一步研究Google Colab平台

2. 工具

2.1 ChatGPT

前段时间是 ChatGPT 发布两周年,相信大家对它已经十分熟悉,因此这里不再赘述。

2.2 Google Colab

Google Colab(全称 Google Colaboratory)是由 Google 提供的一种基于云端的 Jupyter Notebook 环境,允许用户编写和执行 Python 代码。

Colab 提供免费的计算资源(包括 GPU 和 TPU),使得数据科学、机器学习和深度学习等计算密集型任务更加容易进行。它支持直接从 Google Drive 导入和存储文件,方便用户管理数据。

Colab 主要特点包括

  • 无需配置环境:用户可以直接在浏览器中使用,免去安装和配置的烦恼。
  • 免费的计算资源:提供 GPU 和 TPU 支持,适合需要高性能计算的项目。
  • 云端存储与共享:与 Google Drive 集成,支持文档和项目的轻松共享和协作。
  • 支持 Python 和常见库:内置了大量 Python 库,特别适合数据分析、机器学习等任务。
  • 代码执行与可视化:支持实时执行代码,并将结果以图形、表格等形式直观展示。

2.3 GPT+Colab

本文通过在 ChatGPT 中提问获取爬虫代码,并将其复制到 Colab 中执行。

实际上谷歌浏览器有个ChatGPT for Google Colab插件,感兴趣的可以下载尝试。

3. 代码

先看一下最终得到的文件,4S下载了50篇论文的信息。

img

3.1完整代码

无需配置本地 Python 环境,直接将下面的代码,复制到 Google Colab 的笔记本中,运行代码即可。(截至2024年12月4日13:28:06,亲测可用)

如果想要理解代码逻辑,请看3.2代码详解

img

# python

import requests
from bs4 import BeautifulSoup
import csv
import time
from tqdm import tqdm
import os
import re
import logging
from concurrent.futures import ThreadPoolExecutor, as_completed

# 如果在Google Colab中运行,使用以下模块下载文件
from google.colab import files

# 设置日志配置
logging.basicConfig(filename='nber_scraper.log', level=logging.INFO,
                    format='%(asctime)s:%(levelname)s:%(message)s')

def extract_author_names(authors_html):
    """
    从包含HTML <a> 标签的作者列表中提取纯文本的作者姓名。
    """
    authors = []
    for author_html in authors_html:
        soup = BeautifulSoup(author_html, 'html.parser')
        author_name = soup.get_text(strip=True)
        authors.append(author_name)
    return authors if authors else ['None']

def normalize_punctuation(text):
    """
    将智能标点转换为标准标点。
    """
    # 将智能引号转换为标准引号
    text = re.sub(r'[“”]', '"', text)
    text = re.sub(r"[‘’]", "'", text)
    # 将其他特殊标点转换为标准标点
    text = re.sub(r'–|—', '-', text)
    # 处理其他可能的乱码字符,如"鈥"
    text = text.replace('鈥', '"').replace('鈥', '"').replace('鈥', '"')  # 根据需要添加更多替换规则
    return text

def fetch_nber_working_papers(page=1, per_page=50, sort_by='public_date'):
    """
    从NBER API获取工作论文,并提取标题、作者、发布日期、URL。
    """
    api_url = 'https://www.nber.org/api/v1/working_page_listing/contentType/working_paper/_/_/search'
    params = {
        'page': page,
        'perPage': per_page,
        'sortBy': sort_by
    }

    response = requests.get(api_url, params=params)

    if response.status_code == 200:
        data = response.json()
        papers = data.get('results', [])

        extracted_papers = []

        for paper in papers:
            title = paper.get('title', 'No Title')

            # 提取作者姓名
            authors_html = paper.get('authors', [])
            authors = extract_author_names(authors_html)

            # 使用 displaydate 作为发布日期
            display_date = paper.get('displaydate', 'None')

            # 构建完整的论文URL
            paper_url = f"https://www.nber.org{paper.get('url', '')}"

            extracted_papers.append({
                'title': title,
                'authors': authors,
                'publication_date': display_date,
                'url': paper_url
            })

        return extracted_papers
    else:
        logging.error(f"请求失败,状态码: {response.status_code}")
        return []

def fetch_full_details(paper_url):
    """
    使用requests和BeautifulSoup提取摘要、Working Paper编号和DOI。
    """
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)\
             Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(paper_url, headers=headers, timeout=10)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')

            # 定位摘要所在的div
            intro_div = soup.find('div', class_='page-header__intro-inner')
            abstract = 'None'
            if intro_div:
                abstract_p = intro_div.find('p')
                if abstract_p:
                    abstract = abstract_p.get_text(separator=' ', strip=True)
                    abstract = normalize_punctuation(abstract)

            # 定位citation信息
            citation_div = soup.find('div', class_='page-header__citation-info')
            working_paper_number = 'None'
            doi = 'None'
            if citation_div:
                citation_items = citation_div.find_all('div', class_='page-header__citation-item')
                for item in citation_items:
                    label = item.find('span', class_='page-header__citation-item-label')
                    if label:
                        label_text = label.get_text(strip=True)
                        if label_text == 'Working Paper':
                            working_paper_number = item.get_text(strip=True).replace('Working Paper', '').strip()
                        elif label_text == 'DOI':
                            doi = item.get_text(strip=True).replace('DOI', '').strip()

            logging.info(f"成功获取论文详细信息: {paper_url}")
            return {
                'abstract': abstract,
                'working_paper_number': working_paper_number,
                'doi': doi
            }

        else:
            logging.error(f"无法访问论文页面,状态码: {response.status_code},URL: {paper_url}")
            return {'abstract': 'None', 'working_paper_number': 'None', 'doi': 'None'}
    except Exception as e:
        logging.error(f"在获取详细信息时发生错误: {e},URL: {paper_url}")
        return {'abstract': 'None', 'working_paper_number': 'None', 'doi': 'None'}

def fetch_all_details_concurrently(papers):
    """
    使用多线程并发获取所有论文的详细信息。
    """
    with ThreadPoolExecutor(max_workers=10) as executor:
        futures = {executor.submit(fetch_full_details, paper['url']): paper for paper in papers}
        for future in tqdm(as_completed(futures), total=len(futures), desc="并发获取详细信息"):
            paper = futures[future]
            try:
                details = future.result()
                paper['abstract'] = details['abstract']
                paper['working_paper_number'] = details['working_paper_number']
                paper['doi'] = details['doi']
            except Exception as e:
                logging.error(f"在获取论文详细信息时出错: {e},URL: {paper['url']}")
                paper['abstract'] = 'None'
                paper['working_paper_number'] = 'None'
                paper['doi'] = 'None'

def save_to_csv(papers, filename='nber_working_papers_full.csv'):
    """
    将提取的论文信息保存到CSV文件中,并在Google Colab中下载。
    """
    # 定义CSV列的顺序
    fieldnames = ['Working Paper Number', 'Publication Date', 'Title', 'Authors', 'Full Abstract', 'DOI', 'URL']

    # 定义保存路径为 /content 目录(Google Colab环境)
    save_path = os.path.join('/content', filename)

    print(f"准备保存 {len(papers)} 篇论文到 CSV 文件: {save_path}")

    with open(save_path, mode='w', encoding='utf-8-sig', newline='') as file:
        writer = csv.DictWriter(file, fieldnames=fieldnames)
        writer.writeheader()
        for paper in papers:
            writer.writerow({
                'Working Paper Number': paper.get('working_paper_number', 'None'),
                'Publication Date': paper['publication_date'],
                'Title': paper['title'],
                'Authors': ', '.join(paper['authors']),
                'Full Abstract': paper.get('abstract', 'None'),
                'DOI': paper.get('doi', 'None'),
                'URL': paper['url']
            })
            # 可选:打印已保存的论文标题
            print(f"已保存论文: {paper['title']}")

    print(f"数据已保存到 {save_path}")

    # 在Google Colab中下载文件
    try:
        files.download(save_path)
        print(f"文件 {filename} 已下载到本地。")
    except Exception as e:
        print(f"下载文件时出错: {e}")

def main():
    # 打印当前工作目录
    print(f"当前工作目录: {os.getcwd()}")

    # 设置要获取的页数和每页的论文数量
    total_pages = 1  # 示例:获取第一页
    per_page = 50

    all_papers = []

    for page in range(1, total_pages + 1):
        print(f"获取第 {page} 页的论文信息...")
        papers = fetch_nber_working_papers(page=page, per_page=per_page, sort_by='public_date')
        all_papers.extend(papers)
        time.sleep(1)  # 为了避免过于频繁的请求,暂停1秒

    print(f"共获取到 {len(all_papers)} 篇论文的信息。")

    # 使用多线程并发获取详细信息
    print("开始并发获取每篇论文的详细信息...")
    fetch_all_details_concurrently(all_papers)

    # 保存到CSV文件并下载
    save_to_csv(all_papers)

if __name__ == "__main__":
    main()

3.2代码详解

本节根据ChatGPT o1-preview 的回答,提供全部代码解释。

1. 导入必要的模块

# python
import requests
from bs4 import BeautifulSoup
import csv
import time
from tqdm import tqdm
import os
import re
import logging
from concurrent.futures import ThreadPoolExecutor, as_completed  # 修改导入语句

# 如果在Google Colab中运行,使用以下模块下载文件
from google.colab import files

模块解释:

  • requests:用于发送HTTP请求,从NBER API和论文网页获取数据。
  • BeautifulSoup (bs4):用于解析HTML内容,从网页中提取所需的信息。
  • csv:用于将提取的数据写入CSV文件。
  • time:用于控制请求之间的延时,防止过于频繁的请求。
  • tqdm:用于显示进度条,跟踪长时间运行的操作的进度。
  • os:用于处理文件路径和操作系统相关的功能。
  • re:用于正则表达式操作,处理文本中的特殊字符。
  • logging:用于记录脚本运行过程中的信息、错误和警告,便于调试和维护。
  • concurrent.futures.ThreadPoolExecutor, as_completed:用于实现多线程并发请求,提高数据抓取的效率。
  • google.colab.files:专门用于在Google Colab环境中下载生成的文件到本地计算机。

2. 设置日志配置

# 设置日志配置
logging.basicConfig(filename='nber_scraper.log', level=logging.INFO,
                    format='%(asctime)s:%(levelname)s:%(message)s')

**目的:**记录脚本运行过程中发生的事件和错误,便于后续分析和调试。

  • logging.basicConfig:配置日志记录的基本设置。
    • filename='nber_scraper.log':将日志信息写入名为nber_scraper.log的文件中。
    • level=logging.INFO:设置日志级别为INFO,记录INFO及以上级别的信息(如WARNING、ERROR等)。
    • format='%(asctime)s:%(levelname)s:%(message)s':定义日志信息的格式,包括时间戳、日志级别和消息内容。

3. 定义函数:extract_author_names

def extract_author_names(authors_html):
    """
    从包含HTML <a> 标签的作者列表中提取纯文本的作者姓名。
    """
    authors = []
    for author_html in authors_html:
        soup = BeautifulSoup(author_html, 'html.parser')
        author_name = soup.get_text(strip=True)
        authors.append(author_name)
    return authors if authors else ['None']

目的:将HTML格式的作者信息转换为纯文本,便于后续处理和保存。

  • 输入参数:authors_html,包含多个HTML 标签的作者信息。
  • 遍历每个作者的HTML片段。
  • 使用BeautifulSoup解析HTML,提取纯文本的作者姓名。
  • 将提取的作者姓名添加到authors列表中。
  • 返回值:返回包含所有作者姓名的列表;如果没有作者信息,则返回[‘None’]。

4. 定义函数:normalize_punctuation

def normalize_punctuation(text):
    """
    将智能标点转换为标准标点。
    """
    # 将智能引号转换为标准引号
    text = re.sub(r'[“”]', '"', text)
    text = re.sub(r"[‘’]", "'", text)
    # 将其他特殊标点转换为标准标点
    text = re.sub(r'–|—', '-', text)
    # 处理其他可能的乱码字符,如"鈥"
    text = text.replace('鈥', '"').replace('鈥', '"').replace('鈥', '"')  # 根据需要添加更多替换规则
    return text

目的: 确保文本中的标点符号统一,避免在保存到CSV或显示时出现乱码问题。

  • 输入参数:text,包含可能的智能标点或乱码字符的文本。

5. 定义函数:fetch_nber_working_papers

def fetch_nber_working_papers(page=1, per_page=50, sort_by='public_date'):
    """
    从NBER API获取工作论文,并提取标题、作者、发布日期、URL。
    """
    api_url = 'https://www.nber.org/api/v1/working_page_listing/contentType/working_paper/_/_/search'
    params = {
        'page': page,
        'perPage': per_page,
        'sortBy': sort_by
    }

    response = requests.get(api_url, params=params)

    if response.status_code == 200:
        data = response.json()
        papers = data.get('results', [])

        extracted_papers = []

        for paper in papers:
            title = paper.get('title', 'No Title')

            # 提取作者姓名
            authors_html = paper.get('authors', [])
            authors = extract_author_names(authors_html)

            # 使用 displaydate 作为发布日期
            display_date = paper.get('displaydate', 'None')

            # 构建完整的论文URL
            paper_url = f"https://www.nber.org{paper.get('url', '')}"

            extracted_papers.append({
                'title': title,
                'authors': authors,
                'publication_date': display_date,
                'url': paper_url
            })

        return extracted_papers
    else:
        logging.error(f"请求失败,状态码: {response.status_code}")
        return []

目的: 通过NBER的API获取工作论文的基本信息,为后续提取更详细的信息(如摘要、DOI等)做准备。

  • 输入参数:
    • page:要获取的页面编号,默认为1。
    • per_page:每页显示的论文数量,默认为50。
    • sort_by:排序方式,默认为按public_date(发布日期)排序。
  • 构建API请求:
    • api_url:NBER API的URL,用于获取工作论文列表。
    • params:请求参数,包括页面编号、每页数量和排序方式。
  • 发送HTTP GET请求:
    • 使用requests.get发送请求,传递URL和参数。
  • 处理响应:
    • 如果响应状态码为200(成功),则解析JSON响应。
    • 从JSON数据中提取results,即论文列表。
  • 提取所需信息:
    • 遍历每篇论文,提取标题、作者、发布日期和URL。
    • 使用extract_author_names函数提取作者姓名。
    • 构建完整的论文URL(因为API返回的URL可能是相对路径)。
    • 将提取的信息添加到extracted_papers列表中。
  • 返回结果:
    • 返回包含所有提取论文信息的列表。
    • 如果请求失败,记录错误并返回空列表。

6. 定义函数:fetch_full_details

def fetch_full_details(paper_url):
    """
    使用requests和BeautifulSoup提取摘要、Working Paper编号和DOI。
    """
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)\
             Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(paper_url, headers=headers, timeout=10)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')

            # 定位摘要所在的div
            intro_div = soup.find('div', class_='page-header__intro-inner')
            abstract = 'None'
            if intro_div:
                abstract_p = intro_div.find('p')
                if abstract_p:
                    abstract = abstract_p.get_text(separator=' ', strip=True)
                    abstract = normalize_punctuation(abstract)

            # 定位citation信息
            citation_div = soup.find('div', class_='page-header__citation-info')
            working_paper_number = 'None'
            doi = 'None'
            if citation_div:
                citation_items = citation_div.find_all('div', class_='page-header__citation-item')
                for item in citation_items:
                    label = item.find('span', class_='page-header__citation-item-label')
                    if label:
                        label_text = label.get_text(strip=True)
                        if label_text == 'Working Paper':
                            working_paper_number = item.get_text(strip=True).replace('Working Paper', '').strip()
                        elif label_text == 'DOI':
                            doi = item.get_text(strip=True).replace('DOI', '').strip()

            logging.info(f"成功获取论文详细信息: {paper_url}")
            return {
                'abstract': abstract,
                'working_paper_number': working_paper_number,
                'doi': doi
            }

        else:
            logging.error(f"无法访问论文页面,状态码: {response.status_code},URL: {paper_url}")
            return {'abstract': 'None', 'working_paper_number': 'None', 'doi': 'None'}
    except Exception as e:
        logging.error(f"在获取详细信息时发生错误: {e},URL: {paper_url}")
        return {'abstract': 'None', 'working_paper_number': 'None', 'doi': 'None'}

目的: 从每篇论文的详细页面中提取更具体的信息(摘要、工作论文编号、DOI),补充之前通过API获取的基本信息

  • 输入参数:paper_url,单篇论文的详细页面URL。

  • 功能:

  • 发送HTTP GET请求:

    • 使用requests.get发送请求,附带自定义的User-Agent头,以模拟真实的浏览器请求,避免被网站拒绝。
    • 设置timeout=10,即请求超时时间为10秒,防止长时间等待。
  • 处理响应:

    • 如果响应状态码为200(成功),则解析HTML内容。
  • 提取摘要:

    • 使用BeautifulSoup查找包含摘要的``,其类名为page-header__intro-inner
    • 在该内找到标签,提取文本内容。
    • 使用normalize_punctuation函数标准化标点符号,避免乱码。
  • 提取工作论文编号和DOI:

    • Working Paper:提取工作论文编号。

    • DOI:提取DOI号。

    • 查找包含引用信息的``,类名为page-header__citation-info

    • 在该内找到所有子,类名为page-header__citation-item

    • 遍历每个子,根据标签(的文本)确定提取内容:

  • 记录日志:

    • 成功提取后,记录成功信息。
    • 如果请求失败或解析错误,记录错误信息。
  • 返回结果:

    • 返回包含摘要、工作论文编号和DOI的字典。
    • 如果提取失败,返回默认值’None’。

7. 定义函数:fetch_all_details_concurrently

def fetch_all_details_concurrently(papers):
    """
    使用多线程并发获取所有论文的详细信息。
    """
    with ThreadPoolExecutor(max_workers=10) as executor:
        futures = {executor.submit(fetch_full_details, paper['url']): paper for paper in papers}
        for future in tqdm(as_completed(futures), total=len(futures), desc="并发获取详细信息"):
            paper = futures[future]
            try:
                details = future.result()
                paper['abstract'] = details['abstract']
                paper['working_paper_number'] = details['working_paper_number']
                paper['doi'] = details['doi']
            except Exception as e:
                logging.error(f"在获取论文详细信息时出错: {e},URL: {paper['url']}")
                paper['abstract'] = 'None'
                paper['working_paper_number'] = 'None'
                paper['doi'] = 'None'

目的: 并发地提取所有论文的详细信息,显著提升抓取效率。

  • 输入参数:papers,包含基本信息的论文列表,每篇论文是一个字典,包含标题、作者、发布日期和URL。
  • 功能:
  • 创建线程池:
    • 使用ThreadPoolExecutor创建一个包含10个线程的线程池,max_workers=10。
    • 原因:多线程允许同时发送多个HTTP请求,提高数据抓取的效率,显著减少总运行时间。
  • 提交任务:
    • 遍历每篇论文,使用executor.submit提交fetch_full_details函数的任务,传入论文的URL。
    • 创建一个字典futures,键为未来(future)对象,值为对应的论文字典。
  • 处理完成的任务:
    • 使用tqdmas_completed函数,遍历已完成的未来对象,显示进度条。
    • 对于每个已完成的任务:
    • 获取对应的论文字典。
    • 调用future.result()获取提取的详细信息。
    • 更新论文字典,添加摘要、工作论文编号和DOI。
    • 错误处理:如果在获取详细信息时发生异常,记录错误并将相关字段设为None

8. 定义函数:save_to_csv

def save_to_csv(papers, filename='nber_working_papers_full.csv'):
    """
    将提取的论文信息保存到CSV文件中,并在Google Colab中下载。
    """
    # 定义CSV列的顺序
    fieldnames = ['Working Paper Number', 'Publication Date', 'Title', 'Authors', 'Full Abstract', 'DOI', 'URL']

    # 定义保存路径为 /content 目录(Google Colab环境)
    save_path = os.path.join('/content', filename)

    print(f"准备保存 {len(papers)} 篇论文到 CSV 文件: {save_path}")

    with open(save_path, mode='w', encoding='utf-8-sig', newline='') as file:
        writer = csv.DictWriter(file, fieldnames=fieldnames)
        writer.writeheader()
        for paper in papers:
            writer.writerow({
                'Working Paper Number': paper.get('working_paper_number', 'None'),
                'Publication Date': paper['publication_date'],
                'Title': paper['title'],
                'Authors': ', '.join(paper['authors']),
                'Full Abstract': paper.get('abstract', 'None'),
                'DOI': paper.get('doi', 'None'),
                'URL': paper['url']
            })
            # 可选:打印已保存的论文标题
            print(f"已保存论文: {paper['title']}")

    print(f"数据已保存到 {save_path}")

    # 在Google Colab中下载文件
    try:
        files.download(save_path)
        print(f"文件 {filename} 已下载到本地。")
    except Exception as e:
        print(f"下载文件时出错: {e}")

目的: 将所有提取的论文信息按照指定的列顺序保存到CSV文件中,并在Google Colab环境中自动下载该文件,便于后续分析和使用。

  • 输入参数:

    • papers:包含所有论文信息的列表,每篇论文是一个字典。
    • filename:保存的CSV文件名,默认为nber_working_papers_full.csv
  • 功能:

  • 定义CSV列的顺序:

    • Working Paper Number

    • Publication Date

    • Title

    • Authors

    • Full Abstract

    • DOI

    • URL

    • fieldnames列表按照用户指定的顺序排列:

  • 构建保存路径:

    • 使用os.path.join将目录/content与文件名组合,形成完整的保存路径save_path
    • 注意:/content是Google Colab的默认工作目录。
  • 打开CSV文件:

    • 使用open函数以写模式('w')打开文件,指定编码为utf-8-sig
    • utf-8-sig:在文件开头添加BOM(字节顺序标记),有助于某些软件(如Excel)正确识别UTF-8编码。
    • newline='':避免在写入CSV时出现多余的空行。
  • 写入CSV文件:

    • 使用paper.get('field', 'None')获取字段值,如果字段不存在则使用None作为默认值。

    • ', '.join(paper['authors']):将作者列表转换为以逗号分隔的字符串。

    • 创建csv.DictWriter对象,指定列名。

    • 写入表头(header)。

    • 遍历每篇论文,按照fieldnames顺序写入数据:

    • 打印保存信息:每保存一篇论文,打印一条消息,显示已保存的论文标题。

  • 下载CSV文件:

    • 使用google.colab.files.download方法在Google Colab中自动下载生成的CSV文件到本地计算机。
    • 错误处理:如果下载过程中发生错误,打印错误信息。

9. 定义函数:main

def main():
    # 打印当前工作目录
    print(f"当前工作目录: {os.getcwd()}")

    # 设置要获取的页数和每页的论文数量
    total_pages = 2  # 示例:获取第一页
    per_page = 50

    all_papers = []

    for page in range(1, total_pages + 1):
        print(f"获取第 {page} 页的论文信息...")
        papers = fetch_nber_working_papers(page=page, per_page=per_page, sort_by='public_date')
        all_papers.extend(papers)
        time.sleep(1)  # 为了避免过于频繁的请求,暂停1秒

    print(f"共获取到 {len(all_papers)} 篇论文的信息。")

    # 使用多线程并发获取详细信息
    print("开始并发获取每篇论文的详细信息...")
    fetch_all_details_concurrently(all_papers)

    # 保存到CSV文件并下载
    save_to_csv(all_papers)

目的:协调整个抓取流程,从获取基本信息到提取详细信息,再到保存和下载,确保流程高效、有序地完成。

  • 打印当前工作目录:

    • 使用os.getcwd()获取并打印当前的工作目录路径。
    • 目的:确认脚本的运行环境和文件保存位置。
  • 设置抓取参数:

    • total_pages = 2:设置要抓取的页数为2页(示例)。
    • per_page = 50:每页抓取50篇论文。
  • 抓取论文基本信息:

    • 打印当前抓取的页数。

    • 调用fetch_nber_working_papers函数抓取当前页的论文信息。

    • 将抓取到的论文信息添加到all_papers列表中。

    • 使用time.sleep(1)暂停1秒,防止过于频繁的请求导致被目标网站封禁。

    • 初始化空列表all_papers,用于存储所有论文的信息。

    • 使用for循环遍历每一页:

  • 打印抓取结果:

    • 打印总共抓取到的论文数量。
  • 并发获取详细信息:

    • 打印开始并发获取详细信息的消息。
    • 调用fetch_all_details_concurrently函数,使用多线程并发地抓取每篇论文的详细信息(摘要、工作论文编号、DOI)。
  • 保存并下载CSV文件:

    • 调用save_to_csv函数,将所有论文信息保存到CSV文件中,并在Google Colab中自动下载。

10. 主程序入口

if __name__ == "__main__":
    main()
  • 作用:
    • 当脚本作为主程序运行时(而不是被导入为模块),执行main()函数。
    • 这是Python中常见的惯用法,用于定义脚本的入口点,确保在直接运行脚本时执行特定的代码。

4. Prompt 全过程

授人以鱼,不如授人以渔。本节提供得到正确代码的全部 Prompt 过程,仅供参考。

Q1: 帮我爬取https://www.nber.org/papers?page=1&perPage=50&sortBy=public_date 这个网站里面所有文章的题目、作者、摘要等信息,并提供google colab 的代码

第一轮回复(ChatGPT 4o):您可以使用 Python 的 requests 库来获取网页内容,并使用 BeautifulSoup 解析 HTML。……

【我将提供的代码复制到 Google Colab 中,并未得到结果。】

Q2: 不好使呢

第二轮回复(ChatGPT 4o):抱歉,可能是因为页面的结构或者 JavaScript 渲染的问题。NBER 网站可能使用了 JavaScript 动态加载数据,而 requests 和 BeautifulSoup 只能解析静态页面,无法处理这些动态加载的内容。

一种有效的方式是使用 Selenium 来模拟浏览器行为,加载所有的 JavaScript 内容并抓取页面。这里是一个更新的示例,使用 Selenium 来爬取 NBER 网站上的文章信息。……

【但在几轮追问下,我仍然无法使用 Selenium 模拟浏览器抓取数据。】

值得注意的是,为了考验 ChatGPT 的能力,我并没有根据它提供的代码进行手动调整(实际是因为我根本不会),而是直接复制它提供的完整代码,在 Colab 中运行,看其能否提供想要的结果。

于是我选择最新的模型 ChatGPT o1-preview 进行追问。

Q3: https://www.nber.org/papers?page=1&perPage=50&sortBy=public_date 帮我把前5篇文章的题目、作者和摘要提取出来

第X轮回复(o1-preview): 思考持续5秒后,给我提供详细的步骤,包括安装必要的依赖项、配置Selenium并启动浏览器、编写爬虫代码以提取前5篇文章的信息等。

【但在几轮追问下,ChatGPT o1-preview 提供的代码仍然无法运行成功。】

或许是给它提供的信息有限?

Q4: 【此处为NBER的网站的源代码(右键查看网页源代码既可获得)】这是网页的源代码,应该如何爬取呢?

第X轮回复(o1-preview): 要爬取您提供的网页源代码中的数据,您需要了解网页内容是如何加载的。根据您提供的源代码,这个网页(NBER的“Working Papers”页面)可能使用动态加载的数据,例如通过API请求获取内容。这意味着直接从静态HTML中提取数据可能不够有效。因此,以下是一个系统化的步骤指南,帮助您有效地爬取所需的数据。

提供相关代码:步骤 1:了解网页结构和数据加载方式;步骤 2:检查API端点……

注意: 根据实际的API响应结构,您可能需要调整数据提取部分。

有些API端点可能需要身份验证或特定的请求头,请根据需要进行设置。

Q5: 示例:使用 requests 访问API,但是无法得到作者等。标题: FinTech Platforms and Asymmetric Network Effects: Theory and Evidence from Marketplace Lending 作者: None 发布日期: None

第X轮回复(o1-preview): 理解了,您在使用 requests 访问 API 时,虽然能够获取到论文标题,但无法获取到作者和发布日期。这个问题可能出在以下几个方面:

  1. API 响应结构:可能作者和发布日期信息位于 JSON 数据的嵌套字段中,您的代码未能正确解析。
  2. 请求参数:可能需要调整请求参数,以确保 API 返回完整的数据。
  3. 访问权限:某些字段可能需要特定的权限或认证才能访问

步骤 1:检查 API 响应结构(提供相关代码)……

import requests
import json

# 定义API端点
api_url = 'https://www.nber.org/api/v1/working_page_listing/contentType/working_paper/_/_/search'

# 定义请求参数(根据需要调整)
params = {
    'page': 1,
    'perPage': 50,
    'sortBy': 'public_date'
}

# 发送GET请求
response = requests.get(api_url, params=params)

# 检查响应状态
if response.status_code == 200:
    data = response.json()
    # 打印完整的JSON响应,便于检查结构
    print(json.dumps(data, indent=2, ensure_ascii=False))
else:
    print(f"请求失败,状态码: {response.status_code}")

【运行了上述代码后,我将返回的信息,再次发给o1-preview】

第X轮回复(o1-preview): 理解了,您在使用 requests 访问 API 时,虽然能够获取到论文标题,但作者和发布日期仍显示为 None。根据您提供的 JSON 数据,问题可能出在以下几个方面:

  1. 发布日期字段:publisheddate 字段为 null,而实际的发布日期信息存储在 displaydate 字段中。
  2. 作者字段的格式:authors 字段中的作者名称是包含在 HTML 标签中的字符串,直接提取可能导致解析错误或显示为 None。

对此:

  1. 使用 displaydate 字段代替 publisheddate 字段来获取发布日期。
  2. 解析 authors 字段中的 HTML 字符串,以提取纯文本的作者姓名。

以下是一个完整的 Python 示例,展示如何正确提取标题、作者和发布日期:……

【需要注意的是,在NBER的首页仅能看到文章的部分摘要,因此需要点击相应文章,跳转到新的页面,才能够得到全部摘要。】

于是乎……

Q6: 但是在这个页面中摘要是不完全的,需要单击相应的文章跳转到另外一个页面才可以

第X轮回复(o1-preview):

  • 使用API获取基本信息:通过API获取工作论文的基本信息,包括标题、作者、显示日期和论文的URL。
  • 访问每篇论文的单独页面:使用获取的URL访问每篇论文的详细页面。
  • 解析详细页面获取完整摘要:从每个详细页面中提取完整的摘要。
  • 数据存储:将提取的所有信息(标题、作者、发布日期、完整摘要、链接)保存到CSV或其他格式中。 ……

img

Q7: 我想把文件存在C:\Users\Admin\Desktop

【追问几轮后(需要将报错反馈给o1-preview),发现可以将文件下载到本地,但是抓取下来的摘要仍不是全部的。】

Q8: 摘要是需要点击对应文章的URL后,去提取摘要。这是点击其中一篇文章的url后得到的网页源代码【相应源代码】

第X轮回复(o1-preview): 给出了相应代码……

img

【复制到 Colab 中可以成功下载,但是会发现有些标点符号或者西文是乱码的。】

img

Q8: 我输出的文字中会有乱码,我看了下实际是一些标点符号

第X轮回复(o1-preview): 给出了相应代码……

【乱码问题解决,但人总是不满足的。】

Q9: 我还想要:Working Paper 33152 DOI 10.3386/w33152 这样的信息

第X轮回复(o1-preview): 给出了相应代码……

【成功得到想要的信息。】

img

Q10: 我想按照 Working Paper Number、Publication Date、Title Authors Full Abstract DOI URL 的顺序

第X轮回复(o1-preview): 给出了相应代码……

【得到想要的字段排序。】

img

写在后面

NBER 可能并不是很难爬取的网站,但是 ChatGPT o1-preview 和 Google Colab 组合起来的威力,还是让我吃惊的。

我之前没有 Python 爬虫基础(甚至Pyhon的基础语法也不是很熟悉),仅是用 Stata 做过一点简单的爬虫。但是通过不断向 ChatGPT 提问,竟然得到了一个完全不用修改的代码。

Google Colab 提供的在线平台,大大省去了本地配置环境的时间。需要注意的是,Colab 提供的免费算力和储存空间是有限的。不过,一般的项目应该是足以应付的。

技术的壁垒正在大大降低,思想的重要性大大增加。

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

<think> 我们正在处理用户关于GoogleColab的查询。根据引用内容,我们可以总结以下几点: 1. **Google Colab是什么**:Google ColabColaboratory)是一个基于云的免费Jupyter笔记本环境,无需配置即可使用,特别适合机器学习和数据科学工作(引用[1][2])。 2. **主要特点**: - 提供免费GPU资源(引用[4])。 - 无需配置环境,开箱即用(引用[2])。 - 支持挂载Google云端硬盘(引用[4])。 3. **资源限制**:虽然免费,但资源有限制,使用一段时间后运行时会重置。Colab Pro和Pro+提供更多资源和更高稳定性(引用[3])。 4. **使用步骤**:包括创建谷歌云盘、新建Colab Notebook、设置GPU、挂载Google Drive等(引用[4])。 5. **高级功能**:存在一些隐藏的高级玩法(引用[2])。 用户的问题是想查找与GoogleColab相关的信息。因此,我们应该围绕上述要点进行回答,并生成相关问题。 **回答结构**: 1. 简要介绍Google Colab。 2. 突出其核心优势(免费GPU、无需配置等)。 3. 提到资源限制和付费升级选项。 4. 提供基本使用步骤(简化版,因为详细步骤在引用[4]中已有)。 5. 生成相关问题。 **注意**:用户可能已经阅读过之前的引用内容,因此我们不需要重复所有细节,而是概括重点。 </think>### Google Colab 相关信息总结 Google ColabColaboratory)是由 Google 提供的免费云端 Jupyter 笔记本服务,主要面向机器学习、数据分析和教育领域。以下是核心信息: 1. **核心功能** - **免费 GPU/TPU 资源**:提供 Tesla K80/T4 等 GPU 加速计算(需在笔记本设置中启用)[^4] - **零配置环境**:预装 Python、TensorFlow、PyTorch 等主流框架,开箱即用[^2] - **云端存储集成**:支持挂载 Google Drive 直接读写数据(需执行 `from google.colab import drive; drive.mount('/content/drive')`)[^4] 2. **使用限制** - **会话时长**:免费版单次会话最长 12 小时,闲置超 90 分钟自动断开[^3] - **资源配额**:免费用户 GPU 使用量每月约 100 小时,可通过 Colab Pro($10/月)提升至 200+ 小时[^3] - **环境重置**:每次重启运行时需重新安装自定义依赖包[^4] 3. **典型应用场景** - 机器学习模型训练(尤其适合学生和小型项目) - 数据可视化与统计分析 - Python 教学/协作编程(支持实时多人编辑) 4. **进阶技巧** - **防断连**:在浏览器控制台执行以下 JS 代码保持活跃: ```javascript setInterval(()=>{document.querySelector("#connect").click()}, 60000) ``` - **硬件监控**:使用 `!nvidia-smi` 查看 GPU 状态 - **大文件处理**:建议将数据集上传至 Google Drive 而非笔记本空间[^4] [示例笔记本](https://colab.research.google.com/drive/1ymIYzFg4Q7iBjnTut31aBqPHgOpkjHYD) 展示了完整的 MNIST 手写数字识别项目实现[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值