文章目录
- 一、selenium原理 + 安装
- 二、selenium使用
- 1.创建浏览器对象,访问网址
- 2.消除警告提示
- 3.不显示浏览器中受控制字样
- 4.防检测
- 5.设置延时
- 5.1强制延时
- 5.2隐式延时
- 6.设置浏览器窗口大小
- 三、案例实战:百度搜索
- 四、iframe标签
- 五、案例实战:QQ空间登录
- 六、获取网页数据两种方式
- 七、案例实战:艺恩票房信息
一、selenium原理 + 安装
selenium是第三方自动化库,完全用来模拟人对浏览器做任何操作,通常用于爬虫和自动化测试。需要先安装,安装命令是:
pip install selenium
安装好之后暂时还用不了,需要安装谷歌驱动chromedriver,下载驱动的网址如下:
https://googlechromelabs.github.io/chrome-for-testing/#stable
下载好之后解压,可以看到chromedriver.exe,将其配置为环境变量即可。
二、selenium使用
1.创建浏览器对象,访问网址
具体用法代码如下:
# 从selenium库中导入浏览器驱动
from selenium import webdriver
# 创建谷歌浏览器对象
browser = webdriver.Chrome()
# 准备网址
url = 'https://www.baidu.com'
# 对网址发起请求
browser.get(url)
2.消除警告提示
如果有的小伙伴使用时在控制台出现警告字符,想去除警告的话在开头加上如下代码:
import warnings
warnings.filterwarnings('ignore')
3.不显示浏览器中受控制字样
还有的小伙伴有强迫症,不喜欢看到浏览器上方显示的“Chrome正受到自动…”字样,如下图:
这个也可以去掉,代码如下所示:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 创建Chrome浏览器对象
browser = webdriver.Chrome(options=chrome_options)
4.防检测
当然谷歌浏览器一般都会有检测机制,可以检测出我们是真实的人还是代码,所以也要加上防检测代码,具体代码模版如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 创建Chrome浏览器对象
browser = webdriver.Chrome(options=chrome_options)
# 防检测
browser.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source": " Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) "
}
)
# 准备网址
url = ''
# 对网址发起请求
browser.get(url)
5.设置延时
程序运行的速度很快,但是一般电脑配置都参差不齐,如果电脑配置差会导致程序报错,程序运行到后面而网页还没加载好,针对这种问题,我们要设置延时,设置延时方式有两种
5.1强制延时
强制延时使用time模块,里面的sleep()方法,代码示例如下:
# 导入time模块
import time
# 程序执行到此沉睡5s,而后往下执行
time.sleep(5)
print('ok')
5.2隐式延时
隐式延时又叫隐式等待,比如我去请求某个网站,设置隐式等待20s,但是我1s就访问成功了,那么剩下19s就不会等了,继续往下执行,换句话就是灵活等待。反之,如果20s内都没访问成功,则不再等待,继续往下执行剩余代码。
设置隐式延时代码如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 创建Chrome浏览器对象
browser = webdriver.Chrome(options=chrome_options)
# 防检测
browser.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source": " Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) "
}
)
# 准备网址
url = 'https://www.baidu.com'
# 对网址发起请求
browser.get(url)
# 设置隐式等待100s
browser.implicitly_wait(100)
print('ok')
运行之后会发现根本没有等100s,网站请求成功之后就执行了打印ok。
6.设置浏览器窗口大小
运行代码之后我们会发现浏览器窗口只有屏幕一半大小,可以设置为全屏,具体代码如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 创建Chrome浏览器对象
browser = webdriver.Chrome(options=chrome_options)
# 防检测
browser.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source": " Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) "
}
)
# 设置浏览器窗口为最大
browser.maximize_window()
# 准备网址
url = 'https://www.baidu.com'
# 对网址发起请求
browser.get(url)
三、案例实战:百度搜索
案例实战:使用selenium库实现百度搜索
全部代码如下:
import time
import warnings
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
class BdssSpider(object):
def __init__(self):
'''
1、初始化部分
'''
warnings.filterwarnings('ignore')
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
self.start_url = 'https://www.baidu.com'
self.driver = webdriver.Chrome(chrome_options)
self.driver.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source": " Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) "
}
)
self.driver.maximize_window()
def requests_start_url(self):
'''
2、访问起始网址
'''
self.driver.get(self.start_url)
self.driver.implicitly_wait(10)
self.find_element()
def find_element(self):
'''
3、输入内容,点击搜索按钮
'''
# 通过元素的id值定位,然后发送搜索关键字
self.driver.find_element(by=By.ID, value='kw').send_keys('风景')
time.sleep(1)
# 通过元素的id值定位,然后点击
self.driver.find_element(by=By.ID, value='su').click()
def main(self):
'''
逻辑控制部分
'''
self.requests_start_url()
input('Press any key to quit...')
if __name__ == '__main__':
bdss = BdssSpider()
bdss.main()
四、iframe标签
iframe标签作用其实相当于给网页中套了一个网页,比如下面代码所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<input type="text", id="p1">
<iframe>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<input type="text", id="p2">
</body>
</html>
</iframe>
</body>
</html>
如果想直接通过id="p2"定位到里面的input标签是定位不到的,因为只能定位到外面的html中的input标签,不能定位到里面嵌套的另外一个html文件。这时候如果要定位到里面的,就需要用到标签切换,那如何使用iframe标签切换呢?接下来通过一个案例实战来具体实现。
五、案例实战:QQ空间登录
QQ空间登录里面就使用了iframe标签嵌套了一个HTML代码,如下图所示:
所以正常使用selenium的标签定位是定位不到的,这就是难点,接下来看看如何用iframe标签切换来解决,具体代码如下:
import time
import warnings
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
class QqdlSpider(object):
def __init__(self):
'''
1、初始化部分
'''
# 去除警告
warnings.filterwarnings('ignore')
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
self.url = 'https://qzone.qq.com'
# 创建浏览器对象
self.driver = webdriver.Chrome(chrome_options)
# 防检测
self.driver.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source": " Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) "
}
)
# 浏览器窗口最大化
self.driver.maximize_window()
def open_url(self):
'''
2、访问QQ空间主页
'''
self.driver.get(self.url)
# 隐式等待10s
self.driver.implicitly_wait(10)
self.switch_login()
def switch_login(self):
'''
3、切换登录方式为密码登录
'''
# 找到iframe标签
iframe = self.driver.find_element(by=By.ID, value='login_frame')
# 切换到iframe里面
self.driver.switch_to.frame(iframe)
# 定位到密码登录标签并且点击
self.driver.find_element(by=By.XPATH, value='//*[@id="switcher_plogin"]').click()
self.login_account()
def login_account(self):
'''
4、输入用户名密码登录
'''
# 输入用户名
self.driver.find_element(by=By.XPATH, value='//*[@id="u"]').send_keys('QQ账号')
time.sleep(2)
# 输入密码
self.driver.find_element(by=By.XPATH, value='//*[@id="p"]').send_keys('QQ密码')
time.sleep(2)
# 点击登录
self.driver.find_element(by=By.XPATH, value='//*[@id="login_button"]').click()
def main(self):
'''
逻辑控制部分
'''
self.open_url()
input('Press any key to quit...')
if __name__ == '__main__':
qqdl = QqdlSpider()
qqdl.main()
六、获取网页数据两种方式
- 查找元素(find_element())→ 定位到具体标签元素
- 获取页面源码(page_source)→ 获取的是当前页面的所有数据,包含静态和动态数据都有
七、案例实战:艺恩票房信息
案例实战:使用selenium库爬取艺恩票房信息
效果如下图所示:
全部代码如下:
import time
import warnings
from lxml import etree
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class YepfSpider(object):
def __init__(self):
'''
1、初始化部分
'''
# 去除警告
warnings.filterwarnings('ignore')
# 创建ChromeOptions对象
chrome_options = Options()
# 添加启动参数,禁用浏览器自动化控制提示
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
self.url = 'https://www.endata.com.cn/BoxOffice/BO/Year/index.html'
# 创建浏览器对象
self.driver = webdriver.Chrome(chrome_options)
# 防检测
self.driver.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source": " Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) "
}
)
# 浏览器窗口最大化
self.driver.maximize_window()
def open_url(self):
'''
2、打开网址
'''
self.driver.get(self.url)
time.sleep(3)
self.get_response()
def get_response(self):
'''
3、获取网页源码
'''
# 获取网页源码
response = self.driver.page_source
self.parse_response(response)
def parse_response(self, response):
'''
4、xpath解析响应
'''
html_xpath = etree.HTML(response)
# 1、影片名称
movie_names = html_xpath.xpath('//td[@class="movie-name"]/a/p/text()')
# 2、类型
movie_types = html_xpath.xpath('//*[@id="TableList"]/table/tbody/tr/td[3]/text()')
# 3、总票房(万)
movie_boxes = [i.replace(',', '')+'万' for i in html_xpath.xpath('//*[@id="TableList"]/table/tbody/tr/td[4]/text()')]
# 4、国家及地区
movie_countries = html_xpath.xpath('//*[@id="TableList"]/table/tbody/tr/td[7]/text()')
# 5、上映日期
launch_dates = html_xpath.xpath('//*[@id="TableList"]/table/tbody/tr/td[8]/text()')
for movie_name, movie_type, movie_box, movie_country, launch_date in zip(movie_names, movie_types, movie_boxes, movie_countries, launch_dates):
print(movie_name, movie_type, movie_box, movie_country, launch_date, sep=' | ')
def main(self):
'''
逻辑控制部分
'''
self.open_url()
input('Press any key to quit...')
if __name__ == '__main__':
yepf = YepfSpider()
yepf.main()