Python+selenium 模拟网页点击爬虫进阶

​在上一篇文章《Python教程—模拟网页点击》讲解了简单的登录过程,本次讲一下完整的selenium爬虫,依然针对车辆定位系统这类网址,这类网址有个特点就是需要点击触发才能获取动态数据,反应时间看网速,也容易漏掉部分数据,并且访问元素在列表中,不能直接使用Copy Xpath的路径,需要先访问列表块,再去访问其中的元素,甚至还有要先访问列表图块才能对其中的元素进行访问。

一般网页版客户端不好用还不得不用,本文分享的内容希望能帮助同行解放双手,一个是无浏览器页面,一个是有浏览器页面,可以看下具体效果。

Python+selenium 模拟网页点击爬虫进阶_第1张图片Python+selenium 模拟网页点击爬虫进阶_第2张图片

需要用到的库有selenium和time,keys主要使用其中的回车功能

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

创建网页窗口,这里采用的是google浏览器

opt = webdriver.ChromeOptions()   #创建浏览
#opt.set_headless()    #无窗口模式
#driver.maximize_window()   #最大化窗口
driver = webdriver.Chrome(options=opt)  #创建浏览器对象
​
print("正在打开网页")
driver.get('http://') #打开网页

一般的打开网页的审查元素,用小箭头点击目标区域查看对应代码块,右键Copy Xpath复制路径,这里无列表块可以直接使用Copy Xpath的路径访问

Python+selenium 模拟网页点击爬虫进阶_第3张图片

Python+selenium 模拟网页点击爬虫进阶_第4张图片

可以通过find_element_by_xpath根据相应xpath路径找到填写区域,使用send_keys进行填写

time.sleep(1)     #加载等待
print("正在填写账号")
# 填入账号
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/form/div[2]/div[3]/div[1]/div[2]/div/div/span/span/input")
# 清空原有内容
elem.clear()
# 填入账号
elem.send_keys("")

点击登录按钮,同样的Copy Xpath路径

time.sleep(1)     #加载等待
print("正在登录")
# 登录按钮并单击
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/form/div[5]/div/div/span/button").click()

部分网页客户端登陆后网页数据需要一定时间加载,可以设置久一点等待时间

网页中的列表类似于,其中红框是需要点击的区域

Python+selenium 模拟网页点击爬虫进阶_第5张图片

下方有页码块,页码块也可以直接通过Copy Xpath路径访问

对于访问列表元素的路径,给一个公式

//div[@class='']/.....

怎么完善代码,在Elements中找到列表图块和需要点击的元素位置并分别Copy Xpath

/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/div/div/div[2]/div[2]/div
/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/div/div/div[2]/div[2]/div/table/tbody/tr[1]/td/span/a[1]

这里注意列表图块需要选择带有px的代码行

Python+selenium 模拟网页点击爬虫进阶_第6张图片

这个列表名称为ant-table-body-inner,然后看元素与列表图块多出了一些路径

/table/tbody/tr[1]/td/span/a[1]

因此我们可以完善元素位置路径

//div[@class='ant-table-body-inner']/table/tbody/tr[1]/td/span/a[1]

列表中还需要依次访问其他元素,这里可以改成加循环的格式,其中i指的是第i个元素

//div[@class='ant-table-body-inner']/table/tbody/tr["+str(i)+"]/td/span/a[1]

点击元素完整命令行,使用click点击

driver.find_element_by_xpath("//div[@class='ant-table-body-inner']/table/tbody/tr["+str(i)+"]/td/span/a[1]").click() #点击列表中的元素

点击后会弹出新的窗口,同样的,先定位新窗图块,在定位其中数据的位置,然后通过text直接读出文本,例如

result=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[3]").text

对于列表图块来说,其中的元素个数不会变动,但对于页码图块,其中元素的个数会发生改变,主要在开始几页和结尾几页

简单粗暴的方式就是设置几个if条件语句,下面采用的是填页码翻页的形式,当然也是为了避免中途网络延迟导致未加载报错,方便重新运行程序接着上次页码继续执行

kk=1 #从第几页开始
dengdai=1.5 #设置等待时间,单位秒,如果网络不好可设置为1.5
​
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[11]/div[2]/input")
elem.clear()
elem.send_keys(str(kk-1))
elem.send_keys(Keys.ENTER)
​
for K in range(kk,503):#采用输入页码形式翻页
    
    time.sleep(0.5)
    if K<5:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[11]/div[2]/input")
    if K==5:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[12]/div[2]/input")
    if K>5 and K<500:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[13]/div[2]/input")
    if K==500:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[12]/div[2]/input")
    if K>500:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[11]/div[2]/input")
​
    elem.clear()
    elem.send_keys(str(K))
    elem.send_keys(Keys.ENTER)
    time.sleep(0.5)

其他的细节代码,比如文本处理、条件,就根据自己想要的结果去完善

完整代码(已删掉账号密码网址)

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
​
opt = webdriver.ChromeOptions()   #创建浏览
#opt.set_headless()    #无窗口模式
#driver.maximize_window()   #最大化窗口
driver = webdriver.Chrome(options=opt)  #创建浏览器对象
​
print("正在打开网页")
driver.get('http://') #打开网页
​
time.sleep(1)     #加载等待
print("正在填写账号")
# 查找账号填写位置
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/form/div[2]/div[3]/div[1]/div[2]/div/div/span/span/input")
# 清空原有内容
elem.clear()
# 填入账号
elem.send_keys("")
​
time.sleep(1)     #加载等待
print("正在填写密码")
# 查找密码填写位置
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/form/div[3]/div/div/span/span/input")
# 清空原有内容
elem.clear()
# 填入密码
elem.send_keys("")
​
time.sleep(1)     #加载等待
print("正在登录")
# 登录按钮并单击
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/form/div[5]/div/div/span/button").click()
​
print("等待加载页面")
time.sleep(5)     #加载等待
​
kk=1 #从第几页开始
dengdai=1.5 #设置等待时间,单位秒,如果网络不好可设置为1.5
​
elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[11]/div[2]/input")
elem.clear()
elem.send_keys(str(kk-1))
elem.send_keys(Keys.ENTER)
​
for K in range(kk,503):#采用输入页码形式翻页
    
    time.sleep(0.5)
    if K<5:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[11]/div[2]/input")
    if K==5:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[12]/div[2]/input")
    if K>5 and K<500:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[13]/div[2]/input")
    if K==500:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[12]/div[2]/input")
    if K>500:
        elem = driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div/div/div/div/div/div/div/ul/li[11]/div[2]/input")
​
    elem.clear()
    elem.send_keys(str(K))
    elem.send_keys(Keys.ENTER)
    time.sleep(0.5)
    
    if K<502:
        
        for i in range(1,11):
            
            if K==186 and i==9:#该位置的对象数据缺失,直接越过即可
                continue
        
            time.sleep(0.3)     #加载等待
            driver.find_element_by_xpath("//div[@class='ant-table-body-inner']/table/tbody/tr["+str(i)+"]/td/span/a[1]").click() #点击列表中的元素
            time.sleep(dengdai)     #加载等待
            result=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[3]").text
            result1=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[2]").text
            result2=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[2]/div/div[1]/div[2]").text
            result3=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[1]/div/div/div[2]").text
            
            if result3=='':  #如果第一次未读取,则进行第二次读取
                driver.find_element_by_xpath("//div[@class='ant-table-body-inner']/table/tbody/tr["+str(i)+"]/td/span/a[1]").click() #点击列表中的元素
                time.sleep(dengdai)     #加载等待
                result=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[3]").text
                result1=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[2]").text
                result2=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[2]/div/div[1]/div[2]").text
                result3=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[1]/div/div/div[2]").text
            
            result4=["第"+str(K)+"页序号"+str(i)+":",result,result1,result2,result3]  #打印结果
            print(result4)
            
            driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[1]/button/i").click() #点击窗口退出按钮
​
    if K==502:
        
         for i in range(1,3):
        
            time.sleep(0.3)     #加载等待
            driver.find_element_by_xpath("//div[@class='ant-table-body-inner']/table/tbody/tr["+str(i)+"]/td/span/a[1]").click() #点击列表中的元素
            time.sleep(dengdai)     #加载等待
            result=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[3]").text
            result1=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[2]").text
            result2=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[2]/div/div[1]/div[2]").text
            result3=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[1]/div/div/div[2]").text
            
            if result3=='':  #如果第一次未读取,则进行第二次读取
                driver.find_element_by_xpath("//div[@class='ant-table-body-inner']/table/tbody/tr["+str(i)+"]/td/span/a[1]").click() #点击列表中的元素
                time.sleep(dengdai)     #加载等待
                result=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[3]").text
                result1=driver.find_element_by_xpath("//div[@class='ant-table-body']/table/tbody/tr["+str(i)+"]/td[2]").text
                result2=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[2]/div/div[1]/div[2]").text
                result3=driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[2]/div/div[1]/div/div[2]/div/div[2]/div/div[1]/div/div/div[2]").text
            
            result4=["第"+str(K)+"页序号"+str(i)+":",result,result1,result2,result3]  #打印结果
            print(result4)
            
            driver.find_element_by_xpath("//div[@class='ant-drawer-content-wrapper']/div/div/div[1]/button/i").click() #点击窗口退出按钮

 

你可能感兴趣的:(python,selenium,chrome)