07-selenium、PhantomJS(无头浏览器)

selenium(自动化测试工具可用于在爬虫中解决js动态加载问题)

  简介(本质就是模仿浏览器工作)

  Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。话说回来,PhantomJS(无头浏览器)不也是一个浏览器吗,那么 Selenium 支持不?答案是肯定的,这样二者便可以实现无缝对接了。

然后又有什么好消息呢?Selenium支持多种语言开发,比如 Java,C,Ruby等等,有 Python 吗?那是必须的!

  安装一下 Python 的 Selenium 库,再安装好 PhantomJS,不就可以实现 Python+Selenium+PhantomJS 的无缝对接了嘛!PhantomJS 用来渲染解析JS,Selenium 用来驱动以及与 Python 的对接,Python 进行后期的处理,完美的三剑客!

有人问,为什么不直接用浏览器而用一个没界面的 PhantomJS(无头浏览器) 呢?答案是:效率高!而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器。

  前面爬取站长素材的时候图片是必须有浏览器视窗才加载。用selenium可以解决这种视窗加载问题。

环境安装

  1、下载安装selenium

pip3 install selenium

  2、下载浏览器对应版本的驱动(这里最好用谷歌浏览器方便强大)

http://chromedriver.storage.googleapis.com/index.html

  selenium演示:

from selenium import webdriver
import time
#指定浏览器,参数是浏览器驱动的路径,前面加上r防止转义
driver = webdriver.Chrome(r"./chromedriver.exe")#打开浏览器
#用get打开页面
driver.get("https://www.baidu.com")
# 下面是演示一下其他操作
# #查找页面的“设置”选项,并点击
# driver.find_elements_by_link_text('设置')[0].click()
# time.sleep(1)
# #打开搜索设置选项
# driver.find_elements_by_link_text('搜索设置')[0].click()
# time.sleep(1)
# # 选中每页显示50条 下拉不能先点击 直接先选中找到子元素点击
# m = driver.find_element_by_id("nr")
# time.sleep(2)
# m.find_element_by_xpath('//*[@id="nr"]/option[3]').click()
# time.sleep(0.7)
# #类名可能多个 会返回列表 因此取第一个  id,xpath都是唯一的
# driver.find_elements_by_class_name("prefpanelgo")[0].click()
# time.sleep(1)
# #处理弹出的警告页面  确认accept()  取消dismiss()
# driver.switch_to_alert().accept()
#找到搜索框 输入关键字(.send_keys)
driver.find_element_by_id('kw').send_keys("校花")
time.sleep(0.5)
#找到搜索按钮 提交
driver.find_element_by_id("su").click()
time.sleep(2)
#找到图片搜索栏链接 看图片
driver.find_elements_by_link_text("图片")[0].click()
time.sleep(3)
#退出浏览器 关闭浏览器
driver.quit()

selenium爬取雪球 投资的网站首页(涉及到js动态加载)

from selenium import webdriver
from lxml import etree
import time

driver = webdriver.Chrome("./chromedriver.exe")
#让浏览器指定url发起请求 经测试它有动态加载数据
driver.get("https://xueqiu.com/")
time.sleep(3)
#获取浏览器打开的当前页面的源码数据*******
page_text = driver.page_source
#用etree解析数据
tree = etree.HTML(page_text)
text = tree.xpath('//*[@id="app"]/div[3]/div[1]/div[2]/div[2]/div[1]/div[3]/p/text()')[0]
print(text)
time.sleep(2)
driver.quit()
###打印结果:
"""好买商学院专注出品原创内容,内容包括金融理财知识,基金基础知识,股票,债券,大家想了解更多,
就点击头像关注好买商学院吧,更多精彩内容等你来看喔! 股市简介: 周五(9.27),
今日早盘两市微幅高开后分化,沪指横盘震荡,深成指、创业板指双双走高涨超1%。截止收盘,沪指涨0.11%,报收293..."""

selenium相关行为动作的制定:

from selenium import webdriver
import time

driver = webdriver.Chrome("./chromedriver.exe")
#打开淘宝网站
driver.get("https://www.taobao.com")
time.sleep(2)
#定位到想要找的节点输入框
input_text = driver.find_element_by_id("q")
#输入你想输入的关键字send_keys()
input_text.send_keys("华为")
time.sleep(3)
#类选择器 找到节点按钮
btn = driver.find_element_by_css_selector(".btn-search")
#点击按钮发送
btn.click()
time.sleep(2)
#执行js程序(js注入)
driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
time.sleep(2)
driver.quit()

运行有点久,时间可以自行调节。

动作链:

from selenium import webdriver
import time
#导入动作链模块
from selenium.webdriver import ActionChains

driver = webdriver.Chrome("./chromedriver.exe")
#这个菜鸟教程里面有iframe标签以内的html标签
driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
#如果定位节点在标签iframe内,那么则必须使用switch_to进行iframe的切换
driver.switch_to.frame("iframeResult")
#开始定位节点(选中节点)
sm_div = driver.find_element_by_id("draggable")
#实例化一个动作链对象(将浏览器对象作为参数传入)
action = ActionChains(driver)
#点击并且长按(节点对象)
action.click_and_hold(sm_div)
#开始模拟人拖动
for i in range(5):
    #让sm+div移动
    action.move_by_offset(17,0).perform()#一定要加perform(立即执行动作链)不然不会移动 容易忘记他*****************
    time.sleep(0.6)
time.sleep(3)
#退出浏览器
driver.quit()

无头浏览器(PhantomJS停止更新了,因此用谷歌的无头浏览器):

from selenium import webdriver
from lxml import etree
import time

#无头浏览器设置(*********增加爬取效率)
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#无头浏览器需要传入参数在实例化的浏览器对象中*****
driver = webdriver.Chrome(executable_path="./chromedriver.exe",options=chrome_options)
#让浏览器指定url发起请求 经测试它有动态加载数据
driver.get("https://xueqiu.com/")
time.sleep(3)
#获取浏览器打开的当前页面的源码数据*******
page_text = driver.page_source
#用etree解析数据
tree = etree.HTML(page_text)
text = tree.xpath('//*[@id="app"]/div[3]/div[1]/div[2]/div[2]/div[1]/div[3]/p/text()')[0]
print(text)
time.sleep(2)
driver.quit()

规避被监测(用于反反爬措施):

from selenium import webdriver
from lxml import etree
import time
#*****************规避被监测***********************
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])

#无头浏览器设置(*********增加爬取效率)
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#无头浏览器需要传入参数在实例化的浏览器对象中
driver = webdriver.Chrome(executable_path="./chromedriver.exe",options=option,chrome_options=chrome_options)
#让浏览器指定url发起请求 经测试它有动态加载数据
driver.get("https://xueqiu.com/")
time.sleep(3)
#获取浏览器打开的当前页面的源码数据*******
page_text = driver.page_source
#用etree解析数据
tree = etree.HTML(page_text)
text = tree.xpath('//*[@id="app"]/div[3]/div[1]/div[2]/div[2]/div[1]/div[3]/p/text()')[0]
print(text)
time.sleep(2)
driver.quit()

模拟qq空间登录:

from selenium import webdriver
from lxml import etree
import time

driver = webdriver.Chrome(executable_path='./chromedriver.exe')
driver.get('https://qzone.qq.com/')
# 在web 应用中经常会遇到frame 嵌套页面的应用,使用WebDriver 
# 每次只能在一个页面上识别元素,对于frame 嵌套内的页面上的元素,
# 直接定位是定位是定位不到的。这个时候就需要通过switch_to.frame()方法将当前定位的主体切换了frame 里。
driver.switch_to.frame('login_frame')
driver.find_element_by_id('switcher_plogin').click()
time.sleep(3)
#如果有别人的qq号 先清除
driver.find_element_by_id('u').clear()
# 这里填写你的QQ号
driver.find_element_by_id('u').send_keys('1259553287')  
time.sleep(3)
#如果有别人的密码
driver.find_element_by_id('p').clear()
time.sleep(4)
driver.find_element_by_id('p').send_keys('xxxxxxxxx')  # 这里填写你的QQ密码
time.sleep(3)
driver.find_element_by_id('login_button').click()
time.sleep(5)
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
# page_text = driver.page_source
#
# tree = etree.HTML(page_text)
# # 执行解析操作
# li_list = tree.xpath('//ul[@id="feed_friend_list"]/li')
# for li in li_list:
#     text_list = li.xpath('.//div[@class="f-info"]//text()|.//div[@class="f-info qz_info_cut"]//text()')
#     text = ''.join(text_list)
#     print(text + '\n\n\n')

driver.close()

执行JavaScript

对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用execute_script()方法即可实现,代码如下:

from selenium import webdriver
#js操作 
driver = webdriver.Chrome("./chromedrive.exe")
driver.get('https://www.jd.com/')
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
driver.execute_script('alert("123")')

获取页面源码数据

driver.page_source

模拟浏览器前进后退

import time
from selenium import webdriver
driver = webdriver.Chrome("./chromedriver.exe")
driver.get('https://www.baidu.com')
driver.get('https://www.jd.com')
driver.get('http://www.qq.com/')
driver.back()
time.sleep(5)
driver.forward()
driver.close()

Cookie处理

使用Selenium,还可以方便地对Cookies进行操作,例如获取、添加、删除Cookies等。示例如下:

from selenium import webdriver
browser = 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()#删除Cookies
print(browser.get_cookies())

总结:selenium就是模拟浏览器对数据进行操作。步骤总结:第一步导入from selenium import webdriver 第二步实例化浏览器对象driver = webdriver.Chrome(execute_path="驱动器路径",options=(反被监测),chrome_options=(无头浏览器))相关代码上面有  第三步检查相关节点是不是在iframe里面 是就切换frame(switch_to.frame(“id”)) 第四步找到目标节点进行相关操作   第五步获取页面源码(driver.page_source)最后根据个人需要进行解析。

你可能感兴趣的:(07-selenium、PhantomJS(无头浏览器))