将WebElement.text转为字符串时触发WebDriverException: no such session问题求助
WebDriverException: no such session 错误排查与解决(Twitter爬虫场景)
我最近在做Twitter数据的情感分析项目,写了一个TweetMiner类来爬取和预处理数据,但在调用massMine方法的内层循环时,遇到了WebDriverException: no such session错误。先贴一下我的相关代码:
import time from selenium import webdriver from selenium.webdriver.common.keys import Keys import numpy as np import pandas import re class TweetMiner(object): def __init__(self): self.base_url = u'https://twitter.com/search?q=from%3A' self.raw_data = [] def mineTweets(self, query, tweet_quota): ''' Mine data from a singular twitter account, input consists of a twitter handle, and a value indicating how much data to mine Ex: “@diddy” should be inputted as “diddy” ''' browser = webdriver.Chrome() url = self.base_url + query browser.get(url) time.sleep(1) body = browser.find_element_by_tag_name('body') for _ in range(tweet_quota): body.send_keys(Keys.PAGE_DOWN) time.sleep(0.2) tweets = browser.find_elements_by_class_name('tweet-text') for tweet in tweets: print(tweet.text) browser.close() return tweets def massMine(self, inputArray, dataSize): ''' Mine data from an array of twitter accounts, input array consists of twitter handles and a value indicating how much data to mine Ex: “@diddy” should be inputted as “diddy” ''' for user in inputArray: rtn = "" tweets = self.mineTweets(user,dataSize) for tweet in tweets: rtn += (tweet.text) return rtn
错误原因分析
这个错误的核心原因很明确:WebDriver会话已经被关闭,但后续代码还在尝试操作该会话对应的元素对象。
看mineTweets方法,最后调用了browser.close(),这会直接关闭当前浏览器窗口并结束整个WebDriver会话。但massMine方法里拿到tweets返回值后,循环调用tweet.text——这时候tweets里的每个元素都是已关闭会话中的DOM元素引用,会话不存在了,自然就抛出了no such session的错误。
解决方案
方案一:返回推文文本而非元素对象(推荐)
修改mineTweets方法,在关闭浏览器之前就把所有推文的文本提取出来,返回文本列表而不是元素对象,这样就不再依赖已关闭的会话:
def mineTweets(self, query, tweet_quota): browser = webdriver.Chrome() url = self.base_url + query browser.get(url) time.sleep(1) body = browser.find_element_by_tag_name('body') for _ in range(tweet_quota): body.send_keys(Keys.PAGE_DOWN) time.sleep(0.2) tweets = browser.find_elements_by_class_name('tweet-text') # 提前提取文本 tweet_texts = [tweet.text for tweet in tweets] for text in tweet_texts: print(text) browser.close() return tweet_texts
然后对应修改massMine方法,直接处理文本列表:
def massMine(self, inputArray, dataSize): rtn = "" for user in inputArray: tweet_texts = self.mineTweets(user,dataSize) for text in tweet_texts: rtn += text return rtn
方案二:延迟关闭浏览器(不推荐)
如果确实需要保留元素操作(这个场景下没必要),可以把browser.close()移到所有元素操作完成之后,但这种方式在批量爬取多个用户时,容易导致浏览器资源泄漏,不建议使用。
我自己的解决方法
后来我还尝试了另一种思路:直接在mineTweets里把每条推文写入文本文件,这样既可以及时保存数据,也避免了在会话关闭后再操作元素对象:
def mineTweets(self, query, tweet_quota): browser = webdriver.Chrome() url = self.base_url + query browser.get(url) time.sleep(1) body = browser.find_element_by_tag_name('body') for _ in range(tweet_quota): body.send_keys(Keys.PAGE_DOWN) time.sleep(0.2) tweets = browser.find_elements_by_class_name('tweet-text') # 直接写入文件 with open(f"{query}_tweets.txt", "a", encoding="utf-8") as f: for tweet in tweets: print(tweet.text) f.write(tweet.text + "\n") browser.close()
内容的提问来源于stack exchange,提问作者Luke4211
相关产品推荐
相关产品推荐

