【问题标题】:Navigation using selenium in python在 python 中使用 selenium 进行导航
【发布时间】:2018-08-23 14:06:25
【问题描述】:

我正在使用 Python 和 Selenium 抓取这个网站。但它目前只抓取 7 月份的前 10 页,它将下一个按钮的上一个兄弟的页码转换为 int 并单击下一个 number_of_pages - 1 但是在到达第 10 页后它会停止。

网址 - https://planning.adur-worthing.gov.uk/online-applications/search.do?action=monthlyList

谁能帮我让它刮掉所有的页面?

def pagination( driver ):
   data = []
   last_element = driver.find_element_by_xpath('//a[ contains( concat( " ", normalize-space( @class ), " "), " next ") ]/preceding-sibling::a[1]')
   if last_element is None:
    number_of_pages = 1
else:
    number_of_pages = int( last_element.text )
# data = [ getData( driver ) ]
data.extend(getData(driver))
for i in range(number_of_pages - 1):
    driver.find_element_by_xpath('//a[ contains( concat( " ", normalize-space( @class ), " "), " next ") ]').click()
    data.extend( getData( driver ) )
    time.sleep(1)
return data

【问题讨论】:

  • 你能在 for 循环之前打印 number_of_pages 吗?我怀疑因为您将最后一个元素的文本转换为 int,它只显示 10(即使有更多页面)
  • 我刚刚测试了你的权利,它只会把 10 变成 int 它不会在其他页面上继续
  • 根据您给定的链接 [URL - planning.adur-worthing.gov.uk/online-applications/… 。我只看到 10 页。
  • 如果您按第 10 页,您是否正在检查 7 月,应该会出现更多内容

标签: python selenium selenium-webdriver


【解决方案1】:

number_of_pages 的值似乎是 10。

找到另一种方法来找出有多少页。

您可以使用 while 循环来检查“下一页”按钮是否可用,如果可用,则继续,否则,即为最后一页。

像这样:

while next_button_element.is_displayed():
    // Do the action that is currently in the for loop

【讨论】:

  • 你的意思是这样的吗:next_button_element = driver.find_element_by_xpath('//a[ contains( concat( " ", normalize-space( @class ), " "), " next ") ]' ) while next_button_element.is_displayed(): driver.find_element_by_xpath('//a[ contains( concat( " ", normalize-space( class ), " "), " next ") ]').click() data.extend( getData( driver ) ) time.sleep(1) 返回数据
  • 使用更简单的选择器:next按钮css选择器driver.find_elements_by_css_selector('a.next')
  • 无需两次查找元素。找到一次并将其存储在变量中,然后对其使用 is_displayed() 或 click() 函数
  • 这不起作用 next_button_element = driver.find_elements_by_css_selector('a.next') 而 next_button_element.is_displayed(): next_button_element.click() data.extend( getData( driver ) ) time.sleep(1 ) 返回数据
【解决方案2】:

您可以使用的代码:

while True:
    data.extend(getData(driver))
    try:
        driver.find_element_by_css_selector('a.next').click()
    except:
        break

【讨论】:

  • 得到这个错误 next_button_by = (By.CSS_SELECTOR, "a.next") NameError: global name 'By' is not defined
  • 添加from selenium.webdriver.common.by import By
  • if driver.find_elements(next_button_by)==0: 这一行给出了错误:WebDriverException: Message: invalid argument: 'using' must be a string
  • 错过获取计数.count或使用len(driver.find_elements(next_button_by))
  • 它可以工作,谢谢,但是当 a.next 不存在时,我如何让它停止打印此错误 NoSuchElementException: Message: no such element: Unable to locate element: {"method":" css 选择器","选择器":"a.nex t"}
【解决方案3】:

听着,我知道你从我的answer 中为你的上一个问题考虑了计算总页数的想法。在前一种情况下,因为我们可以直接获得最后一个页码,所以它可以工作,但这里不是这样。

解决方案:

虽然不能直接得到页数但是总条目数是-

现在,您可以在上面的屏幕截图中看到 7 月份的情况,这个数字是 174。假设您将分页长度(单页中的条目数)设置为默认 10,则页数应该是 18 (17 页,每页 10 个条目,其余 4 个条目额外增加一页)。

所以,计算页数的逻辑应该很简单。如果您以某种方式在total_entries 变量中获得了这个条目总数,那么页数应该是(取自this

number_of_pages = (total_entries/10) + 1

默认情况下,Python 通过除法运算符返回下限整数,因此174/10 将返回17,添加+1 将返回18。所以你有它 - 18 作为页数。

现在,提取条目总数。您使用下面的定位器来查找包含它的 <span> 元素。

driver.find_element_by_xpath('//span[@class='showing']')

但是这个元素包含这样的文本 - Showing 1-10 of 174。您只需要整个字符串中的 174 部分。为此,首先提取“of”之后的字符串,然后将其转换为 int。

从文本中提取条目总数为 int 的算法:

showing_text = driver.find_element_by_xpath("//span[@class='showing']").text    #Showing 1-10 of 174
number_of_entries_text = showing_text.split("of",1)[1]        # 174 as text
number_of_entries = int( re.findall(r'\d+',number_of_entries_text)[0])  #174 as int
number_of_pages = (number_of_entries/10) + 1   #18

最终代码:

def pagination( driver ):
   data = []
   last_element = driver.find_element_by_xpath("//span[@class='showing']")
   if last_element is None:
      number_of_pages = 1
   else:
      showing_text = driver.find_element_by_xpath("//span[@class='showing']").text              number_of_entries_text = showing_text.split("of",1)[1]        
      number_of_entries = int( re.findall(r'\d+',number_of_entries_text)[0])  
      number_of_pages = (number_of_entries/10) +1   

   for i in range(number_of_pages - 1):
       driver.find_element_by_xpath('//a[ contains( concat( " ", normalize-space( @class ), " "), " next ") ]').click()
       time.sleep(1)

注意:

我认为我的解决方案更好,因为您不必反复检查任何可用的元素或捕获任何异常。您只需直接获取页数,然后多次单击下一步按钮即可。

【讨论】:

  • math.cecil 将其向下舍入为最小整数,这意味着它会跳过第 18 页
  • 如果有办法让它也能转到第 18 页,那就太好了
  • @AbdulJamac 很抱歉,我让它变得比必要的复杂。默认情况下,Python 在除法运算符上返回下限 int,因此不需要 math.ceil。检查我编辑的答案。只需将条目总数除以 10 并添加 1 即可。是的,那样的话,它会一直走到最后,即 18 岁。
猜你喜欢
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
相关资源
最近更新 更多