爬虫中的selenium简单学习及案例
selenium
-
什么是selenium
- 一款基于浏览器自动化的模块
-
和爬虫的关联:
- 模拟登录
- 便捷的获取动态加载的数据
-
缺点:
- 爬取数据的效率底
- 环境部署繁琐
-
模块下载:
- pip install selenium
-
selenium如何获取动态加载的数据
- 环境安装:pip install selenium
- 基本的使用流程
- 结合着某一款浏览器驱动程序实例化一个浏览器对象
- 下载浏览器驱动程序:
- http://chromedriver.storage.googleapis.com/index.html
- 查看驱动和浏览器版本的映射关系:
- http://blog.csdn.net/huilan_same/article/details/51896672
- 编写自动化操作代码
- 结合着某一款浏览器驱动程序实例化一个浏览器对象
-
基本编码流程
- 导包
- 创建一个浏览器对象,且在创建的过程中需要使用浏览器的驱动程序
- 使用get方法进行请求发送
- 指定其他的行为动作对应的代码
- 关闭浏览器
-
演示程序
#模块引入 from selenium import webdriver from time import sleep # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的 driver = webdriver.Chrome(r'./chromedriver.exe') # 用get打开百度页面 driver.get("http://www.baidu.com") # 查找页面的“设置”选项,并进行点击 driver.find_elements_by_link_text('设置')[0].click() sleep(2) # 打开设置后找到“搜索设置”选项,设置为每页显示50条 driver.find_elements_by_link_text('搜索设置')[0].click() sleep(2) # 选中每页显示50条 m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 点击保存设置 driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 处理弹出的警告页面 确定accept() 和 取消dismiss() driver.switch_to_alert().accept() sleep(2) # 找到百度的输入框,并输入 美女 driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 点击搜索按钮 driver.find_element_by_id('su').click() sleep(2) # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面 driver.find_elements_by_link_text('美女_百度图片')[0].click() sleep(3) # 关闭浏览器 driver.quit()selenium详细用法
-
基础案例
from selenium import webdriver from bs4 import BeautifulSoup #实例化一个浏览器对象 bro = webdriver.Chrome(executable_path='D:\爬虫\谷歌访问助手/chromedriver.exe') #发起一个get请求 bro.get(url='http://125.35.6.84:81/xk/') #获取当前浏览器页面的源码数据 page_text = bro.page_source #使用bs4进行解析 soup = BeautifulSoup(page_text,'lxml') dl_list = soup.select('#gzlist>li>dl') for dl in dl_list: name = dl.string print(name)
-
selenium详细用法
- 行为动作:
- 标签定位:find系列的函数
- find_element_by_id()
- find_element_by_xpath()
- 节点交互
- 点击:click()
- send_keys('xxx')
- 执行js:
- bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
- 动作链
- 导包:from selenium.webdriver import ActionChains
- 创建一个动作链对象:action = ActionChains(bro)
- 调用动作链对象中封装的属性和方法:
- action.click_and_hold(ele)
- move_by_offset(x,y)
- perform():立即执行动作链
- release()
- page_source:返回当前浏览器显示页面的全部页面源码数据
- 标签定位:find系列的函数
- 浏览器无头设置
- 规避检测
- 截图:save_screenshot('./1.png')
#通过selenium实现浏览器自动化访问淘宝,并搜索关键字'华为' from time import sleep from selenium import webdriver #实例化一个浏览器对象 bro = webdriver.Chrome(executable_path='D:\爬虫\谷歌访问助手/chromedriver.exe') #获取淘宝url bro.get('https://www.taobao.com/') #find系列的函数是用作于定位标签 search_input = bro.find_element_by_id('q') #在淘宝首页搜索框中录入一个商品名称 search_input.send_keys('华为') #阻塞两秒,防止浏览器加载阻塞导致未获取标签 sleep(2) #执行JS代码 #Js代码,让浏览器滚轮向下拖动一个屏的高度 bro.execute_script('window.scrollTo(0,document.body.scrollHeight)') sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)') sleep(2) btn = bro.find_element_by_xpath('//*[@id="J_TSearchForm"]/div[1]/button') #绑定事件 btn.click() sleep(2) #退出浏览器 bro.quit()
-
模拟登陆访问QQ空间
from selenium import webdriver from lxml import etree from time import sleep #实例化一个浏览器对象 bro = webdriver.Chrome(executable_path='D:\爬虫\谷歌访问助手/chromedriver.exe') #获取空间url bro.get('https://qzone.qq.com/') #switch_to操作切换frame,此时才能进行登陆页面的操作 bro.switch_to.frame('login_frame') #点击使用账号密码登陆,需要绑定click事件 bro.find_element_by_id('switcher_plogin').click() bro.find_element_by_id('u').send_keys('QQ账号') bro.find_element_by_id('p').send_keys('QQ密码') #点击登陆,绑定click事件 bro.find_element_by_id('login_button').click() sleep(2) #获取登陆页面的所有的文本数据 page_text = bro.page_source # 进行数据解析 tree = etree.HTML(page_text) #获取内容 data = tree.xpath('//*[@id="feed_3484622709_311_0_1560755089_0_1"]/div[1]//text()') print(data) sleep(3) bro.quit()
- 行为动作:
-
相关的网站会对爬虫的请求实现监测,检测请求是否为selenium进行的发送
-
如何让selenium规避监测?
- 访问美团网址(规避selenium监视)示例
from time import sleep
from selenium.webdriver import ChromeOptions
from selenium import webdriver
#实例化一个ChromeOptions对象
option = ChromeOptions()
#设置chromedriver启动参数,规避对selenium的检测机制
option.add_experimental_option('excludeSwitches', ['enable-automation'])
#设定url
url = 'https://bj.meituan.com/'
#实例化一个浏览器对象
bro = webdriver.Chrome(executable_path='D:\爬虫\谷歌访问助手/chromedriver.exe')
# 由于美团做了一定的设置,需要进行两次get请求才可以访问
bro.get(url)
sleep(2)
bro.get(url)
#屏幕截图
bro.save_screenshot('1.png')
#打印当前浏览器页面的源码数据
print(bro.page_source)
-
如何设置浏览器无可视化界
from selenium.webdriver.chrome.options import Options from selenium import webdriver from time import sleep # 创建一个参数对象,用来控制chrome以无界面模式打开 chrome_options = Options() #设置谷歌浏览器的页面无可视化 chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') #设定url url = 'https://bj.meituan.com/' #实例化一个浏览器对象,并把设置的无可视化传入浏览器对象 bro = webdriver.Chrome(executable_path='D:\爬虫\谷歌访问助手/chromedriver.exe',chrome_options=chrome_options) bro.get(url) sleep(2) bro.get(url) bro.save_screenshot('2.png') print(bro.page_source)
-
phantomJs:
-
就是一款无可视化界面的浏览器,了解即可
-
由于已经停止更新维护,现在已经被弃用
-
多使用谷歌无头浏览器
-
-
12306模拟登陆
from chaojiying_Python.chaojiying import Chaojiying_Client from selenium import webdriver from selenium.webdriver import ActionChains from PIL import Image from time import sleep #调用超级鹰获取验证码 def get_codeImg_text(imgPath, imgType): chaojiying = Chaojiying_Client('loukunpeng813', 'nidayedeqQ123', ' 899991') #用户中心>>软件ID 生成一个替换 96001 im = open(imgPath, 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要// # print(chaojiying.PostPic(im, 1902)) return chaojiying.PostPic(im, imgType)['pic_str'] #实例化一个浏览器对象,并把设置的无可视化传入浏览器对象 bro = webdriver.Chrome(executable_path='D:\爬虫\谷歌访问助手/chromedriver.exe') #获取12306的网站 bro.get('https://kyfw.12306.cn/otn/login/init') sleep(2) #账号密码进行模拟登陆 bro.find_element_by_id('username').send_keys('12306账号') bro.find_element_by_id('password').send_keys('12306密码') #想要获取验证码图片左上角和右下角亮点坐标,通过这亮点坐标可以形成一个裁剪的矩形区域 code_img_ele = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img') location = code_img_ele.location # 验证码图片左上角坐标 size = code_img_ele.size #验证码图片的长宽 #指定矩形区域 rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height'])) #保存验证码 bro.save_screenshot('aa.png') i = Image.open('./aa.png') code_img_name = 'code.png' frame = i.crop(rangle) frame.save(code_img_name) #进行验证码的识别 result = get_codeImg_text(code_img_name,9004) print(result) # x1,y1|x2,y2|x3,y3 x,y #[[x1,y1],[x2,y2],[x3,y3]] [[x,y]] all_list = [] if '|' in result: list_1 = result.split('|') count_1 = len(list_1) for i in range(count_1): xy_list = [] x = int(list_1[i].split(',')[0]) y = int(list_1[i].split(',')[1]) xy_list.append(x) xy_list.append(y) all_list.append(xy_list) else: x = int(result.split(',')[0]) y = int(result.split(',')[1]) xy_list = [] xy_list.append(x) xy_list.append(y) all_list.append(xy_list) for l in all_list: #x,y就是需要点击的某一个点的坐标 x = l[0] y = l[1] #move_to_element_with_offset就是将x,y的参照系转移到指定的标签中 #每一个动作连的操作都必须基于一个单独的动作连 ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform() sleep(2) bro.find_element_by_id('loginSub').click() sleep(10) bro.quit()