03 爬虫之selenium模块
selenium模块
1.概念,了解selenium
什么是selenium?selenium是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作。
selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器
2.下载安装selenium
2.1下载驱动
http://npm.taobao.org/mirrors/chromedriver/2.35/
if mac系统:
然后将解压后的chromedriver移动到/usr/local/bin目录下
if window系统:
下载chromdriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.38,并非2.9
2.2 安装pip包
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium
3.selenium的基本使用
3.1简单实用示例:
################################## 1 简单使用 # ##################################
用get打开百度页面
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
input=driver.find_element_by_id("kw")
input.send_keys("美女")
sleep(2) 法一:
input.send_keys(Keys.ENTER) #按回车确定 法二:模拟点击
search=driver.find_element_by_id("su")
search.click()
sleep(5)
driver.close()
3.2 元素定位
################################## 2 元素定位方法 # ##################################
search.find_element_by_class_name()
search.find_element_by_name()
search.find_element_by_link_text()
search.find_element_by_partial_link_text()
search.find_element_by_css_selector(".c1 p")
search.find_element_by_xpath("//*[@id=i1]/a")
#结果是一个列表
search.find_elements_by_class_name()
3.3节点信息的查看
################# 节点信息
print(content_left.tag_name) # div
print(content_left.get_attribute("id"))
print(content_left.size) # {'height': 1453, 'width': 661}
print(content_left.location) # {'x': 0, 'y': 133}
driver.close()
3.4 节点交互
######################################## 3节点交互 ###########################
driver = webdriver.Chrome()
driver.get("https://www.jd.com/") # 节点定位:搜索框标签
input=driver.find_element_by_id("key")
input.send_keys("MAC") #向标签内输入内容
sleep(2)
input.clear() #清空标签内容
input.send_keys("书")
sleep(1)
input.send_keys(Keys.ENTER) #模仿回车键
sleep(10)
driver.close()
3.5 动作链
################################ 4 动作链 ##################################### from selenium.webdriver import ActionChains
Driver = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
Driver.get(url)
Driver.switch_to.frame('iframeResult') ##因为该页面中有两个HTML文件,需要选择其中一个
source = Driver.find_element_by_css_selector('#draggable')
target = Driver.find_element_by_css_selector('#droppable')
actions = ActionChains(Driver)
# actions.drag_and_drop(source, target)
actions.click_and_hold(source).perform()
sleep(2)
actions.move_to_element(target).perform()
sleep(2)
actions.move_by_offset(xoffset=50,yoffset=0).perform() actions.release()
Driver.close()
3.6 JS代码的使用(重点很重要)
################################### 5 执行JavaScript ########################## from selenium import webdriver
#
browser = webdriver.Chrome()
browser.get('https://www.jd.com/')
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') #模仿鼠标将下拉条拉到底部
browser.execute_script('alert("123")')
3.7 Cookie
##################################### cookie ##############################
from selenium import webdriver
#
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
print(browser.get_cookies()) #获取Cookie
browser.add_cookie({'name': 'alex', 'domain': 'www.zhihu.com', 'value': ''}) #增加写入COOKIE
print(browser.get_cookies())
browser.delete_all_cookies() #清除所有Cookie
print(browser.get_cookies())
3.8 隐式等待和显式等待
################ 隐式等待:在查找所有元素时,如果尚未被加载,则等10秒
# driver.implicitly_wait(10) ############### 显示等待
# 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
#显式等待:显式地等待某个元素被加载
# wait=WebDriverWait(driver,10)
# wait.until(EC.presence_of_element_located((By.ID,'content_left')))
#
# content_left=driver.find_element_by_id("content_left")
phantomJs
PhantomJS是一款无界面的浏览器,其自动化操作流程和上述操作谷歌浏览器是一致的。由于是无界面的,为了能够展示自动化操作流程,PhantomJS为用户提供了一个截屏的功能,使用save_screenshot函数实现。
简单用法示例:
from selenium import webdriver
import time # # phantomjs路径
path = r'C:\Users\Administrator\AppData\Local\Postman\app-6.7.3\Postman.exe'
browser = webdriver.PhantomJS(path) # # 打开百度
url = 'http://www.baidu.com/'
browser.get(url) time.sleep(1) browser.save_screenshot(r'baidu.png') # 查找input输入框
my_input = browser.find_element_by_id('kw') # 往框里面写文字
my_input.send_keys('美女')
time.sleep(3) #截屏
browser.save_screenshot(r'meinv.png') # 查找搜索按钮
button = browser.find_elements_by_class_name('s_btn')[0]
button.click()
time.sleep(1)
browser.save_screenshot(r'show.png')
time.sleep(1)
browser.quit() ################################################ 案例 ########################################################## from selenium import webdriver
from time import sleep
import time if __name__ == '__main__':
url = 'https://movie.douban.com/typerank?type_name=%E6%81%90%E6%80%96&type=20&interval_id=100:90&action='
# 发起请求前,可以让url表示的页面动态加载出更多的数据
path = r'C:\Users\Administrator\AppData\Local\Postman\app-6.7.3\Postman.exe'
# 创建无界面的浏览器对象
bro = webdriver.PhantomJS(path)
# 发起url请求
bro.get(url)
time.sleep(2)
# 截图
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)
print(html_source)
with open('new_source.html', 'w',encoding="utf8") as fp:
fp.write(html_source)
bro.quit()
重点:selenium+phantomjs 就是爬虫终极解决方案:有些网站上的内容信息是通过动态加载js形成的,所以使用普通爬虫程序无法回去动态加载的js内容。例如豆瓣电影中的电影信息是通过下拉操作动态加载更多的电影信息。
综合操作:需求是尽可能多的爬取豆瓣网中的电影信息
滑动验证码简单破解示例:
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 time def 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 = 0
for im in im_list_upper:
new_im.paste(im,(x_offset,0)) # 把小图片放到 新的空白图片上
x_offset += im.size[0] x_offset = 0
for im in im_list_down:
new_im.paste(im,(x_offset,58))
x_offset += im.size[0]
#new_im.show()
return new_im def 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.webp'
image_result = requests.get(image_url).content
image_file = BytesIO(image_result) # 是一张无序的图片
image = merge_image(image_file,location_list) return image def get_track(distance): # 初速度
v=0
# 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移
t=0.2
# 位移/轨迹列表,列表内的一个元素代表0.2s的位移
tracks=[]
tracks_back=[]
# 当前的位移
current=0
# 到达mid值开始减速
mid=distance * 7/8
print("distance",distance)
global random_int
random_int=8
distance += 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*t+0.5*a*(t**2)
# 当前的位置
current += s
# 添加到轨迹列表
if round(s)>0:
tracks.append(round(s))
else:
tracks_back.append(round(s)) # 速度已经达到v,该速度作为下次的初速度
v= v0+a*t print("tracks:",tracks)
print("tracks_back:",tracks_back)
print("current:",current) # 反着滑动到大概准确位置 tracks_back.append(distance-current)
tracks_back.extend([-2,-5,-8,]) return tracks,tracks_back def get_distance(image1,image2):
'''
拿到滑动验证码需要移动的距离
:param image1:没有缺口的图片对象
:param image2:带缺口的图片对象
:return:需要移动的距离
'''
# print('size', image1.size) threshold = 50
for i in range(0,image1.size[0]): #
for j in range(0,image1.size[1]): #
pixel1 = 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[@class="gt_cut_bg gt_show"]/div')
image2 = get_image(driver, '//div[@class="gt_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_element=element).perform() # 点击鼠标左键,按住不放
import time
time.sleep(0.4)
print('第二步,拖动元素')
for track in track_list[0]:
ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform() # 鼠标移动到距离当前位置(x,y)
#time.sleep(0.4)
for track in track_list[1]:
ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform() # 鼠标移动到距离当前位置(x,y)
time.sleep(0.1)
import time
time.sleep(0.6)
# ActionChains(driver).move_by_offset(xoffset=2, yoffset=0).perform() # 鼠标移动到距离当前位置(x,y)
# ActionChains(driver).move_by_offset(xoffset=8, yoffset=0).perform() # 鼠标移动到距离当前位置(x,y)
# ActionChains(driver).move_by_offset(xoffset=2, yoffset=0).perform() # 鼠标移动到距离当前位置(x,y)
print('第三步,释放鼠标')
ActionChains(driver).release(on_element=element).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 element
except 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 = 0
import sys
sys.exit()
except Exception as e:
print('识别错误,继续')
count -= 1
time.sleep(1)
else:
print('too many attempt check code ')
exit('退出程序')
finally:
driver.close()
详细用法可参考:https://www.cnblogs.com/pyedu/p/10306662.html
03 爬虫之selenium模块的更多相关文章
- 爬虫之selenium模块
Selenium 简介 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟 ...
- 三: 爬虫之selenium模块
一 selenium模块 什么是selenium?selenium是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作. selenium最初是一个自动化测试工具, ...
- 3、爬虫之selenium模块
一 selenium模块 什么是selenium?selenium是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作. selenium最初是一个自动化测试工具, ...
- 爬虫之 selenium模块
selenium模块 阅读目录 一 介绍 二 安装 三 基本使用 四 选择器 五 等待元素被加载 六 元素交互操作 七 其他 八 项目练习 一 介绍 selenium最初是一个自动化测试工具,而爬 ...
- 爬虫四 selenium模块
一.介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作, ...
- 网络爬虫之Selenium模块和Xpath表达式+Lxml解析库的使用
实际生产环境下,我们一般使用lxml的xpath来解析出我们想要的数据,本篇博客将重点整理Selenium和Xpath表达式,关于CSS选择器,将另外再整理一篇! 一.介绍: selenium最初是一 ...
- 爬虫之selenium模块;无头浏览器的使用
一,案例 爬取站长素材中的图片:http://sc.chinaz.com/tupian/gudianmeinvtupian.html import requests from lxml import ...
- 爬虫四 selenium模块详细参数
selenium元素定位方法 一.访问页面并获取网页html from selenium import webdriver browser = webdriver.Chrome() browser.g ...
- 爬虫之selenium模块chrome版本映射表
驱动及版本对应关系如下: 驱动下载路径见底部: chromedriver版本 支持的Chrome版本v2.43 v69-71v2.42 v68-70v2.41 v67-69v2.40 v66-68v2 ...
随机推荐
- tp框架中的一些疑点知识-7
mysqli是用面向对象的,所以用箭头对象语法, 而mysql是用C语言面向过程写的, 所以用的都是php全局函数 式的写法. tinkle: 叮叮当当的响; (口语)一次电话, i will giv ...
- Python中的open和codecs.open
最近老被编码困扰,多次折腾之后,感觉python的编解码做得挺好的,只要了解下边的流程,一般都能解决 input文件(gbk, utf-8...) ----decode-----> unicod ...
- P2536 [AHOI2005]病毒检测
反思 对于*符号,明明可以让相同位置再次匹配下一个,或者跳过当前位置匹配,但是却写了个把trie的子树全部push进队列的垃圾写法,结果一直MLE 告辞 思路 模板串多且不长,可以塞到trie树里,这 ...
- springboot搭建环境整合jsp页面整合mybatis
1.pom文件依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- 6、lvs使用进阶(02)
把web server服务和443服务绑定在一起之后呢? 假设一种场景,对web服务器来讲需要session保持.一个在线购物网站,在购物时,如果不结账,一般是http协议,当结账时,需要网站跳转,可 ...
- POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)
http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...
- markdown一些网站
1.https://stackedit.io/editor 2.https://github.com/bioinformatist/LncPipeReporter 3.
- Django2.2安装
Django2.2安装 https://media.djangoproject.com/releases/2.2/Django-2.2.tar.gz 解压 tar -zvxf Django-2.2.t ...
- iterrows(), iteritems(), itertuples()对dataframe进行遍历
iterrows(): 将DataFrame迭代为(insex, Series)对. itertuples(): 将DataFrame迭代为元祖. iteritems(): 将DataFrame迭 ...
- Oracle(限定查询2)
3.2 对数据进行限定查询 在标准SQL之中定义了许多的运算符. 3.2.1.关系运算符 范例: 范例: 范例: 在使用关系运算符判断字符数据的时候注意大小写的编写问题.因为Oracle是区分大小写的 ...