You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BeautifulSoup爬取Radletters通讯数据:DataFrame合并报错求助

爬取Radletters博客通讯信息的问题修正

代码里的核心问题:

  • 页码范围漏了最后一页:原代码range(2, No_of_pages_in_radletters)只会生成2到47的页码,第48页爬不到。Python的range是左闭右开区间,要包含48页得写成range(2, No_of_pages_in_radletters + 1)。
  • BeautifulSoup调用错误:导入的是BeautifulSoup,但代码里用了未定义的bs,会直接触发NameError,得改成soup = BeautifulSoup(response.text, 'html.parser')。
  • pd.concat用法错误:pd.concat需要传入DataFrame组成的列表,原代码pd.concat(page1_df,pages_df)是错误写法,正确的是pd.concat([page1_df, pages_df])。而且每次循环都合并一次效率低,不如把所有页面的DataFrame存进列表,最后一次性合并。
  • 缺少请求异常处理:网络波动、网页报错会直接中断程序,得加异常捕获跳过出错的页面。
  • 未检查数据长度一致性:如果某页的标题、描述等列表长度不一样,生成DataFrame会报错,得先检查长度一致再处理。

修正后的完整代码:

import requests
from bs4 import BeautifulSoup
import pandas as pd

# 这里放你爬取第1页得到的page1_df
# page1_df = ... 

No_of_pages_in_radletters = 48
page_urls = []
# 修正页码范围,包含第48页
for i in range(2, No_of_pages_in_radletters + 1):
    main_url = f'https://www.radletters.com/?page={i}&tag='
    page_urls.append(main_url)

# 用列表存所有页面的DataFrame,最后一次性合并
all_dfs = [page1_df]

for page in page_urls:
    try:
        response = requests.get(page)
        # 检查请求是否成功,失败则抛出异常
        response.raise_for_status()
        # 正确调用BeautifulSoup
        soup = BeautifulSoup(response.text, 'html.parser')

        # 提取通讯标题(用列表推导式简化代码)
        newsletter_class = 'md:mt-2 mt-1 align-text-bottom inline-block font-semibold cursor-text'
        newsletter_title_list = [title.text.strip() for title in soup.find_all('div', newsletter_class)]

        # 提取通讯描述
        newsletter_desc_class = 'flex justify-center text-sm text-gray-600'
        newsletter_description_list = [desc.text.strip() for desc in soup.find_all('div', {'class': newsletter_desc_class})]

        # 提取通讯URL
        newsletter_url_class = 'flex justify-center mx-8 mt-3'
        newsletter_url_list = [url.a['href'] for url in soup.find_all('div', {'class': newsletter_url_class})]

        # 提取话题标签
        newsletter_topic_tags_class = 'md:mt-2 mt-1 flex flex-wrap justify-center'
        newsletter_topic_tags_list = []
        for topic_tags in soup.find_all('div', {'class': newsletter_topic_tags_class}):
            clean_tags = topic_tags.text.replace('\n', '').strip().replace('            ', ',')
            newsletter_topic_tags_list.append(clean_tags)

        # 检查四个列表长度是否一致,避免生成DataFrame出错
        if len(newsletter_title_list) == len(newsletter_description_list) == len(newsletter_url_list) == len(newsletter_topic_tags_list):
            page_data = {
                'Newsletter Title': newsletter_title_list,
                'Description': newsletter_description_list,
                'url': newsletter_url_list,
                'Topic Tags': newsletter_topic_tags_list
            }
            pages_df = pd.DataFrame(page_data)
            all_dfs.append(pages_df)
        else:
            print(f"页面 {page} 数据不完整,跳过")
    except Exception as e:
        print(f"爬取页面 {page} 失败: {str(e)}")
        continue

# 一次性合并所有DataFrame,ignore_index重置索引
page1_df = pd.concat(all_dfs, ignore_index=True)
print(page1_df)

额外说明:

  • 先把所有页面的DataFrame存入列表再合并,比循环里每次合并更高效,还能避免重复合并导致的索引混乱。
  • 异常处理能让程序在遇到个别页面出错时继续运行,不会直接崩溃。
  • 数据长度检查能避免因为网页结构变化导致的DataFrame生成失败。

内容的提问来源于stack exchange,提问作者Anand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 01:20:25