- - 便捷的获取网站中动态加载的数据
- - 便捷实现模拟登录
- - 基于浏览器自动化的一个模块。
-
- from selenium import webdriver
- from lxml import etree
- # 导入对应的浏览器驱动(在网上下载对应浏览器版本,并选择相应的浏览器驱动函数,若为Microsoft Edge浏览器,在下载后要将驱动名称改为MicrosoftWebDriver.exe,否则不能使用)
- bro = webdriver.Edge(executable_path="./MicrosoftWebDriver.exe")
- #对网站发起请求(国家药品监局)
- bro.get("http://scxk.nmpa.gov.cn:81/xk/")
- #page_source函数能获取请求数据
- page_text=bro.page_source
- #解析数据
- tree=etree.HTML(page_text)
- name_loc_list=tree.xpath("//*[@id='gzlist']/li")
- for name_loc in name_loc_list:
- name=name_loc.xpath('.//dl/@title')[0]
- print(name)
-
- time.sleep(5)
- #关闭浏览器
- bro.quit()
- """
- 结果:
- 婕珞芙(云南)化妆品有限责任公司
- 扬州福悦熹日化有限公司
- 扬州鸿轩实业有限公司
- 金平金岭生物瑶药开发有限责任公司
- 河源市杰格丰化妆品有限公司
- 汕头市欧姿雅日化有限公司
- 汕头市美意实业有限公司
- 辽宁美爱富化妆品有限公司
- 广州觅你化妆品有限公司
- 蓝海药业(广州)有限公司
- 广东芭薇生物科技股份有限公司
- 广州德信药业科技有限公司
- 广东香奈雪生物科技有限公司
- 汕头市缘如遇科技有限公司
- 婧贵生物科技(广州)有限公司
-
- 前面我们已经说过:对于这个网站上的数据是动态加载出来的,不能直接通过requests模块函数进行对于企业名称数据的获取
- 但是为什么selenium模块能直接获取数据呢?
- Selenium测试直接运行在浏览器中,就像真正的用户在操作一样,在打开过程中网页上的数据就已经加载出来过了
- 所以我们直接对数据进行处理就能的出结果
- """
-
- from selenium import webdriver
-
- bro = webdriver.Edge(executable_path="./MicrosoftWebDriver.exe")
- #将浏览器最大化,以便后期定位
- bro.maximize_window()
- #进入该网址
- bro.get("https://www.taobao.com/")
-
- #find的函数定位(有很多像find_element_by_**的函数供我们使用,我们可以通过自己的需求进行使用,也包括xpath)
- # 这句代表获取id为q的标签数据
- re_id=bro.find_element_by_id('q')
-
- # 因为这个标签对应的是搜索框,可以进行数据搜索,填入‘鞋’
- re_id.send_keys("鞋")
-
- time.sleep(3)
-
- # 定位搜索按钮,以便我们点击进行搜索
- # 返回一个列表,里面是selenium对象所以要有[0]
- # 注意find_elements_by_xpath返回列表,find_element_by_xpath返回对象,有一个s的区别
- cli=bro.find_elements_by_xpath('//*[@id="J_TSearchForm"]/div[1]/button')
- # 对于搜索按钮进行点击进入界面
- cli[0].click()
-
- #后退
- bro.back()
- time.sleep(3)
- # 运行js代码的函数,这句后面表示下翻一页
- bro.execute_script("window.scrollTo(0,document.body.scrollHeight)")
- time.sleep(3)
- #前进
- bro.forward()
- time.sleep(3)
- #关闭
- bro.quit()
-
- import time
- from msedge.selenium_tools import Edge
- from selenium.webdriver import ActionChains # 导入动作链库
-
-
- bro = Edge(executable_path="./MicrosoftWebDriver.exe")
-
- bro.get("https://www.cdsy.xyz/try/try.php?filename=jqueryui-api-droppable")
-
- # 由于iframe是一个特殊的标签,在iframe里的标签(像id=‘draggable’的标签)不能直接被查找所以
- # 我们要做一些预处理操作bro.switch_to.frame
- # 传入iframe的id运行后就可以对里面的标签进行操作了,可以理解为更改了作用域
- bro.switch_to.frame("iframeResult")
- div = bro.find_element_by_id('draggable')
-
- # 为了使某些标签移动,动作连贯化,对bro界面进行动作链的实例化
- action = ActionChains(bro)
-
- # id=‘draggable’的标签就是我们移动目标的标签,对他的返回值进行动作链相关的操作
- # click_and_hold含义是点击且长按div对象,等待后续操作
- action.click_and_hold(div)
-
- for i in range(5):
- # 对实例化好后包含div对象的action进行移动
- # move_by_offset(x,y)x表示横轴方向移动的像素点大小,y为纵轴方向移动的像素点大小
- # perform()表示立即操作
- action.move_by_offset(10, 0).perform()
- time.sleep(0.5)
-
- # 释放动作链
- action.release()
- time.sleep(2)
- # 关闭
- bro.quit()
-
定位点击登陆选项
点击账号密码登陆(iframe内)
定位账号密码框,填入账号密码,点击登陆按钮
- from msedge.selenium_tools import Edge
- #规避操作
- service_arg=['--verbose']
-
- bro=Edge(executable_path="./MicrosoftWebDriver.exe",service_args=service_arg)
- # 扣扣网址
- bro.get("https://im.qq.com/index")
- # 定位点击登陆选项
- str=bro.find_element_by_xpath('//*[@id="loginInfo"]/a')
- str.click()
-
- # 点击账号密码登陆(iframe内)
- bro.switch_to.frame('frame-login')
- str=bro.find_element_by_xpath('//*[@id="switcher_plogin"]')
- str.click()
-
- #定位账号框,填入账号
- account=bro.find_elements_by_class_name('inputstyle')[0]
- account.send_keys('账号')
-
- #定位密码框,填入密码
- secret=bro.find_element_by_id('p')
- secret.send_keys('密码')
-
- #点击登录按钮
- str=bro.find_elements_by_class_name('btn')[0]
- str.click()
-
有些朋友最怕遇到滑动验证码,以至于爬数据登陆网站束手无策,我给大家分装了一个函数,下面教大家怎么用
- import cv2 # 导库
- def distance(image_path,tem_path,x):
- image = cv2.imread(image_path, 0)
- tem = cv2.imread(tem_path, 0)
- height, width = tem.shape[:2]
- res = cv2.matchTemplate(image, tem, cv2.TM_CCOEFF_NORMED)
- min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
- return max_loc[0] - x
-
- """
- distance(image_path # 整个验证码的路径 见图1
- ,tem_path # 目标移动位置路径 见图2
- ,x # 见图3
- # 对没错,x 就是像素值,大概是几十左右
- )
- 返回值max_loc[0] - x
- 含义是需要移动的像素点
-
- 那么我们使用动作链进行操作:
-
- action = ActionChains(bro)
- action.click_and_hold(div) #div是滑动时的按键
- action.move_by_offset(distance返回值, 0).perform()
-
- 也就是说,首先要把image_path对应的图片(图1)通过请求下载下来
- tem_path对应的图片(图2) 是我们提前截屏截好的
- x大概12,可以在8到15之间试一下
- 然后通过动作链进行操作即可
-
- 注意:
- 1. 不用担心缺口不一样会不会出错
- 2. 对不同图片可以使用相同的tem_path
- 3. tem_path对应的图片尽量精准,且要与运行时图片图片大小相同
- 4. 后续我也会改进这个,让它自动实现测距
- """
-
图1
图2
(没错就是截屏截下来的,你使用的时候也需要搞下来啊,没办法,孩子只有这个笨方法)
图3(那个白色的x就是我们要的像素值)
- 由于from selenium import webdriver中并没有无头操作
- 我们使用另一个库来操作:msedge-selenium_tools(可完全替代selenium.webdriver)
- from msedge.selenium_tools import EdgeOptions
- from msedge.selenium_tools import Edge
- Edge来代替webdriver.Edge
- EdgeOptions是无头参数包
-
- 于是就有了:
- from msedge.selenium_tools import EdgeOptions
- from msedge.selenium_tools import Edge
- #这三句为固定用法,其他和上述所有操作无差别
- edge_options = EdgeOptions()
- edge_options.use_chromium = True
- edge_options.add_argument('headless')
- edge_options.add_argument('--disable-gpu')
-
- bro=Edge(executable_path="./MicrosoftWebDriver.exe",options=edge_options)
-
为了防止浏览器检测到我们是通过selenium形式登陆网页,我们进行如下操作
- from msedge.selenium_tools import Edge
- #固定写法
- service_arg=['--verbose']
- bro=Edge(executable_path="./MicrosoftWebDriver.exe",service_args=service_arg)
-
- from msedge.selenium_tools import EdgeOptions
- from msedge.selenium_tools import Edge
-
- #无头操作
- edge_options = EdgeOptions()
- edge_options.use_chromium = True
- edge_options.add_argument('headless')
- edge_options.add_argument("disable-gpu")
-
- #规避操作
- service_arg=['--verbose']
-
- bro=Edge(executable_path="./MicrosoftWebDriver.exe"#驱动器path参数
- ,options=edge_options#无头操作参数
- ,service_args=service_arg#规避操作参数
- )
-
【持续更新ing】