我正在使用python结合硒和Beautiful Soup从网站上抓取一些数据。您可以单击此页面上的按钮来更改表中显示的数据,但这全部由页面中的javascript处理。页面URL不会更改。 Selenium可以在加载时成功地在页面上呈现javascript,但是它会继续使用以前的状态(在单击之前),因此会刮除相同的数据而不是新的数据。
我尝试遵循Obey The Testing Goat上给出的解决方案,但是它似乎总是超时并且不会使状态过时。我尝试使用time.sleep手动等待10秒,以等待状态可能在一段时间后刷新。我尝试使用WebDriverWait
等到旧页面变旧为止。我尝试浏览硒文档中可能的解决方案。下面提供的代码尝试使用网站上提供的解决方案,但是无论超时率如何,它都只会超时。
from selenium.webdriver.support.wait import WebDriverWait
from contextlib import contextmanager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import staleness_of
class MySeleniumTest():
# assumes self.browser is a selenium webdriver
def __init__(self, browser, soup):
self.browser = browser
self.soup = soup
@contextmanager
def wait_for_page_load(self, timeout=30):
old_page = self.browser.find_element_by_tag_name('html')
yield
WebDriverWait(self.browser, timeout).until(staleness_of(old_page))
def tryChangingState(self):
with self.wait_for_page_load(timeout=20):
og_state = self.soup
tab = self.browser.find_element_by_link_text('Breakfast')
tab.click()
tab = self.browser.find_element_by_link_text('Lunch')
tab.click()
new_state = self.soup
# check if the HTML code has changed
print(og_state != new_state)
# create tester object
tester = MySeleniumTest(browser, soup)
# try changing state by after clicking on button
tester.tryChangingState()
我不确定我是否以正确的方式使用它。我还尝试在第一次单击后使用self.wait_for_page_load(timeout=20):
创建一个新代码,并将其中的其余代码放入其中,但这也不起作用。我希望og_state != new_state
会导致true
暗示HTML已更改,但实际结果是false
。
答案 0 :(得分:0)
原始海报在这里。我找到了问题的原因。硒中的状态正在更新,但是由于我使用的是Beautiful Soup进行解析,因此Beautiful Soup对象使用的是先前硒Web驱动程序对象中的源代码。但是,每次单击页面时更新汤对象,刮板便能够成功收集新数据。
我通过简单地调用soup = BeautifulSoup(browser.page_source, 'lxml')
换句话说,我不必担心selenium Web驱动程序的状态,这仅仅是更新解析器正在读取的源代码的问题。