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



我正在尝试使用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='more_results_link']仍然指向该按钮)。相反,我收到以下错误消息:

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()

编辑2:

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

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

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

知道如何解决最后一个问题吗?

谢谢大家的评论。

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

最新更新