如何将Selenium与BeautifulSoup爬取的谷歌学术多页结果保存至Pandas DataFrame
解决谷歌学术爬取结果保存到DataFrame的问题
我看了你的代码,问题主要出在单个条目DataFrame的创建方式以及已经被弃用的append方法上——这会导致数据结构混乱,而且循环中反复拼接DataFrame效率极低。咱们换个更可靠高效的方案,直接收集所有爬取结果到列表,最后一次性生成DataFrame:
优化后的完整代码
import pandas as pd from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup import re import random import time # 初始化空列表,用来存储所有爬取到的条目字典 results_list = [] # ChromeDriver本地存储路径 PATH = '/Applications/chromedriver' driver = webdriver.Chrome(PATH) try: # 访问目标URL driver.get('https://scholar.google.de/') # 显式等待搜索栏加载完成(替代time.sleep,更可靠) search_box = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, 'gs_hdr_tsi')) ) # 输入搜索内容并提交 search_box.send_keys('"circular economy"AND "Dlt" AND "Germany" AND "Sweden"') search_box.send_keys(Keys.RETURN) # 计算结果页数 count_element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, 'gs_ab_md')) ) Anzahl = count_element.text total_results = int(re.findall(r'\d+', Anzahl)[0]) # 计算需要点击"下一页"的次数(每页10条) total_pages = (total_results // 10) + 1 print(f"页面数量: {total_pages}") # 遍历所有页面(这里先测试2页,实际换成total_pages) for page_num in range(total_pages): # 等待结果列表加载完成 WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, '[data-lid]')) ) page_source = driver.page_source soup = BeautifulSoup(page_source, 'lxml') # 遍历当前页面的每个条目 for item in soup.select('[data-lid]'): try: print('----------------------------------------') # 提取标题(去除多余空格) title = item.select('h3')[0].get_text(strip=True) # 提取链接 link = item.select('a')[0]['href'] # 提取作者、来源信息 author_source = item.select('.gs_a')[0].get_text(strip=True) # 提取年份(处理没有年份的情况) year_match = re.findall(r'\d{4}', author_source) year = year_match[0] if year_match else None # 提取摘要(处理没有摘要的情况) abstract = item.select('.gs_rs')[0].get_text(strip=True) if item.select('.gs_rs') else None # 将当前条目存入字典,添加到列表 results_list.append({ "Titel": title, "Link": link, "Authoren": author_source, "Veröffentlichungsjahr": year, "Abstract": abstract }) print(f"标题: {title}") print(f"链接: {link}") print(f"作者/来源: {author_source}") print(f"年份: {year}") print(f"摘要: {abstract[:100]}...") # 只打印前100个字符避免输出过长 print('----------------------------------------') except Exception as e: print(f"处理条目时出错: {str(e)}") print('---') # 如果不是最后一页,点击"下一页" if page_num < total_pages - 1: try: # 等待"下一页"按钮可点击 next_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.LINK_TEXT, 'Weiter')) ) next_btn.click() # 随机等待,避免被谷歌封禁 time.sleep(random.randint(2, 10)) except Exception as e: print(f"无法点击下一页: {str(e)}") break finally: # 无论是否出错,都关闭浏览器 driver.quit() # 将列表转换为DataFrame df = pd.DataFrame(results_list) print(f"共爬取到 {len(df)} 条数据") # 导出到CSV(支持中文编码) df.to_csv('google_scholar_results.csv', index=False, encoding='utf-8-sig') # 或者导出到Excel # df.to_excel('google_scholar_results.xlsx', index=False)
关键改动说明
用列表收集数据:
先把每个条目的字典存入results_list,最后一次性生成DataFrame,比循环append高效10倍以上,还能避免数据结构错误。显式等待替代
time.sleep:WebDriverWait会等待元素加载完成后再操作,不会因为网络波动导致找不到元素的报错,稳定性大幅提升。容错处理优化:
对年份、摘要等可能缺失的字段做了判断,保证DataFrame的结构完整,不会因为某条数据缺失字段而中断程序。弃用
append方法:
pandas 2.0+已经正式移除了append,用列表收集后转DataFrame是官方推荐的标准写法。更友好的输出:
摘要只打印前100个字符,避免控制台输出过长影响阅读。
运行代码后,你会得到一个google_scholar_results.csv文件,里面包含所有爬取到的标题、链接、作者、年份和摘要信息。如果需要调整字段或者导出格式,直接修改字典的键或者导出代码即可。
内容的提问来源于stack exchange,提问作者ObiwanKeTobi
相关产品推荐
相关产品推荐

