文章目录
- 一、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 Optionsclass 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 Optionsclass 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)# 隐式等待10sself.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 Optionsclass 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_sourceself.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()