我有一个简单的脚本导航到一系列页面。
我的问题是,如何创建一个页面计数器,以便我知道这个工作的位置?
理想情况下它会读取:
Page 5
Page 4 #For each loop
以下方法可行,但我遇到以下问题:
elements = [x.get_text() for x in
wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,'(//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()]')))]
相关错误:
line 36, in <module>
wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,'(//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()]')))]
File "C:\Users\Django\AppData\Local\Continuum\miniconda3\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
完整代码:
import collections
from random import shuffle
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait
driver = webdriver.Chrome()
driver.set_window_size(1024, 600)
driver.maximize_window()
driver.get('https://www.bet365.com.au/#/AS/B1/')
driver.get('https://www.bet365.com.au/#/AS/B1/')
def page_counter():
for x in range(1000):
yield x
clickMe = wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,'(//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()])')))
options = driver.find_elements_by_xpath('//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()]')
indexes = [index for index in range(len(options))]
shuffle(indexes)
for index in indexes:
count = page_counter()
driver.get('https://www.bet365.com.au/#/AS/B1/')
elements = [x.get_text("*") for x in
wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,'(//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()]')))]
#elements = [x.get_attribute("href") for x in
# driver.find_elements_by_xpath('//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()]')))]
clickMe.click()
shuffle(elements)
links = dict((next(count) + 1, e) for e in elements)
desc_links = collections.OrderedDict(sorted(links.items(), reverse=True))
for key, value in desc_links.items():
try:
driver.get(value)
print('Page ' + str(key))
except TimeoutException as ex:
pass
替代方案:
import collections
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.set_window_size(1024, 600)
driver.maximize_window()
driver.get('https://www.bet365.com.au/#/AS/B1/')
driver.find_element_by_id('TopPromotionBetNow').click()
def page_counter():
for x in range(1000):
yield x
count = page_counter()
time.sleep(10)
classifications = driver.find_elements_by_class_name('wn-Classification')
for classification in classifications:
if classification.text == 'Soccer':
classification.click()
break
time.sleep(10)
markets = driver.find_elements_by_class_name('sm-Market')
for market in markets:
group_name = market.find_element_by_class_name('sm-Market_GroupName')
if group_name.text == 'Main Lists':
coupon_lables = [x for x in market.find_elements_by_class_name('sm-CouponLink_Label')]
break
coupon_lables = [x.text for x in market.find_elements_by_class_name('sm-CouponLink_Label')]
links = dict((next(count) + 1, e) for e in coupon_lables)
desc_links = collections.OrderedDict(sorted(links.items(), reverse=True))
for key, value in desc_links.items():
for label in coupon_lables:
print('Page ' + str(key))
print('executing:' + label)
time.sleep(5)
driver.find_element_by_xpath(f'//div[contains(text(), "' + label + '")]').click()
time.sleep(5)
driver.find_element_by_class_name('cl-BreadcrumbTrail_BackButton').click()
我的输出:
Page 12
executing:UK Saturday's Matches
Page 12
executing:Spanish Saturday's Matches
Page 12
executing:Italian Saturday's Matches
Page 12
executing:International Saturday's Matches
Page 12
executing:Europe Saturday's Matches
期望:
Page 12
Page 11
Page 10
知道如何解决这个问题
代码应该如下所示:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import sys, time
driver = webdriver.Chrome()
driver.get('https://www.bet365.com.au/#/AS/B1/')
try:
WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.ID, 'TopPromotionInfo'))).click()
except:
print("Unexpected error:", sys.exc_info()[0])
try:
elements = WebDriverWait(driver, 25).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'wn-Classification')))
for element in elements:
if 'Soccer' in element.text:
element.click()
break
except:
print("Unexpected error:", sys.exc_info()[0])
market = []
try:
market = WebDriverWait(driver, 25).until(EC.presence_of_all_elements_located((By.XPATH, "//div[@class='sm-MarketGroup ']/div[@class='sm-MarketGroup_Open ']/div[@class='sm-Market ']")))
except:
print("Unexpected error:", sys.exc_info()[0])
for m1 in market:
if 'Main Lists' in m1.find_element_by_class_name('sm-Market_GroupName ').text:
elements = m1.find_elements_by_class_name('sm-CouponLink ')
labels = [x.text for x in elements]
c=0
for label in labels:
c+=1
print('Executing... ', c, len(labels))
driver.find_element_by_xpath('//div[contains(text(),"' + label +'")]').click()
time.sleep(5)
WebDriverWait(driver, 25).until(EC.presence_of_element_located((By.CLASS_NAME, 'cl-BreadcrumbTrail_BackButton '))).click()
time.sleep(5)
break
您的xpath
无效,您需要从中移除开口支架
'(//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()])'
^ remove this
应该
'//div[div/div/text()="Main Lists"]//div[starts-with(@class, "sm-CouponLink_Label") and normalize-space()])'
有趣的是为什么你没有得到InvalidSelectorException
。看看expected_conditions
source code你可以看到element_to_be_clickable
正在使用visibility_of_element_located
,而_find_element
又使用_find_element
(在源代码的底部定义)。
WebDriverException
抓住InvalidSelectorException
,所以TimeoutException
,它可以指导你解决问题,被抓住了,而你收到了element_to_be_clickable
。
编辑
此外,WebElement
返回单个visibility_of_all_elements_located
,它不可能迭代它。相反,你可以使用elements = [x.get_text("*") for x in
wait(driver, 10).until(EC.visibility_of_all_elements_located(...))
driver.find_elements
或使用elements = driver.find_elements_by_xpath(...)
for element in elements:
wait(driver, 10).until(EC.element_to_be_clickable(element))
定位元素并在循环中逐个测试元素
qazxswpoi