目录
一、selenium
1、为什么学习selenium?
2、爬虫和反爬虫的斗争
3、爬虫建议
4、获取ajax数据的方式
5、介绍
二、Selenium提供了8种定位方式
1、定位元素的8种方式
2、通过css定位,css定位有N种写法,这里列几个常用写法
3、通过link_text定位
4、通过partial_link_text定位
三、Selenium库下webdriver模块常用方法的使用
1、控制浏览器操作的一些方法
2、鼠标事件
3、键盘事件
案例:
4、获取断言信息
四、使用selenium爬取动态加载的信息
1、安装selenium模块
2、selenium模块的使用 :爬取京东商品
requests获取ajax数据:优点:性能高,代码少;缺点:ajax接口有参数加密,需要学习js语法,门槛较高,当网站的js改动就需要重写代码
selenium获取ajax数据:优点:使用简单,直接模拟浏览器。缺点:性能低 代码量多
保存获取到的HTML,供查错和重复使用
关注网站的所有类型的页面 H5页面 APP
多伪装
随机请求头
在不被发现的情况下我们尽可能的提高速度
直接分析ajax调用的接口。然后通过代码请求这个接口。
使用Selenium+chromedriver模拟浏览器行为获取数据
方式 |
优点 |
缺点 |
分析接口 |
直接可以请求到数据。不需要做一些解析工作。代码量少,性能高 |
分析接口比较复杂,特别是一些通过js混淆的接口,要有一定的js功底。容易被发现是爬虫。 |
selenium |
直接模拟浏览器的行为。浏览器能请求到的,使用selenium也能请求到。爬虫更稳定。 |
代码量多。性能低 |
selenium是一个web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏
● chromedriver是一个驱动Chrome浏览器的驱动程序,使用他才可以驱动浏览器。当然针对不同的浏览器有不同的driver。以下列出了不同浏览器及其对应的driver:
○ Chrome:https://sites.google.com/a/chromium.org/chromedriver/downloads
○ Firefox:https://github.com/mozilla/geckodriver/releases
○ Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
○ Safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/
● 下载chromedriver
● 百度搜索:淘宝镜像(https://npm.taobao.org/)
● 安装总结:https://www.jianshu.com/p/a383e8970135
● 安装Selenium:pip install selenium
● 新的chromedriver 第地址 http://chromedriver.storage.googleapis.com/index.html
插件地址:CNPM Binaries Mirror
下载后的chromedriver插件放在python环境变量的目录下面。D:\soft\Anaconda3\Anaconda\Scripts
参考文献:
Python Selenium库的使用_凯耐的博客-CSDN博客_python selenium
定位一个元素 |
定位多个元素 |
含义 |
find_element_by_id |
find_elements_by_id |
通过元素id定位 |
find_element_by_name |
find_elements_by_name |
通过元素name定位 |
find_element_by_xpath |
find_elements_by_xpath |
通过xpath表达式定位 |
find_element_by_link_text |
find_elements_by_link_tex |
通过完整超链接定位 |
find_element_by_partial_link_text |
find_elements_by_partial_link_text |
通过部分链接定位 |
find_element_by_tag_name |
find_elements_by_tag_name |
通过标签定位 |
find_element_by_class_name |
find_elements_by_class_name |
通过类名进行定位 |
find_elements_by_css_selector |
find_elements_by_css_selector |
通过css选择器进行定位 |
注意:
在学习爬虫中的selenium部分时,出现AttributeError: 'WebDriver' object has no attribute 'find_element_by_id'问题。新版的selenium已经不再使用find_element_by_id方法,将driver.find_element_by_id('kw')修改为如下语句driver.find_element(By.ID,'kw'),再在其代码页的最前端添加下列代码:from selenium.webdriver.common.by import By
例如:
from selenium import webdriver
from selenium.webdriver.common.by import By
from lxml import etree
# 实例化一个浏览器对象 Chrome代表google浏览器
driver = webdriver.Chrome()
# 请求地址
driver.get('https://www.baidu.com')
driver.find_element(By.ID,'kw').send_keys('新冠病毒')
by_class_name = driver.find_element(By.CLASS_NAME,'soutu-btn')
by_tag_name = driver.find_element(By.TAG_NAME,'input')
by_name = driver.find_element(By.NAME,'referrer')
print('by_name:',by_name)
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://baidu.com')
driver.find_element(By.CSS_SELECTOR,'#kw')
name = driver.find_element(By.CSS_SELECTOR,'[name=referrer]')
driver.find_element(By.CSS_SELECTOR,'.s-top-nav')
# driver.find_element(By.CSS_SELECTOR,'html > body > form > span > input')
#driver.find_element(By.CSS_SELECTOR,'span.soutu-btn > input#kw')
driver.find_element(By.CSS_SELECTOR,'form#form > span > input')
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://baidu.com')
driver.find_element(By.LINK_TEXT,'新闻').text
driver.find_element(By.LINK_TEXT,'hao123').text
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://baidu.com')
driver.find_element(By.PARTIAL_LINK_TEXT,'新').text
driver.find_element(By.PARTIAL_LINK_TEXT,'hao').text
driver.find_element(By.PARTIAL_LINK_TEXT,'123').text
方法 |
说明 |
set_window_size() |
设置浏览器的大小 |
back() |
控制浏览器后退 |
forward() |
控制浏览器前进 |
refresh() |
刷新当前页面 |
clear() |
清除文本 |
send_keys (value) |
模拟按键输入 |
click() |
单击元素 |
submit() |
用于提交表单 |
get_attribute(name) |
获取元素属性值 |
is_displayed() |
设置该元素是否用户可见 |
size |
返回元素的尺寸 |
text |
获取元素的文本 |
from selenium import webdriver
from time import sleep
#1.创建Chrome浏览器对象,这会在电脑上在打开一个浏览器窗口
driver = webdriver.Chrome()
#2.通过浏览器向服务器发送URL请求
driver.get("https://www.baidu.com/")
sleep(3)
#3.刷新浏览器
driver.refresh()
#4.设置浏览器的大小
driver.set_window_size(1400,800)
#5.设置链接内容
driver.find_element(By.ID,'kw').send_keys('新冠病毒')
sleep(3)
driver.find_element(By.ID,'su').click() # 点击百度
sleep(10)
在 WebDriver 中,将这些关于鼠标操作的方法封装在 ActionChains 类提供
方法 |
说明 |
ActionChains(driver) |
构造ActionChains对象 |
context_click() |
执行鼠标悬停操作 |
move_to_element(above) |
右击 |
double_click() |
双击 |
drag_and_drop() |
拖动 |
move_to_element(above) |
执行鼠标悬停操作 |
context_click() |
用于模拟鼠标右键操作, 在调用时需要指定元素定位 |
perform() |
执行所有 ActionChains 中存储的行为,可以理解成是对整个操作的提交动作 |
首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。
这种情况下我们可以有两种调用方法:链式写法
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()
鼠标事件对应的方法
•单击:click()
•右击:context_click()
•双击:double_click()
•鼠标悬停:move_to_element()
•鼠标拖动:drag_and_drop(source, target),source: 鼠标拖动的源元素,target: 鼠标释放的目标元素。
说明:
1.进行鼠标事件操作,需要导入相应的模块:from selenium.webdriver import ActionChains
2.调用 ActionChains()方法,在使用将浏览器驱动 driver 作为参数传入:ActionChains(driver)
3.模拟鼠标操作事件,在调用时需要传入定位到的元素:move_to_element(click)
4.执行所有 ActionChains 中存储的行为,要对整个操作事件进行提交动作:perform()
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.implicitly_wait(5) # 隐式等待
driver.maximize_window() # 最大化浏览器窗口
driver.get("http://www.baidu.com")
driver.find_element(By.ID,'kw').send_keys("selenium")
print("鼠标单击操作")
driver.find_element(By.ID,'su').click() # 鼠标单击“百度一下”
print("鼠标悬停操作")
click = driver.find_element(By.PARTIAL_LINK_TEXT,'百度翻译') # 定位到鼠标要操作的元素(Selenium_百度百科)
ActionChains(driver).move_to_element(click).perform()
time.sleep(3)
print("鼠标右击操作")
ActionChains(driver).context_click(click).perform()
time.sleep(3)
print("鼠标双击操作")
ActionChains(driver).double_click(click).perform()
print("鼠标拖动操作")
click1 = driver.find_element(By.PARTIAL_LINK_TEXT,'百度百科')
ActionChains(driver).drag_and_drop(click, click1).perform()
time.sleep(3)
driver.quit()
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.get('https://baidu.com')
# 定位到悬停的元素
set = driver.find_element(By.ID,'s-usersetting-top')
# 对定位的元素执行鼠标悬停操作
ActionChains(driver).move_to_element(set).perform()
# sleep(3)
# 找到链接 找到搜索设置
search_set = driver.find_element(By.PARTIAL_LINK_TEXT,'搜索设置')
search_set.click() # 点击搜索设置
sleep(1)
driver.find_element(By.ID,'SL_1').click()
sleep(2)
# 保存设置
driver.find_element(By.PARTIAL_LINK_TEXT,'保存设置').click()
sleep(2)
常用的键盘操作如下:
模拟键盘按键 |
说明 |
send_keys(Keys.BACK_SPACE) |
删除键(BackSpace) |
send_keys(Keys.SPACE) |
空格键(Space) |
send_keys(Keys.TAB) |
制表键(Tab) |
send_keys(Keys.ESCAPE) |
回退键(Esc) |
send_keys(Keys.ENTER) |
回车键(Enter) |
模拟键盘按键 |
说明 |
send_keys(Keys.CONTROL,'a') |
全选(Ctrl+A) |
send_keys(Keys.CONTROL,'c') |
复制(Ctrl+C) |
send_keys(Keys.CONTROL,'x') |
剪切(Ctrl+X) |
send_keys(Keys.CONTROL,'v') |
粘贴(Ctrl+V) |
send_keys(Keys.F1…Fn) |
键盘 F1…Fn |
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://baidu.com')
driver.find_element(By.ID,'kw').send_keys('selenium') # 输入selenium
sleep(2)
driver.find_element(By.ID,'kw').send_keys(Keys.BACK_SPACE) # 删除一个文字
sleep(2)
# 输入空格键+'教程'
driver.find_element(By.ID,'kw').send_keys(Keys.SPACE)
sleep(1)
driver.find_element(By.ID,'kw').send_keys('教程')
sleep(1)
# ctrl+a 全选输入框内容
driver.find_element(By.ID,'kw').send_keys(Keys.CONTROL,'a')
sleep(2)
# 剪切输入款内容
driver.find_element(By.ID,'kw').send_keys(Keys.CONTROL,'x')
sleep(2)
# ctrl + v粘贴内容到如书框
driver.find_element(By.ID,'kw').send_keys(Keys.CONTROL,'v')
sleep(2)
# 通过回车键来代替单击操作
driver.find_element(By.ID,'kw').send_keys(Keys.ENTER)
sleep(3)
driver.quit()
属性 |
说明 |
title |
用于获得当前页面的标题 |
current_url |
用户获得当前页面的URL |
text |
获取搜索条目的文本信息 |
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com')
print('===========查询前==========')
title = driver.title
print('title:',title)
now_url = driver.current_url
print('当前页面URL:',now_url)
driver.find_element(By.ID,'kw').send_keys('selenium')
driver.find_element(By.ID,'su').click()
sleep(2)
print('===========查询后==========')
title = driver.title
print('title2:',title)
now_url = driver.current_url
print('now_url2:',now_url)
sleep(2)
# 关闭所有窗口
driver.quit()
在cmd中切换到anaconda目录下scripts,执行pip install selenium
下载浏览器驱动
selenium模块安装完成以后还需要选择一个浏览器,然后下载赌赢的浏览器驱动。此时才可以通过selenium模块来控制浏览器的操作。我选择Google浏览器。地址:https://chromedriver.storage.googleapis.com/index.html?path=80.0.3987.106.
这里要注意的是Google的版本。
查看Google的版本号的方法:
根据版本号搜谷歌浏览器驱动镜像
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
def get_good(driver):
try:
# 通过JS控制滚轮滑动获取所有商品信息
js_code = '''
window.scrollTo(0,5000);
'''
driver.execute_script(js_code) # 执行js代码
# 等待数据加载
time.sleep(2)
# 3、查找所有商品div
# good_div = driver.find_element_by_id('J_goodsList')
good_list = driver.find_elements(By.CLASS_NAME, "gl-item")
n = 1
for good in good_list:
# 根据属性选择器查找
# 商品链接
good_url = good.find_element(By.CSS_SELECTOR, '.p-img a').get_attribute('href')
# 商品名称
good_name = good.find_element(By.CSS_SELECTOR, '.p-name em').text.replace("\n", "--")
# 商品价格
good_price = good.find_element(By.CLASS_NAME, 'p-price').text.replace("\n", ":")
# 评价人数
good_commit = good.find_element(By.CLASS_NAME, 'p-commit').text.replace("\n", " ")
good_content = f'''
商品链接: {good_url}
商品名称: {good_name}
商品价格: {good_price}
评价人数: {good_commit}
\n
'''
print(good_content)
with open('jd.txt', 'a', encoding='utf-8') as f:
f.write(good_content)
next_tag = driver.find_element(By.CLASS_NAME, 'pn-next')
next_tag.click()
time.sleep(2)
# 递归调用函数
get_good(driver)
time.sleep(10)
finally:
driver.close()
if __name__ == '__main__':
good_name = input('请输入爬取商品信息:').strip()
driver = webdriver.Chrome()
driver.implicitly_wait(10)
# 1、往京东主页发送请求
driver.get('https://www.jd.com/')
# 2、输入商品名称,并回车搜索
# input_tag = driver.find_element_by_id('key') # 京东浏览器的搜索框的id值是key
input_tag = driver.find_element(By.ID, 'key')
input_tag.send_keys(good_name)
input_tag.send_keys(Keys.ENTER)
time.sleep(2)
get_good(driver)