爬虫-Selenium模块
一、基本使用
1.1 安装
#下载浏览器驱动
Selenium3.x调用浏览器必须有一个webdriver驱动文件
chrom:https://chromedriver.storage.googleapis.com/index.html?path=2.35/ 或者 https://vikyd.github.io/download-chromium-history-version/#/
firfox:https://github.com/mozilla/geckodriver/releases
Note: 注意电脑分辨率需要配置为100%,不然出现异常.
1.2 标签定位
Selenium4.x 语法有变化,请使用最新的语法。
定位一个元素 | 定位多个元素 | 含义 |
---|---|---|
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_text | 通过完整超链接定位 |
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选择器进行定位 |
示例:
#html文件
<html>
<head>
<body link="#0000cc">
<a id="result_logo" href="/" onmousedown="return c({'fm':'tab','tab':'logo'})">
<form id="form" class="fm" name="f" action="/s">
<span class="soutu-btn"></span>
<input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off">
#定位方式
dr.find_element_by_id("kw")
dr.find_element_by_name("wd")
dr.find_element_by_class_name("s_ipt")
dr.find_element_by_tag_name("input")
dr.find_element_by_xpath("//*[@id='kw']")
dr.find_element_by_xpath("//*[@name='wd']")
dr.find_element_by_xpath("//input[@class='s_ipt']")
dr.find_element_by_xpath("/html/body/form/span/input")
dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
dr.find_element_by_xpath("//form[@id='form']/span/input")
dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
1.3 webdriver模块控制浏览器的常用方法
from selenium import webdriver
from time import sleep
browser = webdriver.Firefox(executable_path ="F:\GeckoDriver\geckodriver")
browser.get("https://www.baidu.com/")
1、配置浏览器大小
browser.set_window_size()
2、浏览器后退
browser.back()
3、控制浏览器前进
browser.forward()
4、刷新当前页面
browser.refresh()
5、清除文本
browser.clear()
6、模拟按键输入
browser.send_keys (value)
7、单击元素
browser.click()
8、用于提交表单
browser.submit()
9、获取元素属性值
browser.get_attribute(name)
10、设置该元素是否用户可见
browser.is_displayed()
11、获取元素的文本
browser.size()
12、返回元素的尺寸
browser.text()
13、关闭浏览器全部标签页
driver.quit()
14、.关闭当前标签页(从标签页A打开新的标签页B,关闭标签页A)
driver.close()
1.4 webdriver模块键盘操作
模拟键盘按键 | 说明 |
---|---|
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 |
1.5 下拉框操作
Select类的方法
方法 | 说明 |
---|---|
select_by_value(“选择值”) | select标签的value属性的值 |
select_by_index(“索引值”) | 下拉框的索引 |
select_by_visible_testx(“文本值”) | 下拉框的文本值 |
有时我们会碰到下拉框,WebDriver提供了Select类来处理下拉框。
from selenium import webdriver
from selenium.webdriver.support.select import Select
from time import sleep
driver = webdriver.Chrome("F:\Chrome\ChromeDriver\chromedriver")
driver.implicitly_wait(10)
driver.get('http://www.baidu.com')
#1.鼠标悬停至“设置”链接
driver.find_element_by_link_text('设置').click()
sleep(1)
#2.打开搜索设置
driver.find_element_by_link_text("搜索设置").click()
sleep(2)
#3.搜索结果显示条数
sel = driver.find_element_by_xpath("//select[@id='nr']")
Select(sel).select_by_value('50') # 显示50条
sleep(3)
driver.quit()
二、爬取示例
- 案列一
from lxml import etree
from selenium import webdriver
import time
bro = webdriver.Chrome(executable_path='./chromedriver')
url = 'http://125.35.6.84:81/xk/'
bro.get(url)
#爬取药监总局中前三页的数据
time.sleep(2)
#获取当前浏览器显示的页面源码数据
page_text = bro.page_source#该属性可以返回当前页面所有被加载出来的页面源码数据
#列表:存放前三页的页面源码数据
all_page_text = [page_text]
for i in range(3):
#进行下一页按钮的定位且对其进行点击
a_tag = bro.find_element_by_xpath('//*[@id="pageIto_next"]')
a_tag.click()
time.sleep(1)
all_page_text.append(bro.page_source)
for page_text in all_page_text:
#解析企业名称(动态加载的数据)
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)
time.sleep(1)
bro.quit()
- 案列二
#12306的模拟登录
#url:https://kyfw.12306.cn/otn/login/init
#超级鹰的示例代码
#!/usr/bin/env python
# coding:utf-8
#-------------------------超级鹰调用代码----------------------------------
import requests
from hashlib import md5
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()
#自己封装的一个识别验证码图片的函数
def transform_code_img(imgPath,imgType):
chaojiying = Chaojiying_Client('bobo', 'bobo', '999999') #用户中心>>软件ID 生成一个替换 96001
im = open(imgPath, 'rb').read()#本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
return chaojiying.PostPic(im, imgType)['pic_str']#1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
#-------------------------END----------------------------------
from selenium.webdriver import ActionChains#动作链
from PIL import Image#进行截图裁剪
#pip install PIL
#pip install Pillow
from selenium import webdriver
bro = webdriver.Chrome(executable_path='./chromedriver')
url = 'https://kyfw.12306.cn/otn/login/init'
bro.get(url)
time.sleep(2)#保证验证码图片可以被刷新出来
#录入用户名和密码
userName_tag = bro.find_element_by_id('username')
userName_tag.send_keys('bobo123')
pwd_tag = bro.find_element_by_id('password')
pwd_tag.send_keys('123456')
#验证码识别处理:验证码应该被截屏截取下来而不应该单独请求
bro.save_screenshot('./main.png')#main.png表示的是登录页面对应的图片
#在main.png中将验证码的局部图片进行裁剪,
#只需要将验证码图片的左下角和右上角的两点坐标得到,则就可以获取裁剪的矩形区域
#验证码图片的img标签
code_img_tag = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
location = code_img_tag.location#当前标签在页面中左下角的坐标
size = code_img_tag.size#当前标签在页面中的尺寸(长款)
#裁剪的矩形区域
rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))
#基于Image类提供的工具进行裁剪
i = Image.open('./main.png')
frame = i.crop(rangle)
frame.save('./code.png')#code.png就是验证码图片
#识别验证码图片即可
result = transform_code_img('./code.png',9004)
print(result)#返回的需要点击验证码上子图的坐标 x1,y1|x2,y2
#需要将x1,y1|x2,y2转换成[[x1,y1],[x2,y2]]
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:
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)
print(all_list)
for pos in all_list:
x = pos[0]
y = pos[1]
#x,y就是需要点击的一个点的坐标
ActionChains(bro).move_to_element_with_offset(code_img_tag,x,y).click().perform()
time.sleep(1)
#点击登录按钮
bro.find_element_by_id('loginSub').click()
time.sleep(3)
bro.quit()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)