津南天津网站建设,企业年金怎么查,软件技术就业方向,拆分盘网站建设selenium 模块 一.简介 1.Python的一个第三方库#xff0c;对外提供的接口可以操作浏览器#xff0c;然后让浏览器完成自动化的操作。 2.自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器#xff0c;完全…selenium 模块 一.简介 1.Python的一个第三方库对外提供的接口可以操作浏览器然后让浏览器完成自动化的操作。 2.自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器完全模拟浏览器的操作比如跳转、输入、点击、下拉等来拿到网页渲染之后的结果可支持多种浏览器。 二.下载 1.需要先下载驱动 mac系统 然后将解压后的chromedriver移动到/usr/local/bin目录下 windows系统下载chromdriver.exe放到python安装路径的scripts目录 2.安装pip 包 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium 注意selenium3默认支持的webdriver是Firfox而Firefox需要安装geckodriver 三.selenium模块的使用 1.简单使用 from selenium import webdriver
from time import sleep# 后面是你的浏览器驱动位置记得前面加r,r是防止字符转义的
driver webdriver.Chrome()
# 用get打开百度页面
driver.get(http://www.baidu.com)
# 查找页面的“设置”选项并进行点击
driver.find_elements_by_link_text(设置)[0].click()
sleep(2)
# # 打开设置后找到“搜索设置”选项设置为每页显示50条
driver.find_elements_by_link_text(搜索设置)[0].click()
sleep(2)# 选中每页显示50条
m driver.find_element_by_id(nr)
sleep(2)
m.find_element_by_xpath(//*[idnr]/option[3]).click()
m.find_element_by_xpath(.//option[3]).click()
sleep(2)# 点击保存设置
driver.find_elements_by_class_name(prefpanelgo)[0].click()
sleep(2)# 处理弹出的警告页面 确定accept() 和 取消dismiss()
driver.switch_to.alert().accept()
sleep(2)
# 找到百度的输入框并输入 美女
driver.find_element_by_id(kw).send_keys(美女)
sleep(2)
# 点击搜索按钮
driver.find_element_by_id(su).click()
sleep(2)
# 在打开的页面中找到“Selenium - 开源中国社区”并打开这个页面
driver.find_elements_by_link_text(美女_百度图片)[0].click()
sleep(3)# 关闭浏览器
driver.quit() Selenium支持非常多的浏览器如Chrome、Firefox、Edge等还有Android、BlackBerry等手机端的浏览器。另外也支持无界面浏览器PhantomJS。 from selenium import webdriverbrowser webdriver.Chrome()
browser webdriver.Firefox()
browser webdriver.Edge()
browser webdriver.PhantomJS()
browser webdriver.Safari() 2.元素定位 webdriver提供了大致8种元素定位的方法 1. id find_element_by_id()2. namefind_element_by_name()3.class namefind_element_by_calss_name()4.tag namefind_element_by_tag_name()5.link textfind_element_by_link_text()6.partial link text find_element_by_partial_link_text()7.xpath find_element_by_xpath()8.css selector find_element_by_css_selector() 注意 1. find_element_by_xxx 找到第一个符合条件的标签 2.find_elements_by_xxx 所有符合条件标签 3. find_element(查询方式值) find_element_by_id(id) find_element(By.ID,id) 3.节点交互 1. tag.send_keys(内容) # 输入内容 2. tag .clear # 清空输入内容 3. tag.click() # 点击 from selenium import webdriver
import time# 节点交互
browserwebdriver.Chrome() # 实例化一个浏览器对象browser.get(https://www.taobao.com) # 让浏览器 去访问淘宝input browser.find_element_by_id(q) # 找到 输入搜索框input.send_keys(python) # 在输入框中输入内容time.sleep(1)input.clear() # 将上次输入的内容清空input.send_keys(鞋子)search browser.find_element_by_xpath(//*[idJ_TSearchForm]/div[1]/button) # 找到搜索按钮search.click() # 点击搜索按钮time.sleep(2) 4.动作链 from selenium import webdriver
from selenium.webdriver import ActionChains
import timebrowser webdriver.Chrome()# 获取一个浏览器对象
browser.get(http://www.runoob.com/try/try.php?filenamejqueryui-api-droppable) # 让该浏览器去访问该地址browser.switch_to_frame(iframeResult) # 找到id 为 iframeResult iframe 中嵌套着另一个html 文档
sourcebrowser.find_element_by_css_selector(#draggable)
targetbrowser.find_element_by_css_selector(#droppable)actionActionChains(browser)
# action.drag_and_drop(source,target) # 拖到目标
action.click_and_hold(source).perform() # 点击不放
time.sleep(1)
action.move_to_element(target).perform() # 移动到目标
time.sleep(1)
action.move_by_offset(xoffset50,yoffset50).perform() # 在右移20 下移10
time.sleep(3)
action.release() # 解除动作browser.close() 5.执行js代码 用途爬取动态页面等下拉才不断显示新数据的动态页面 from selenium import webdriver
import time
browser webdriver.Chrome()
browser.get(https://www.jd.com/)
browser.execute_script(window.scrollTo(0, document.body.scrollHeight))# 从上到下一直拉到浏览器底部browser.execute_script(alert(123))browser.close() # 关闭浏览器 6.获取节点信息 from selenium import webdriver
from selenium.webdriver.common.by import By #按照什么方式查找By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素browserwebdriver.Chrome()browser.get(https://www.amazon.cn/)waitWebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,cc-lm-tcgShowImgContainer)))tagbrowser.find_element(By.CSS_SELECTOR,#cc-lm-tcgShowImgContainer img)#获取标签属性
print(tag.get_attribute(src))
#获取标签ID位置名称大小了解
print(tag.id)
print(tag.location)
print(tag.tag_name)
print(tag.size)browser.close() 7.延时等待 在Selenium中get()方法会在网页框架加载结束后结束执行此时如果获取page_source可能并不是浏览器完全加载完成的页面如果某些页面有额外的Ajax请求我们在网页源代码中也不一定能成功获取到。所以这里需要延时等待一定时间确保节点已经加载出来。这里等待的方式有两种一种是隐式等待一种是显式等待。 隐式等待 当使用隐式等待执行测试的时候如果Selenium没有在DOM中找到节点将继续等待超出设定时间后则抛出找不到节点的异常。换句话说当查找节点而节点并没有立即出现的时候隐式等待将等待一段时间再查找DOM默认的时间是0。示例如下 from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素browserwebdriver.Chrome()#隐式等待:在查找所有元素时如果尚未被加载则等10秒
browser.implicitly_wait(10)browser.get(https://www.baidu.com)
input_tagbrowser.find_element_by_id(kw)
input_tag.send_keys(美女)
input_tag.send_keys(Keys.ENTER)contentsbrowser.find_element_by_id(content_left) #没有等待环节而直接查找找不到则会报错
print(contents)browser.close() 显示等待 隐式等待的效果其实并没有那么好因为我们只规定了一个固定时间而页面的加载时间会受到网络条件的影响。这里还有一种更合适的显式等待方法它指定要查找的节点然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点就返回查找的节点如果到了规定时间依然没有加载出该节点则抛出超时异常。 from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素browserwebdriver.Chrome()
browser.get(https://www.baidu.com)input_tagbrowser.find_element_by_id(kw)
input_tag.send_keys(美女)
input_tag.send_keys(Keys.ENTER)#显式等待显式地等待某个元素被加载
waitWebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,content_left)))contentsbrowser.find_element(By.CSS_SELECTOR,#content_left)
print(contents)browser.close() 8.cookies # 对Cookies进行操作例如获取、添加、删除Cookies等。from selenium import webdriverbrowser webdriver.Chrome()
browser.get(https://www.zhihu.com/explore)
print(browser.get_cookies())
browser.add_cookie({name: name, domain: www.zhihu.com, value: germey})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies()) 9.异常处理 from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameExceptiontry:browserwebdriver.Chrome()browser.get(http://www.runoob.com/try/try.php?filenamejqueryui-api-droppable)browser.switch_to.frame(iframssseResult)except TimeoutException as e:print(e)
except NoSuchFrameException as e:print(e)
finally:browser.close() 四 phantomJs PhantomJS是一款无界面的浏览器其自动化操作流程和上述操作谷歌浏览器是一致的。 能够展示自动化操作流程PhantomJS提供了一个截屏的功能使用save_screenshot函数实现。 from selenium import webdriver
import time# phantomjs路径
path rPhantomJS驱动路径
browser webdriver.PhantomJS(path)# 打开百度
url http://www.baidu.com/
browser.get(url)time.sleep(3)browser.save_screenshot(rphantomjs\baidu.png)# 查找input输入框
my_input browser.find_element_by_id(kw)
# 往框里面写文字
my_input.send_keys(美女)
time.sleep(3)
#截屏
browser.save_screenshot(rphantomjs\meinv.png)# 查找搜索按钮
button browser.find_elements_by_class_name(s_btn)[0]
button.click()time.sleep(3)browser.save_screenshot(rphantomjs\show.png)time.sleep(3)browser.quit() seleniumphantomjs 就是爬虫终极解决方案: 有些网站上的内容信息是通过动态加载js形成的所以使用普通爬虫程序无法回去动态加载的js内容。 例如豆瓣电影中的电影信息是通过下拉操作动态加载更多的电影信息。需求 尽可能多的爬取豆瓣网中的电影信息 from selenium import webdriver
from time import sleep
import timeif __name__ __main__:url https://movie.douban.com/typerank?type_name%E6%81%90%E6%80%96type20interval_id100:90action# 发起请求前可以让url表示的页面动态加载出更多的数据path rD:\phantomjs\bin\phantomjs.exe# 创建无界面的浏览器对象bro webdriver.PhantomJS(path)# 发起url请求bro.get(url)time.sleep(3)# 截图bro.save_screenshot(1.png)# 执行js代码让滚动条向下偏移n个像素作用动态加载了更多的电影信息js window.scrollTo(0,document.body.scrollHeight)bro.execute_script(js) # 该函数可以执行一组字符串形式的js代码time.sleep(2)bro.execute_script(js) # 该函数可以执行一组字符串形式的js代码time.sleep(2)bro.save_screenshot(2.png) time.sleep(2) # 使用爬虫程序爬去当前url中的内容 html_source bro.page_source # 该属性可以获取当前浏览器的当前页的源码html with open(./source.html, w, encodingutf-8) as fp: fp.write(html_source) bro.quit() 破解滑动验证码 from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait # 等待元素加载的
from selenium.webdriver.common.action_chains import ActionChains #拖拽
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.by import By
from PIL import Image
import requests
import re
import random
from io import BytesIO
import timedef merge_image(image_file,location_list):拼接图片im Image.open(image_file)im.save(code.jpg)new_im Image.new(RGB,(260,116))# 把无序的图片 切成52张小图片im_list_upper []im_list_down []# print(location_list)for location in location_list:# print(location[y])if location[y] -58: # 上半边im_list_upper.append(im.crop((abs(location[x]),58,abs(location[x])10,116)))if location[y] 0: # 下半边im_list_down.append(im.crop((abs(location[x]),0,abs(location[x])10,58)))x_offset 0for im in im_list_upper:new_im.paste(im,(x_offset,0)) # 把小图片放到 新的空白图片上x_offset im.size[0]x_offset 0for im in im_list_down:new_im.paste(im,(x_offset,58))x_offset im.size[0]#new_im.show()return new_imdef get_image(driver,div_path):下载无序的图片 然后进行拼接 获得完整的图片:param driver::param div_path::return:background_images driver.find_elements_by_xpath(div_path)location_list []for background_image in background_images:location {}result re.findall(background-image: url\((.*?)\); background-position: (.*?)px (.*?)px;,background_image.get_attribute(style))# print(result)location[x] int(result[0][1])location[y] int(result[0][2])image_url result[0][0]location_list.append(location)image_url image_url.replace(webp,jpg)# 替换url http://static.geetest.com/pictures/gt/579066de6/579066de6.webpimage_result requests.get(image_url).contentimage_file BytesIO(image_result) # 是一张无序的图片image merge_image(image_file,location_list)return imagedef get_track(distance):# 初速度v0# 单位时间为0.2s来统计轨迹轨迹即0.2内的位移t0.2# 位移/轨迹列表列表内的一个元素代表0.2s的位移tracks[]tracks_back[]# 当前的位移current0# 到达mid值开始减速middistance * 7/8print(distance,distance)global random_intrandom_int8distance random_int # 先滑过一点最后再反着滑动回来while current distance:if current mid:# 加速度越小单位时间的位移越小,模拟的轨迹就越多越详细a random.randint(2,5) # 加速运动else:a -random.randint(2,5) # 减速运动# 初速度v0 v# 0.2秒时间内的位移s v0*t0.5*a*(t**2)# 当前的位置current s# 添加到轨迹列表if round(s)0:tracks.append(round(s))else:tracks_back.append(round(s))# 速度已经达到v,该速度作为下次的初速度v v0a*tprint(tracks:,tracks)print(tracks_back:,tracks_back)print(current:,current)# 反着滑动到大概准确位置
tracks_back.append(distance-current)tracks_back.extend([-2,-5,-8,])return tracks,tracks_backdef get_distance(image1,image2):拿到滑动验证码需要移动的距离:param image1:没有缺口的图片对象:param image2:带缺口的图片对象:return:需要移动的距离# print(size, image1.size)
threshold 50for i in range(0,image1.size[0]): # 260for j in range(0,image1.size[1]): # 160pixel1 image1.getpixel((i,j))pixel2 image2.getpixel((i,j))res_R abs(pixel1[0]-pixel2[0]) # 计算RGB差res_G abs(pixel1[1] - pixel2[1]) # 计算RGB差res_B abs(pixel1[2] - pixel2[2]) # 计算RGB差if res_R threshold and res_G threshold and res_B threshold:return i # 需要移动的距离def main_check_code(driver,element):拖动识别验证码:param driver::param element::return:login_btn driver.find_element_by_class_name(js-login)login_btn.click()element WebDriverWait(driver, 30, 0.5).until(EC.element_to_be_clickable((By.CLASS_NAME, gt_guide_tip)))slide_btn driver.find_element_by_class_name(gt_guide_tip)slide_btn.click()image1 get_image(driver, //div[classgt_cut_bg gt_show]/div)image2 get_image(driver, //div[classgt_cut_fullbg gt_show]/div)# 图片上 缺口的位置的x坐标# 2 对比两张图片的所有RBG像素点得到不一样像素点的x值即要移动的距离l get_distance(image1, image2)print(l,l)# 3 获得移动轨迹track_list get_track(l)print(第一步,点击滑动按钮)element WebDriverWait(driver, 30, 0.5).until(EC.element_to_be_clickable((By.CLASS_NAME, gt_slider_knob)))ActionChains(driver).click_and_hold(on_elementelement).perform() # 点击鼠标左键按住不放import timetime.sleep(0.4)print(第二步,拖动元素)for track in track_list[0]:ActionChains(driver).move_by_offset(xoffsettrack, yoffset0).perform() # 鼠标移动到距离当前位置x,y#time.sleep(0.4)for track in track_list[1]:ActionChains(driver).move_by_offset(xoffsettrack, yoffset0).perform() # 鼠标移动到距离当前位置x,ytime.sleep(0.1)import timetime.sleep(0.6)# ActionChains(driver).move_by_offset(xoffset2, yoffset0).perform() # 鼠标移动到距离当前位置x,y# ActionChains(driver).move_by_offset(xoffset8, yoffset0).perform() # 鼠标移动到距离当前位置x,y# ActionChains(driver).move_by_offset(xoffset2, yoffset0).perform() # 鼠标移动到距离当前位置x,yprint(第三步,释放鼠标)ActionChains(driver).release(on_elementelement).perform()time.sleep(1)def main_check_slider(driver):检查滑动按钮是否加载:param driver::return:while True:try :driver.get(https://www.huxiu.com/)element WebDriverWait(driver, 30, 0.5).until(EC.element_to_be_clickable((By.CLASS_NAME, js-login)))if element:return elementexcept TimeoutException as e:print(超时错误继续)time.sleep(5)if __name__ __main__:try:count 3 # 最多识别3次driver webdriver.Chrome()while count 0:# 等待滑动按钮加载完成element main_check_slider(driver)main_check_code(driver,element)try:success_element (By.CSS_SELECTOR, .gt_success)# 得到成功标志success_images WebDriverWait(driver,3).until(EC.presence_of_element_located(success_element))if success_images:print(成功识别)count 0import syssys.exit()except Exception as e:print(识别错误继续)count - 1time.sleep(1)else:print(too many attempt check code )exit(退出程序)finally:driver.close() 破解滑动验证码 iframe 页面的selenium如何定位 1、iframe有id属性 browser webdriver.Chrome()# 获取一个浏览器对象
browser.get(http://www.runoob.com/try/try.php?filenamejqueryui-api-droppable) # 让该浏览器去访问该地址browser.switch_to_frame(iframeResult) # 找到id 为 iframeResult iframe 中嵌套着另一个html 文档
sourcebrowser.find_element_by_css_selector(#draggable) 2. iframe 没有id 或其id属性时变化的 下面为豆瓣的没id情况的定位 id属性值时变化的https://mail.126.com/ 下面为豆瓣的没id情况的定位代码126定位也用类似的方法 from selenium import webdriverdriver webdriver.Chrome()driver.get(https://www.douban.com/)# iframe 没有id 属性时
iframedriver.find_elements_by_tag_name(iframe)[0]
driver.switch_to_frame(iframe)password_login driver.find_element_by_xpath(//li[classaccount-tab-account]) # element xpath 找一个元素password_login.click() 转载于:https://www.cnblogs.com/knighterrant/p/10474722.html