使用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
相关产品推荐
相关产品推荐

