1.selenium模块的基本使用
问题:selenium模块与爬虫之间具有怎样的关联?
-便捷的获取网站中动态加载的数据
-便捷实现模拟登陆
什么是selenium模块?
-基于浏览器自动化的一个模块。
selenium使用流程:
-环境安装:pip install selenium
-下载一个浏览器的驱动程序 最新火狐浏览器驱动下载地址:https://github.com/mozilla/geckodriver/releases
-驱动程序和浏览器的映射关系
-实例化一个浏览器对象:
-编写基于浏览器自动化的操作代码
-发起请求:get(url)
-标签定位:find系列的方法
-标签交互:send_keys(‘xxx’)
-执行js程序:excute_script(‘jsCode’)
-前进,后退:back(),forward()
-关闭浏览器:quit()
爬取药监局企业名称
from selenium import webdriver
from lxml import etree
from time import sleep
#实例化一个浏览器对象(传入浏览器的驱动)
bro = webdriver.Firefox(executable_path='F:/python_test/geckodriver.exe')
#让浏览器发起一个指定url的请求
bro.get('http://scxk.nmpa.gov.cn:81/xk/')
#获取浏览器当前页面的页面源码数据
page_text = bro.page_source
#解析企业名称
tree = etree.HTML(page_text)
li_list = tree.xpath('//*[@id="gzlist"]/li')
for li in li_list:
name = li.xpath('./dl/@title')[0]
print(name)
sleep(5)
bro.quit()
2.selenium其他自动化操作
让浏览器向下滚动一页操作
基于浏览器自动化的操作代码
-发起请求:get(url)
-标签定位:find系列的方法
-标签交互:send_keys(‘xxx’)
-执行js程序:excute_script(‘jsCode’)
-前进,后退:back(),forward()
-关闭浏览器:quit()
from selenium import webdriver
from time import sleep
bro = webdriver.Firefox(executable_path='F:/python_test/geckodriver.exe')
bro.get('https://www.taobao.com/')
#标签定位
search_input = bro.find_element_by_xpath('//*[@id="q"]')
#标签的交互
search_input.send_keys('matepad Pro')
#执行一组js程序 滚轮滚动一个高度
#window.scrollTo(0,document.body.scrollHeight)
bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
sleep(2)
#点击搜索按钮
btn = bro.find_element_by_css_selector('.btn-search')#class类中有空格的话,只能选择空格左右中的一侧 find_element_by_css_selector element后无s
btn.click()
bro.get('https://fanyi.baidu.com/?aldtype=16047#en/zh/console')
sleep(2)
#回退
bro.back()
sleep(2)
bro.forward()
sleep(5)
bro.quit()
3.selenium处理iframe+动作链
代码中使用的网站https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
-如果定位的标签存在于iframe标签之中,则必须使用switch_to.frame(id)
-动作链(拖动):from selenium.webdriver import ActionChains
-实例化一个动作链对象:action = ActionChains(bro)
-click_and_hold(div):长按且点击操作
-move_by_offset(x,y)
-perform()让动作链立即执行
-action.release()释放动作链对象
from selenium import webdriver
from time import sleep
#导入动作链对应的类
from selenium.webdriver import ActionChains
bro = webdriver.Firefox(executable_path='F:/python_test/geckodriver.exe')
bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
#如果定位的标签是定位在iframe标签中的,则必须再进行如下操作再进行标签定位
bro.switch_to.frame('iframeResult') #iframeResult是所需要调用div标签所在的iframe的id值,达到切换浏览器标签的作用域。默认是定位到外部大的html中
div = bro.find_elements_by_id('draggable')[0]
#动作链
action = ActionChains(bro)
#点击长按指定的标签
action.click_and_hold(div)
for i in range(5):
#move_by_offset(x,y):x水平方向,y竖直方向
action.move_by_offset(17,0).perform()#.perform()表示立即执行动作链操作,向右偏移17个像素,纵方向不变
sleep(0.3)
#释放动作链
action.release()
bro.quit()
4.selenium的模拟登录QQ空间
from selenium import webdriver
from time import sleep
bro = webdriver.Firefox(executable_path='F:/python_test/geckodriver.exe')
bro.get('https://qzone.qq.com/')
bro.switch_to.frame('login_frame')
a_tag = bro.find_elements_by_id('switcher_plogin')[0]
a_tag.click()
UeserName_tag = bro.find_element_by_id('u')
Password_tag = bro.find_element_by_id('p')
sleep(1)
UeserName_tag.send_keys('123456')#用自己的账户
sleep(1)
Password_tag.send_keys('123456')#自己的密码
sleep(1)
btn = bro.find_element_by_id('login_button')
btn.click()
sleep(3)
bro.quit()
5.无头浏览器+反检测
from selenium import webdriver
from time import sleep
#实现无可视化界面
from selenium.webdriver.firefox.options import Options
#实现规避检测
from selenium.webdriver import FirefoxOptions
#实现无可视化界面的操作
firefox_options = Options()
firefox_options.add_argument('--headless')
firefox_options.add_argument('--disable-gpu')
'''
#实现规避检测 火狐浏览器无法实现规避检测操作 需要使用谷歌 浏览器 详情网址参考https://www.cnblogs.com/guniang/p/11727492.html
option = FirefoxOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
'''
#如何实现让selenium规避被检测到的风险
bro = webdriver.Firefox(executable_path='F:/python_test/geckodriver.exe',firefox_options=firefox_options,options=option)
#无可视化界面(无头浏览器) phantomJs
bro.get('https://www.baidu.com')
print(bro.page_source)
sleep(2)
bro.quit()
6.12306模拟登录
-超级鹰:http://www.chaojiying.com/
-注册:普通用户
-登录:普通用户
-题分查询:充值
-创建一个软件(id)
-下载示例代码
-12306模拟登录编码流程:
-使用selenium打开登录页面
-对当期selenium打开的这张页面进行截图
-对当前图片局部区域(验证码图片)进行裁剪
-好处:将验证码图片和模拟登录进行一一对应。
-使用超级鹰识别验证码图片(坐标数据)
火狐浏览器配置文件参考相关网址 https://www.cnblogs.com/eastonliu/p/9083982.html
import requests
from hashlib import md5
from selenium import webdriver
import time
from PIL import Image
import base64
from selenium.webdriver import ActionChains
# base64图片解码
def stringToBase64(imgsrc):
img = str(imgsrc)
img = img[img.find("base64,") + 7:]
#print("base64,图片字符串:{0}".format(img))
return base64.b64decode(img)
# base64图片解码
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
if __name__ == '__main__':
#上述代码是超级鹰提供的示例代码
#配置驱动程序的配置
#配置文件路径
profile_path = 'C:/Users/liber/AppData/Roaming/Mozilla/Firefox/Profiles/9kc38z3h.default-release'
#加载配置数据
profile = webdriver.FirefoxProfile(profile_path)
#使用selenium打开登录页面
bro = webdriver.Firefox(firefox_profile=profile,executable_path='F:/python_test/geckodriver.exe')
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
#点击账号登录
btn = bro.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a')
btn.click()
#向下翻动一下页面
bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(1)
#裁剪出错可能是浏览器缩放比例问题
'''
#save_screenshot作用:将当前页面截图并保存
bro.save_screenshot('F:/python_test/aa.png')
#确定验证码图片左上角和右下角的坐标(裁剪的区域就确定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location#验证码图片左上角的坐标 x,y
print('location:',location)
size = code_img_ele.size#验证码图片对应的长和宽
print('size:',size)
#左上角和右下角的坐标
rangle = (
int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height'])
)
#至此验证码图片就确定下来了
i = Image.open('F:/python_test/aa.png')
code_img_name = 'F:/python_test/code.png'
#crop根据指定区域进行图片裁剪
frame = i.crop(rangle)
frame.save(code_img_name)#裁剪出错可能是浏览器缩放比例问题
'''
#利用base64方法获取验证码图片
check_img = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
# 获取地址图片,对bs64图片字符串进行解码
with open("F:/python_test/code.png","wb") as f:
f.write(stringToBase64(check_img.get_attribute("src")))
print("获取图片")
# 获取地址图片,对bs64图片字符串进行解码
chaojiying = Chaojiying_Client('952246330','Lbh2683072','907788')#用户中心>>软件ID生成一个替换96001
im = open('F:/python_test/code.png', 'rb').read()#本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
print(chaojiying.PostPic(im, 9004)['pic_str'])
result = chaojiying.PostPic(im, 9004)['pic_str']
all_list = []#存储即将要点击点的坐标 [[x1,y1],[x2,y2]]
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:
xy_list = []
x = int(result.split(',')[0])
y = int(result.split(',')[1])
xy_list.append(x)
xy_list.append(y)
all_list.append(xy_list)
print(all_list)
action = ActionChains(bro)
#遍历列表,使用动作链对每一个列表元素对应的元素位置x,y指定的位置进行点击操作
for l in all_list:
x = l[0]
y = l[1]
ActionChains(bro).move_to_element_with_offset(check_img,x,y).click().perform()
time.sleep(0.5)
bro.find_element_by_xpath('//*[@id="J-userName"]').send_keys('xxxxx')
time.sleep(0.5)
bro.find_element_by_xpath('//*[@id="J-password"]').send_keys('xxxxx')
time.sleep(0.5)
bro.find_element_by_xpath('//*[@id="J-login"]').click()
time.sleep(3)
bro.quit()