Python爬取Reddit社区列表异常:仅获取单条数据求助
问题描述
尝试用Python爬取Reddit上搜索"BTC"返回的所有subreddit信息,但目前只能获取第一条记录,无法拿到完整列表。
原尝试代码
import requests import time from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.common.keys import Keys import pandas as pd driver = webdriver.Chrome(r"C:\Users\MSZ\Reddit-scrap\chromedriver") url="https://www.reddit.com/" driver.get(url) Communities=[] time.sleep(15) driver.find_element("id", "header-search-bar").send_keys("BTC") time.sleep(5) driver.find_element("id", "header-search-bar").send_keys(Keys.ENTER) time.sleep(5) community=driver.find_element('xpath', '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[1]/div/div[1]/a[3]/button') community.click() time.sleep(10) colist=driver.find_elements('xpath', '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[2]/div/div[2]/div/div/div[1]/div/a/div/div[1]/div/h6') for comunity in colist: #getting all the Communities Name=comunity.find_element('xpath', '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[2]/div/div[2]/div/div/div[1]/div/a/div/div[1]/div/h6') Members=comunity.find_element('xpath', '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[2]/div/div[2]/div/div/div[1]/div/a/div/div[1]/div/p/span') Description=comunity.find_element('xpath', '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[2]/div/div[2]/div/div/div[1]/div/a/div/div[1]/p') # Saving community info community_info = [Name.text, Members.text, Description.text] Communities.append(community_info) driver.quit() communitydf = pd.DataFrame(Communities) communitydf.columns = ['Community', 'Members', 'Description'] communitydf.to_csv('community_details.csv', index=False) time.sleep(5)
问题原因
- 全局XPath导致重复取同一条数据:循环内使用的是绝对全局XPath,每次都会定位到页面第一个匹配元素,所以所有循环都拿到第一条社区的信息。
- 列表元素定位范围过窄:
colist只定位了社区名称的h6标签,无法关联到对应社区的成员数、描述等其他信息。 - 未处理滚动加载:Reddit搜索结果是滚动加载的,仅获取当前可见区域内容会漏掉下方的社区。
修正后的代码
import time from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By import pandas as pd # 初始化浏览器 driver = webdriver.Chrome(r"C:\Users\MSZ\Reddit-scrap\chromedriver") driver.get("https://www.reddit.com/") Communities = [] time.sleep(15) # 执行搜索操作 search_bar = driver.find_element(By.ID, "header-search-bar") search_bar.send_keys("BTC") time.sleep(2) search_bar.send_keys(Keys.ENTER) time.sleep(5) # 切换到社区标签页 community_tab = driver.find_element(By.XPATH, '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[1]/div/div[1]/a[3]/button') community_tab.click() time.sleep(10) # 滚动加载所有结果(重复滚动直到没有新内容) last_height = driver.execute_script("return document.body.scrollHeight") while True: driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(5) new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height # 定位每个社区的卡片容器 community_cards = driver.find_elements(By.XPATH, '//*[@id="AppRouter-main-content"]/div/div/div[2]/div/div/div[2]/div/div[2]/div/div/div[1]/div/a') # 遍历每个社区卡片,提取信息 for card in community_cards: try: # 使用相对XPath定位当前卡片内的元素(.//表示从当前元素开始查找) name = card.find_element(By.XPATH, './/div/div[1]/div/h6').text members = card.find_element(By.XPATH, './/div/div[1]/div/p/span').text description = card.find_element(By.XPATH, './/div/div[1]/p').text Communities.append([name, members, description]) except Exception as e: # 捕获异常,避免单个元素异常导致程序中断 print(f"处理社区时出错: {e}") continue driver.quit() # 保存数据到CSV communitydf = pd.DataFrame(Communities, columns=['Community', 'Members', 'Description']) communitydf.to_csv('community_details.csv', index=False)
关键改进说明
- 使用相对XPath:通过
.//从当前社区卡片元素开始查找子元素,确保每次获取的是当前卡片的对应信息。 - 滚动加载处理:用JavaScript模拟滚动页面,重复加载直到没有新内容,保证获取全部搜索结果。
- 定位父容器:直接定位社区卡片的父容器,统一获取该社区的所有关联信息。
- 异常处理:加入try-except块,避免个别社区元素结构异常导致程序崩溃。
内容的提问来源于stack exchange,提问作者MSZ900
相关产品推荐
相关产品推荐

