单击按钮的代码只能工作一次,但不会两次

时间:2016-01-20 21:55:49

标签: python selenium selenium-webdriver

我尝试使用selenium网络驱动程序从网站上搜索搜索结果。在我搜索某些内容后,页面底部会显示一个按钮,以显示更多搜索结果。

这是网站上的代码:

<a id="more_results_link" class="but-g but-g-normal" onclick="return changeSuche('more_results',30,null,true);" style="width:600px; float:none; margin:20px auto 0px auto;" href="#">Weitere anzeigen (+30)</a>

这就是我尝试(成功)按下代码中的按钮的方式:

moreElement  = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(".//*[@id='more_results_link']"))
moreElement.click()

现在,我想再次按下该按钮,但现在它不起作用(我查看了Fire Path,以及XPath .//* [/ id =&#39; more_results_link&#39; ]仍然导致那个按钮)。相反,我收到以下错误消息:

Traceback (most recent call last):
  File "test.py", line 56, in test_Login
    moreElement.click()
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 75, in click
    self._execute(Command.CLICK_ELEMENT)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 454, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 107, in check_response
    message = value["value"]["message"]
TypeError: string indices must be integers

知道如何解决问题吗?理想情况下(并且更优雅)我想实现一个循环,只要它存在就点击该按钮(如果没有更多的搜索结果按钮消失)。

编辑:

这是我的完整代码:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.select import Select
import unittest
import csv

class LoginTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_Login(self):
        driver = self.driver

        # enter output file
        with open('test.csv','w') as f:
            file = csv.writer(f)
            file.writerow(("bla", "blub"))

        # enter input file
        with open('NRWPLZ.csv') as csvfile:
            readCSV = csv.reader(csvfile,delimiter=',')

            for row in readCSV:
                self.driver.get("URL")
                type = "Allgemeinarzt"
                city = row[0]
                print(city)

                typeFieldID = "what"
                cityFieldID = "where"
                submitButtonXPath = "//*[@id='suche']/form/div[5]/div/input"

                typeFieldElement   = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_id(typeFieldID))
                cityFieldElement    = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_id(cityFieldID))
                submitButtonElement  = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(submitButtonXPath))

                typeFieldElement.clear()
                typeFieldElement.send_keys(type)
                cityFieldElement.clear()
                cityFieldElement.send_keys(city)
                submitButtonElement.click()

                while driver.find_element_by_xpath(".//*[@id='more_results_link']"):
                    moreElement  = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(".//*[@id='more_results_link']"))
                    moreElement.click()
                    print("ok")

                with open('test.csv','a') as f:
                    file = csv.writer(f)

                    select = Select(driver.find_element_by_id("select_sort"))
                    select.select_by_visible_text("Entfernung")
                    print("dist")

                    count = len(driver.find_elements_by_xpath(".//*[@id='ansicht-ergebnisliste']/div"))
                    print(count)

                    for i in range(1,count):

                        try:
                            print(i)
                            nameXPath = str(".//*[@id='ansicht-ergebnisliste']/div[") + str(i) + str("]/div[4]/h2/a")
                            addressXPath = str(".//*[@id='ansicht-ergebnisliste']/div[") +str(i)+ str("]/div[4]/p[1]")
                            gradeXPath = str(".//*[@id='ansicht-ergebnisliste']/div[") + str(i) + str("]/div[3]/div[2]/div[1]")
                            reviewsXPath = str(".//*[@id='ansicht-ergebnisliste']/div[") + str(i) + str("]/div[3]/div[3]/a")
                            recommendationsXPath = str(".//*[@id='ansicht-ergebnisliste']/div[")  + str(i) + str("]/div[3]/div[3]/div[1]/strong")

                            gp = str(WebDriverWait(driver, 1).until(lambda driver: driver.find_element_by_xpath(nameXPath)).text.encode("utf-8"))
                            address = str(WebDriverWait(driver, 1).until(lambda driver: driver.find_element_by_xpath(addressXPath)).text.encode("utf-8"))
                            grade = str(WebDriverWait(driver, 1).until(lambda driver: driver.find_element_by_xpath(gradeXPath)).text.encode("utf-8"))
                            reviews = str(WebDriverWait(driver, 1).until(lambda driver: driver.find_element_by_xpath(reviewsXPath)).text.encode("utf-8"))
                            recommendations = str(WebDriverWait(driver, 1).until(lambda driver: driver.find_element_by_xpath(recommendationsXPath)).text.encode("utf-8"))
                            file.writerow([''.join(gp.split()),''.join(address.split()),''.join(grade.split()),''.join(reviews.split()),''.join(recommendations.split())])

                        except:
                            pass


    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()

EDIT2:

我想出了如何第二次按下按钮。诀窍是等到第二个结果的第一个元素&#34;批次&#34;装了。但是,出于某种原因,在我加载下一个结果页面后,网站不允许我按距离对结果进行排序(从下拉框中选择选项)。所以我首先要对结果进行排序,然后加载下一个结果页面。

换句话说,我想运行以下代码:

select = Select(WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_id("select_sort")))
select.select_by_visible_text("Entfernung")

moreElement  = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(".//*[@id='more_results_link']"))
moreElement.click()
WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(".//*[@id='ansicht-ergebnisliste']/div[31]/div[4]/h2/a"))
moreElement  = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(".//*[@id='more_results_link']"))
moreElement.click()
WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(".//*[@id='ansicht-ergebnisliste']/div[61]/div[4]/h2/a"))

但是这给了我以下错误消息:

Error
Traceback (most recent call last):
  File "/Users/Jonas/PycharmProjects/jameda/test.py", line 54, in test_Login
    moreElement.click()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 75, in click
    self._execute(Command.CLICK_ELEMENT)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 454, in _execute
    return self._parent.execute(command, params)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 107, in check_response
    message = value["value"]["message"]
TypeError: string indices must be integers

任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

感谢大家的评论。

我最终找到了解决方案:我在每个操作后插入time.sleep(2)(例如从下拉列表中选择一个选项,然后点击按钮),现在它工作正常