Selenium环境配置
0、简介
用途:
- 爬虫
- 自动化运维
1、Selenium环境配置
1. 下载webdriver驱动
浏览器 | webdriver链接 |
---|---|
Chrome | http://npm.taobao.org/mirrors/chromedriver/ |
Firefox | https://github.com/mozilla/geckodriver/releases |
Edge | https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ |
有两种方法:
- 将webdriver放到Anaconda的python运行环境下的scripts文件夹
- 执行selenium时候指定webdriver的路径
2. 安装selenium模块
pip install selenium -i https://pypi.douban.com/simple
3. selenium使用示例
import time
from selenium import webdriver
# 创建一个浏览器对象
browser = webdriver.Chrome() # browser = webdriver.Chrome(executable_path='xxx')
url = 'https://www.baidu.com'
# 请求百度
browser.get(url)
# 获取浏览器截图
browser.save_screenshot('baidu_picture.jpg')
time.sleep(2)
# 关闭浏览器
browser.close()
# 退出
browser.quit()
2、Selenium简单使用
import time
from selenium import webdriver
# 创建实例
browser = webdriver.Chrome()
# 浏览器窗口最大化
browser.maximize_window()
# 请求百度首页
browser.get("https://movie.douban.com/top250")
# 关闭浏览器
browser.close()
# 退出浏览器
browser.quit()
获取网页截图
browser.save_screenshot('xxx.jpg/png')
模拟填写文本
# 首先定位到文本框
text_box = browser.find_element_by_xpath('xxx')
# 清空文本框
text_box.clear()
# 输入文字
text_box.send_keys('xxx')
模拟点击
# 点击搜索
browser.find_element_by_xpath('xxx').click()
获取cookie
browser.get_cookies()
获取网页源码
html = browser.page_source
模拟登陆Python Tip
Python Tip的登录:http://www.pythontip.com/user/login
from selenium import webdriver
# 实例化浏览器
browser = webdriver.Chrome()
# 最大化窗口
browser.maximize_window()
# 请求网页
browser.get("http://www.pythontip.com/user/login")
# 输入账号密码
browser.find_element_by_xpath('//*[@id="editor_name"]').send_keys('Sunrisecai')
browser.find_element_by_xpath('//*[@id="editor_pwd"]').send_keys('xxx')
# 点击登录
browser.find_element_by_xpath('//*[@id="apLogin"]/fieldset/div[3]/input').click()
Python爬虫入门之 Selenium自动化爬虫
1. Selenium的安装配置
Selenium安装和配置:https://www.bilibili.com/video/BV1Ka4y1i7Pz
2. 基本请求
from selenium import webdriver
# 创建实例
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.xxx()
# 浏览器窗口最大化
browser.maximize_window()
# 请求百度首页
browser.get("https://movie.douban.com/top250")
# 关闭当前页面
browser.close()
# 退出浏览器
browser.quit()
3. 常用操作
浏览器方法
浏览器方法 | 作用 |
---|---|
browser.get(url) | 请求url |
browser.quit() | 关闭浏览器 |
browser.close() | 关闭当前页面 |
browser.page_source | 获取源码 |
browser.page_source.find('keyword') | 在源码中查找 |
browser.maximize_window() - 浏览器窗口最大化 | 窗口最大化 |
节点操作:
节点操作 | 作用 |
---|---|
node.send_keys('') | 在文本框填写内容 |
node.click() | 点击 |
node.get_attribute('href/id/name') | 获取节点属性 |
node.text | 获取节点文本 |
3.1 获取cookie
browser.get_cookies()
3.2 获取url
browser.current_url
3.3 获取源码
browser.page_source
3.4 切换Frame
Selenium 打开页面后,默认是在父级 Frame 里面操作,如果页面中还有子 Frame,Selenium 是不能获取到子 Frame 里面的节点的。这时就需要使用 switch_to.frame 方法来切换 Frame。
示例如下:
- 这个在网易云音乐下载和模拟QQ邮箱登录的案例中会讲到。
browser.switch_to_frame('id name')
4. 查找节点
4.1 单个节点
做一个展示:
有多种方式,深入的方法可以通过官方文档进行系统的学习。
# 根据name值查找
find_element_by_name('sunrisecai')
# 根据id值查找
find_element_by_id('sunrisecai')
# 根据xpath查找
find_element_by_xpath('sunrisecai')
# 根据CSS选择器查找
find_element_by_css_selector('sunrisecai')
等价:
find_element()
,里面填写需要查找的节点即可。
from selenium.webdriver.common.by import By
# 根据name值查找
find_element(By.NAME,'sunrisecai')
# 根据id值查找
find_element(By.ID,'sunrisecai')
# 根据xpath查找
find_element(By.XPATH,'sunrisecai')
# 根据CSS选择器查找
find_element(By.CSS_SELECTOR,'sunrisecai')
4.2 多个节点
单个节点与多个节点的区别如下所示:
节点 | 区别 | 区别 |
---|---|---|
单个节点 | find_element | find_element_by_xxx |
多个节点 | find_elements | find_elements_by_xxx |
可以看到基本上是一致的,不同点在于多个节点的element多了一个s,即elements。
5. 模拟填写表单、点击等
填写表单:
# 首先定位到文本框
text_box = browser.find_element_by_xpath('xxx')
# 清空文本框
text_box.clear()
# 输入文字
text_box.send_keys('xxx')
模拟点击:
# 点击搜索
browser.find_element_by_xpath('xxx').click()
5.1 模拟登录Python Tip
登录Python Tip:http://www.pythontip.com/user/login
from selenium import webdriver
url = "http://www.pythontip.com/user/login"
# 实例化浏览器
browser = webdriver.Chrome()
# 最大化窗口
browser.maximize_window()
# 请求网页
browser.get(url)
# 输入账号密码
browser.find_element_by_xpath('//*[@id="editor_name"]').send_keys('PythonXC')
browser.find_element_by_xpath('//*[@id="editor_pwd"]').send_keys('pythonxiaocai')
# 点击登录
browser.find_element_by_xpath('//*[@id="apLogin"]/fieldset/div[3]/input').click()
6. 执行Js
页面进度条下拉操作:
- 京东商城的爬取案例中会用到
browser.execute_script( 'window.scrollTo(0,document.body.scrollHeight)')
7. 隐式等待 和 显式等待
在使用Selenium访问网页的过程中,有时候需要等待网页的加载,所以有时候就需要延时等待一定的实践,确保网页里你需要的内容都加载出来。
隐式等待 和 显式等待:https://blog.csdn.net/Yk_0311/article/details/82629368
7.1 隐式等待
当使用隐式等待执行测试的时候,如果 Selenium 没有在 DOM 中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。
这里用 implicitly_wait
方法实现隐式等待。
示例如下:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class JdSpider(object):
def __init__(self):
self.url = 'https://www.jd.com/'
self.browser = webdriver.Chrome()
# 隐式等待
# self.browser.implicitly_wait(10)
def get_page(self):
self.browser.get(self.url)
self.browser.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书籍')
self.browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
# 常规等待
# time.sleep(5)
next_button = self.browser.find_element_by_class_name('pn-next')
next_button.click()
def main(self):
self.get_page()
spider= JdSpider()
spider.main()
7.2 显式等待
指定要查找的节点,再指定一个最长等待时间。如果在指定时间内加载出来了这个节点,就返回查找的节点;如果到了指定时间没有加载出该节点,则抛出超时异常。
示例如下:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class JdSpider(object):
def __init__(self):
self.url = 'https://www.jd.com/'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,10)
# 隐式等待
# self.browser.implicitly_wait(10)
def get_page(self):
self.browser.get(self.url)
self.browser.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书籍')
self.browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
# 常规等待
# time.sleep(5)
# next_button = self.browser.find_element_by_class_name('pn-next')
# next_button.click()
# 显式等待
next_button=self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'pn-next')))
next_button.click()
def main(self):
self.get_page()
spider= JdSpider()
spider.main()
8. 防止Selenium被屏蔽
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
browser = webdriver.Chrome(options=option)
# 关闭自动化扩展信息
option.add_experimental_option('useAutomationExtension',False)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefined})'})
browser.get('https://antispider1.scrape.cuiqingcai.com/')
Boss直聘案例展示:
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
browser = webdriver.Chrome(options=option)
# 关闭自动化扩展信息
# option.add_experimental_option('useAutomationExtension',False)
# browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefined})'})
url = 'https://www.zhipin.com/'
browser.get(url)
# 输入职位
browser.find_element_by_xpath('//*[@id="wrap"]/div[4]/div/div/div[1]/form/div[2]/p/input').send_keys('Python')
# 点击搜索
browser.find_element_by_xpath('//*[@id="wrap"]/div[4]/div/div/div[1]/form/button').click()
9. 无头模式
如果你觉得每次运行代码弹出来的浏览器窗口太烦人,那么不妨试一下Selenium的无头模式,即不会弹出浏览器窗口。
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_argument('--headless')
browser = webdriver.Chrome(options=option)
url = 'https://www.baidu.com'
browser.get(url)
browser.save_screenshot('baidu.png')
10. 案例讲解
10.1 模拟豆瓣登录
- QQ邮箱登录的操作是一致的。
from selenium import webdriver
url = 'https://www.douban.com/'
browser = webdriver.Chrome()
browser.get(url)
# 切换到frame
frame_node = browser.find_element_by_xpath('//*[@id="anony-reg-new"]/div/div[1]/iframe')
browser.switch_to.frame(frame_node)
# 选择密码登录
browser.find_element_by_xpath('/html/body/div[1]/div[1]/ul[1]/li[2]').click()
# 输入账号密码
browser.find_element_by_xpath('//*[@id="username"]').send_keys('18306658370')
browser.find_element_by_xpath('//*[@id="password"]').send_keys('db@1234')
# 点击登录
browser.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div[5]/a').click()
10.2 网易云音乐下载
强的大佬直接硬肝他们的Js,我就没有那个本事了,不能力敌,只能智取。
搜索链接:
search_url = 'https://music.163.com/#/search/m/?s={}'
网易云音乐API:
api_url = 'http://music.163.com/song/media/outer/url?id={}'
10.2.1 下载音乐
import requests
resp = requests.get(url,headers=headers)
with open('xxx.mp3','wb') as f:
f.write(resp.content)
10.2.2 获取歌曲ID
- 获取源码,歌曲的ID在源码里边
- 从源码中提取
歌曲id
,歌曲名称
,歌手
import re
# 切换到g_iframe页面
browser.switch_to_frame("g_iframe")
html = browser.page_source
# 正则提取歌曲信息
song_id = re.findall('a href="/song\?id=(.*?)"', html)
song_name = re.findall(('<b title="(.*?)"'), html)
singer = re.findall('span class="s-fc7">(.*?)</span>', html)
for id, name, singer in zip(song_id, song_name, singer):
print(id,name,singer)
可以将歌曲ID保存到文本,再进行批量的下载,岂不美哉?
该案例展示比较简陋,感兴趣的小伙伴可以在Github上面,向大佬学习。
案例:Selenium爬取Boss直聘岗位
1. 请求首页
url = 'https://www.zhipin.com/'
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
browser = webdriver.Chrome(options=option)
browser.get(url)
2. 搜索职位
# 输入职位
browser.find_element_by_xpath('//*[@id="wrap"]/div[3]/div/div/div[1]/form/div[2]/p/input').send_keys('Python')
# 点击搜索
browser.find_element_by_xpath('//*[@id="wrap"]/div[3]/div/div/div[1]/form/button').click()
3. 网页解析
方法一:
li_list = browser1.find_elements_by_xpath('//*[@id="main"]/div/div[2]/ul/li')
for li in li_list:
print(li.text)
print()
方法二:
from lxml import etree
parse_html = etree.HTML(html)
4. 数据存储
# 存储到csv
import csv
with open('Boss_PostData.csv','w',newline='') as f:
writer = csv.writer(f)
writer.writerow(['岗位名称','薪资','资历','公司名称','公司规模','xx','xx'])
...
数据
...
writer.writerow([x,x,x,x,x])
5. 翻页
html = browser1.page_source
if 'next disabled' in html:
pass
else:
browser1.find_element_by_class_name('next').click()
案例:Selenium爬取京东商品
参考文章1:https://blog.csdn.net/weixin_45081575/article/details/105227467
《Python爬虫从入门到放弃 11 | Python爬虫实战–利用自动化神器Selenium爬取京东商品》
1. 访问首页
from selenium import webdriver
url = 'https://www.jd.com/'
browser = webdriver.Chrome()
browser.get(url)
2. 文本输入,点击搜索
# 输入内容
browser.find_element_by_xpath('//*[@id="key"]').send_keys('口罩')
# 模拟点击
browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
3. 模拟页面下拉
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
4. 获取网页源码
html = browser.page_source
print(html)
5. 解析网页
方法一:
li_list = browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
for li in li_list:
goods_data = li.text
goods_price = goods_data[0]
if '¥' in goods_data[1]:
goods_name = goods_data[2]
goods_comment = goods_data[3]
shop = goods_data[4]
else:
goods_name = goods_data[1]
goods_comment = goods_data[2]
shop = goods_data[3]
print(goods_price,goods_name,goods_comment,shop)
方法二:
from lxml import etree
parse_html = etree.HTML(html)
6. 数据存储
# 存储到csv
import csv
with open('Jd_goods.csv','w',newline='') as f:
writer = csv.writer(f)
writer.writerow(['价格','商品名称','评价人数','店铺名'])
...
数据
...
writer.writerow([x,x,x,x,x])
7. 翻页
if self.browser.page_source.find('pn-next disabled') == -1:
self.browser.find_element_by_class_name('pn-next').click()