汇总:selenium控制浏览器获取数据(java 版本)
优采云 发布时间: 2022-09-24 19:05汇总:selenium控制浏览器获取数据(java 版本)
前段时间,突然更新了一个数据源网站,原来通过websocket爬取的数据突然变成了gg。没有办法,只能用最原创的方法来爬取想要的数据。我爬过很多网站数据,这里就不讨论爬虫的合理性和合法性了。纯分享一点我知道的技术网站大致分为三种(对于爬虫)⒈网站直接通过接口获取数据(json和pages)。简单的事情就是通过传递一些参数来获取不同的数据,这是最简单的。通过requests模块,你可以很方便的得到你想要的数据。 JSON数据说起来容易,直接解析JSON就好了。另一个是接口返回网页的源代码,稍微麻烦一点,也不难。 scrapy框架好用,xpath也是神器。简单的学习,爬一个网站不成问题。 ⒉第二
秘密武器:爬虫神器之selenium的使用
目录
Selenium 介绍及安装
Selenium 是一个用于 Web 的自动化测试工具,最初是为 网站 自动化测试而开发的。类型就像我们用来玩游戏的按键精灵,可以根据指定的指令自动操作。不同之处在于 Selenium 可以直接在浏览器上运行。对,它支持所有主流浏览器(包括 PhantomJS 这些无接口浏览器)。
根据我们的说明,Selenium 可以让浏览器自动加载页面,获取所需的数据,甚至对页面进行截图,或者判断 网站 上的某些动作是否发生。
Selenium 没有自己的浏览器,不支持浏览器的功能。它需要与第三方浏览器结合使用。但是我们有时需要让它在代码中内联运行,所以我们可以用一个叫做 PhantomJS 的工具来代替真正的浏览器。
PyPI网站下载Selenium库嗯,也可以使用第三方管理器Selenium官方参考文档:o/index.html
安装
pip install selenium
安装 Firefox geckodriver
安装最新版本的 Firefox 并将 Firefox 可执行文件添加到系统环境变量中。记得关闭火狐的自动更新
firefox下载地下:es把下载的geckodriver.exe放到路径D:\Python\python_version\
安装 ChromeDriver
注意版本号要对应
测试代码
# 导入 webdriver
from selenium import webdriver
# 要想调用键盘按键操作需要引入keys包
from selenium.webdriver.common.keys importKeys
# 调用环境变量指定的PhantomJS浏览器创建浏览器对象
driver = webdriver.Chrome()
# 如果没有在环境变量指定PhantomJS位置
# driver = webdriver.Chrome(executable_path="./phantomjs"))
# get方法会一直等到页面被完全加载,然后才会继续程序,通常测试会在这里选择 time.sleep(2)
driver.get("http://www.baidu.com/")
# 打印网页渲染后的源代码
print(driver.page_source)
# 生成新的页面快照
driver.save_screenshot("python爬虫.png")
# 获取当前url
print(driver.current_url)
# 关闭浏览器
driver.quit()
selenium 控制浏览器
最大化窗口
我们知道调用启动的浏览器不是全屏的,所以不会影响脚本的执行,但是有时候会影响我们的“watch”脚本的执行。
browser = webdriver.Chrome()
url= 'http://www.baidu.com'
browser.get(url)
borwser.maximize_window()
设置宽度和高度
最大化还是不够灵活,可以自由设置浏览显示的宽高吗?当然这是可能的。
browser = webdriver.Chrome()
url= 'http://www.baidu.com'
browser.get(url)
borwser.set_window_size(500,600)
浏览器前进后退
浏览器上有后退和前进按钮,对于浏览网页的人来说更方便;对于做web自动化测试的同学来说应该算是一道难题。事实上,这很简单。下面我们来看看python的实现。
browser = webdriver.Chrome()#访问百度首页
first_url= 'http://www.baidu.com'
browser.get(first_url)
time.sleep(2)#访问新闻页面
second_url='http://news.baidu.com'
browser.get(second_url)
time.sleep(2)#返回(后退)到百度首页print "back to %s "%(first_url)
browser.back()
time.sleep(1) #前进到新闻页print "forward to %s"%(second_url)
browser.forward()
time.sleep(2)
browser.quit()
硒元素定位
对象定位应该是自动化的核心。要操作一个对象,首先要识别对象。一个对象就像一个人,他会有各种各样的特征(属性),比如我们可以通过一个人的*敏*感*词*号、姓名,或者他住在哪条街、哪个楼层、哪个门牌号来找到这个人。
物体定位
webdriver提供对象定位方法
使用 By 类确定选择哪种方法
from selenium.webdriver.common.by import By
chrome.find_element(by=By.ID,value='su')
By类的一些属性如下
动作元素
如前所述,很多知识是一个定位元素。定位只是第一步。定位后,需要对该元件进行操作。鼠标点击还是键盘输入取决于我们定位的是按钮还是输入框。
一般来说,webdriver中比较常用的操作对象的方法有以下几种:
from selenium import webdriver
from selenium.webdriver.chrome.service
import Service
from time import sleep
from selenium.webdriver.common.by import By
def test_element():
# 创建驱动对象
s =Service(executable_path='./chromedriver.exe')
# 创建一个浏览器
driver = webdriver.Chrome(service=s)
# 打个百度
driver.get('https://cn.bing.com/')
sleep(2)
# 获取 搜索框,并输出“学习”
driver.find_element(By.ID,'sb_form_q').send_keys('学习')
sleep(1)
# 获取 搜索按钮,并点击
driver.find_element(By.ID,'search_icon').click()
if __name__ =='__main__':
test_element()
selenium 定位下拉菜单
包括下拉菜单页面
Level Locate
Level locate
Link1
Another action
Something else here
Separated link
Link2
Action
Another action
Something else here
Separated link
选定的元素
from selenium import webdriver
from selenium.webdriver.chrome.service
import Service
from selenium.webdriver.common.by import By
import os
from time import sleep
def test_down_menu():
# 创建一个驱动
s =Service(executable_path='./chromedriver.exe')
# 创建浏览器
driver = webdriver.Chrome(service=s)
# 设置方位的文件地址
file_path = 'file:///'+os.path.abspath('./html/test01.html')
# 访问页面
driver.get(file_path)
# 定位父级元素
driver.find_element(By.LINK_TEXT,'Link1').click()
# 找到要移动的位置
menu = driver.find_element(By.LINK_TEXT,'Action')
# 做一个移动光标的动作
# 定义一个动作在driver 移动到menu的位置 执行动作
webdriver.ActionChains(driver).move_to_element(menu).perform()
# sleep(2)
# 定位子级元素
menu.click()
# 睡眠2秒
sleep(2)
# 关闭浏览器
driver.quit()
if __name__ == '__main__':
test_down_menu()
硒级定位
窗口定位
对于一个现代的web应用来说,往往会有框架(frame)或者窗口(window)的应用,这给我们的定位带来了一个难题。有时候我们定位一个元素,定位器没有问题,但是一直无法定位。这时,我们需要检查元素是否在一个框架中。Seelnium webdriver提供了switch_to_frame方法,可以轻松解决这个问题。
多层框架或窗口的定位:driver.switch_to.frame()
框架.html
frame
frame
内部.html
inner
inner
switch_to_frame()
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from selenium.webdriver.common.by import By
import os
from time import sleep
def select_frame():
# 创建驱动
s = Service(executable_path='./chromedriver.exe')
# 创建浏览器
driver = webdriver.Chrome(service=s)
file_path = 'file:///' + os.path.abspath('./html/outer.html')
# 打开网页
driver.get(file_path)
# 切换frame
driver.switch_to.frame('f1')
driver.switch_to.frame('f2')
# 定位元素,输入要搜索的内容
driver.find_element(By.ID,'sb_form_q').send_keys('百战')
# 定位按钮,点击搜索
driver.find_element(By.ID,'search_icon').click()
sleep(3)
driver.quit()
if __name__ =='__main__':
select_frame()
selenium 处理下拉框
爬取数据时,有时数据过多,官网提供了过滤功能select标签。对于这样的数据,我们只需要定位元素并点击它。
drop_down.html
UPS Next Day Air ==> $12.51
UPS Next Day Air Saver ==> $11.61
UPS 3 Day Select ==> $10.69
UPS 2nd Day Air ==> $9.03
UPS Ground ==> $8.34
USPS Priority Mail Insured ==> $9.25
USPS Priority Mail ==> $7.45
USPS First Class ==> $3.20
UPS Next Day Air ==> $12.51
UPS Next Day Air Saver ==> $11.61
UPS 3 Day Select ==> $10.69
UPS 2nd Day Air ==> $9.03
UPS Ground ==> $8.34
USPS Priority Mail Insured ==> $9.25
USPS Priority Mail ==> $7.45
USPS First Class ==> $3.20
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
import os
def choose_option():
# 创建驱动
s = Service('./chromedriver.exe')
# 创建浏览器对象
driver = webdriver.Chrome(service=s)
# 访问页面
# 设置页面地址
file_path = 'file:///' + os.path.abspath('./html/test02.html')
driver.get(file_path)
# 定位下拉框里面选项
sleep(2)
driver.find_element(By.XPATH,'//select[@id="ShippingMethod"]/option[@value="10.69"]').click()
sleep(2)
driver.find_element(By.XPATH,'//select[@id="ShippingMethod2"]/option[@value="9.25"]').click()
# 关闭浏览器
sleep(5)
driver.quit()
if __name__ == '__main__':
choose_option()
selenium 处理弹出窗口
有时,页面可能要弹出窗口。只需转到定位弹出窗口上的“确定”按钮
html
This is a page
Hello,Python Spider
alert('这个是测试弹窗')
from lib2to3.pgen2 import driver
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from time import sleep
import os
def test_windows():
# 创建驱动对象
s = Service('./chromedriver.exe')
# 创建浏览器
driver = webdriver.Chrome(service=s)
# 访问页面
# 设置页面地址
file_path = 'file:///' + os.path.abspath('./html/test03.html')
driver.get(file_path)
sleep(3)
# 定位弹出窗口,并点击
driver.switch_to.alert.accept()
sleep(3)
driver.quit()
if __name__ =='__main__':
test_windows()
selenium 拖放元素
要完成元素的拖拽,首先需要指定被拖拽元素和拖拽目标元素,然后使用ActionChains类来实现,ActionChains用于自定义动作。通过 ActionChains 对象中的 perform() 执行动作,
html
jQuery UI Draggable - Auto-scroll
#draggable, #draggable2, #draggable3 { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 0 10px 10px 0; }
body {font-family: Arial, Helvetica, sans-serif;}
table {font-size: 1em;}
.ui-draggable, .ui-droppable {background-position: top;}
$( function() {
$( "#draggable" ).draggable({ scroll: true });
$( "#draggable2" ).draggable({ scroll: true, scrollSensitivity: 100 });
$( "#draggable3" ).draggable({ scroll: true, scrollSpeed: 100 });
} );
<p>Scroll set to true, default settings
scrollSensitivity set to 100
scrollSpeed set to 100
</p>
Python
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
import os
<p>
def test_drop():
# 创建驱动对象
s = Service('./chromedriver.exe')
# 创建浏览器
driver = webdriver.Chrome(service=s)
# 访问页面
# 设置页面地址
file_path = 'file:///' + os.path.abspath('./html/test04.html')
driver.get(file_path)
# 定位要拖拽的元素
div1 = driver.find_element(By.ID,'draggable')
div2 = driver.find_element(By.ID,'draggable2')
div3 = driver.find_element(By.ID,'draggable3')
# 开始拖拽
# 定义事件
sleep(2)
webdriver.ActionChains(driver).drag_and_drop(div1,div2).perform()
for i in range(10):
webdriver.ActionChains(driver).drag_and_drop_by_offset(div3,10,10).perform()
sleep(0.5)
# 关闭浏览器
sleep(3)
driver.quit()
if __name__ =='__main__':
test_drop()</p>
selenium 调用 js 方法
有时候我们需要控制页面滚动条上的滚动条,但是滚动条并不是页面上的一个元素。这时候我们需要使用js来操作
滚动条的操作一般有两种场景:
调用js方法
execute_script(script, *args)
滚动条回到顶部:
js="document.getElementById('id').scrollTop=0"
driver.execute_script(js)
滚动条到底部
js="document.documentElement.scrollTop=10000"
driver.execute_script(js)
可以修改scrollTop的值,使滚动条位于右侧,0为顶部,10000为底部
以上方法在火狐和IE浏览器上都可以,但是用Chrome浏览器,我发现不行。Chrome浏览器解决方案:
js = "document.body.scrollTop=0"
driver.execute_script(js)
水平滚动条
js = "window.scrollTo(100,400)"
driver.execute_script(js)
硒等待元素
被迫等待
使用时间.sleep
功能:当代码运行到强制等待的那一行时,无论什么原因,都强制等待指定时间,需要通过time模块实现
优点:简单
缺点:无法做出有效判断,会浪费时间
隐式等待
chrome.implicitly_wait(time_num)
过了一定时间,发现元素还没有加载,继续等待我们指定的时间。如果超过指定时间还没有加载,就会抛出异常。如果它没有等待就已经加载,它将立即执行。
优点:设置一次
缺点:必须等待加载完成才能进行后续操作,或者等待超时才能进行后续操作
显示等待
从 selenium.webdriver.support.wait 导入 WebDriverWait
指定等待条件并指定最长等待时间。在这段时间内判断是否满足等待条件。如果是真的,它会立即返回。如果不是真的,它将一直等待,直到等待您指定的最长等待时间。如果仍然不满足则抛出异常,如果满足则正常返回
优点:专门用于等待指定元素,加载后可以运行后续代码
缺点:需要设置多个元素分别等待
url = 'https://www.guazi.com/nj/buy/'
driver = webdriver.Chrome()
driver.get(url)
wait = WebDriverWait(driver,10,0.5)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'next')))
print(driver.page_source)
selenium 参数用法
包括无头模式、代理模式、绕过检测
from selenium.webdriver.chrome.service import Service
from selenium.webdriver import Chrome,ChromeOptions,DesiredCapabilities
from time import sleep
def test_headless():
# 设置参数,将浏览器隐藏起来(无头浏览器)
options = ChromeOptions()
options.add_argument('--headless')
# 设置驱动
service = Service('./chromedriver')
# 启动Chrome浏览器
driver = Chrome(service=service,options=options)
# 访问页面
driver.get('https://www.baidu.com')
# 打印代码
print(driver.page_source)
# 关闭浏览器
driver.quit()
def test_proxy1():
# 设置参数,给浏览器设置代理
options = ChromeOptions()
# options.add_argument('--proxy-server=http://ip:port')
options.add_argument('--proxy-server=http://221.199.36.122:35414')
# 设置驱动
service = Service('./chromedriver')
# 启动Chrome浏览器
driver = Chrome(service=service,options=options)
# 访问页面 "134.195.101.16",
driver.get('http://httpbin.org/get')
# 打印代码
print(driver.page_source)
# 关闭浏览器
driver.quit()
def test_proxy2():
from selenium.webdriver.common.proxy import ProxyType,Proxy
# 设置参数,给浏览器设置代理
ip = 'http://113.76.133.238:35680'
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = ip
proxy.ssl_proxy = ip
# 关联浏览器
capabilities = DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)
# 设置驱动
service = Service('./chromedriver')
# 启动Chrome浏览器
driver = Chrome(service=service,desired_capabilities=capabilities)
# 访问页面 "134.195.101.16",
driver.get('http://httpbin.org/get')
# 打印代码
print(driver.page_source)
# 关闭浏览器
driver.quit()
def test_find():
options = ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)
chrome = Chrome(chrome_options=options)
chrome.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => false
})
"""
})
chrome.get('http://httpbin.org/get')
info = chrome.page_source
print(info)
sleep(20)
if __name__ =='__main__':
# test_headless()
# test_proxy1()
# test_proxy2()
test_find()
硒实用案例
from selenium.webdriver.chrome.service import Service
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from lxml import etree
def spider_huya():
# 创建一个驱动
service = Service('./chromedriver.exe')
# 创建一个浏览器
driver = Chrome(service=service)
# 设置隐式等待
driver.implicitly_wait(5)
# 访问网址
driver.get('https://www.huya.com/g/lol')
count = 1
while True:
# print('获取了第%d页' % count)
# count += 1
# 提取数据
e = etree.HTML(driver.page_source)
names = e.xpath('//i[@class="nick"]/@title')
person_nums = e.xpath('//i[@class="js-num"]/text()')
# 打印数据
# for n,p in zip(names,person_nums):
# print(f'主播名:{n} 人气:{p}')
# 找到下一页的按钮
# try:
# next_btn = driver.find_element(By.XPATH,'//a[@class="laypage_next"]')
# next_btn.click()
# except Exception as e:
# break
if driver.page_source.find('laypage_next') == -1:
break
next_btn = driver.find_element(By.XPATH,'//a[@class="laypage_next"]')
next_btn.click()
# 关闭浏览器
driver.quit()
if __name__ == '__main__':
spider_huya()