【Selenium】获取当前页面所有可点击跳转的链接

一、思路

获取的思路很简单:点击所有元素,发生跳转事件就获取。

二、逻辑

1.获取所有元素;

        使用XPath表达式:“//*”匹配所有元素;

        获取所有元素的数量;

        遍历元素:“(//*)[n]”,其中n为序号,从1开始;

2.全部模拟鼠标点击;

        使用Selenium自带的鼠标点击方法,可能会出现页面遮挡的问题,最好使用js的方法点击;

3.判断跳转;

        (1).在当前页面跳转:

                提前获取原始页面的内容,点击元素之后再获取一遍,如果内容不一致说明发生了跳转;

                也可以通过链接的变化来判断是否跳转,但有些页面是单页面应用,链接可能不会发生变化;

        

        (2).打开新标签页跳转:

                直接获取新标签页的链接;

三、代码

该代码会报一些无法点击的异常

import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 设置Chrome浏览器驱动路径
driver_path = "chromedriver.exe"
# 初始化Chrome浏览器
driver = webdriver.Chrome(executable_path=driver_path)
driver.maximize_window()

# 打开网页
driver.get("https://www.baidu.com")

wait = WebDriverWait(driver, 10)

# 获取原有内容
xPath = '//body'
elements = driver.find_elements(By.XPATH, xPath)
content = elements[0].get_attribute('innerText')


# 获取页面上所有的元素
xPath = '//*'
elements = driver.find_elements(By.XPATH, xPath)

# 点击每个元素并获取跳转后的URL
for index, element in enumerate(elements):
    try:

        try:
            element.click()
            time.sleep(1)
        except:
            continue
            # try:
            #     # 使用js点击
            #     xPath = '({})[{}]'.format(xPath, index + 1)
            #     js = 'document.evaluate("{}",document).iterateNext().click()'.format(xPath)
            #     driver.execute_script(js)
            #     time.sleep(1)
            # except:
            #     continue

        pages = driver.window_handles
        page_num = len(pages)
        if page_num > 1:
            driver.switch_to.window(pages[1])
            WebDriverWait(driver, 10)

            current_url = driver.current_url
            driver.close()

            driver.switch_to.window(pages[0])
        else:
            # 获取新内容
            xPath = '//body'
            elements = driver.find_elements(By.XPATH, xPath)
            new_content = elements[0].get_attribute('innerText')
            if new_content != content:
                current_url = driver.current_url

                # 返回原页面
                driver.get("https://www.baidu.com")
            else:
                continue

        print("Clicked element:", element.tag_name)
        print("Current URL:", current_url)
    except Exception as e:
        print('错误:', e)
        continue


# 关闭浏览器
driver.quit()

四、注意

  1. 页面含有多个网页嵌套iframe,iframe里面也有iframe,iframe套娃,Selenium获取iframe里面的内容需要先切换到iframe里面才能获取,而且获取完之后还要切换回原页面,非常麻烦;
  2. 页面含有隐藏的元素,只有点击才会出现,使用上述方法点击之后会因为新元素的出现导致前后内容不一致,误以为在当前页签跳转,实际并没有; 
  3. 因为每个元素都会点击一遍,类似“<div><a><span></span></a></div>”这种嵌套元素,XPath会匹配每一层嵌套,并依次点击div > a > span,这样的话,在HTML中明明表示是同一种链接,但使用XPath“(//*)[n]”匹配就会匹配出3个元素,并被点击三次,获取三个同样的链接,套娃式的标签嵌套也是无法获取全部链接的最大难题;
  4. XPath“(//*)[n]”会匹配所有页面上的元素,包括:head、meta、link、script、style、title等隐藏元素,虽然执行点击操作也不会发生什么,但会浪费大量时间,使整个获取过程变得非常缓慢。

六、总结

综上所述,Selenium可以获取页面的所有链接,但是一个网页的元素标签非常多,通过XPath表达式:“//*”匹配所有元素并遍历点击,这个过程非常缓慢。

如果想快速获取页面的所有链接,还是需要人工点击一遍网页的所有内容,确认该元素点击之后可发生跳转,然后通过Xpath表达式指定元素获取。

也就是说使用Selenium一键式获取页面上的所有链接,是非常不现实的,需要人工辅助。

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值