赞
踩
selenium是第三方自动化库,完全用来模拟人对浏览器做任何操作,通常用于爬虫和自动化测试。需要先安装,安装命令是:
pip install selenium
安装好之后暂时还用不了,需要安装谷歌驱动chromedriver,下载驱动的网址如下:
https://googlechromelabs.github.io/chrome-for-testing/#stable
下载好之后解压,可以看到chromedriver.exe,将其配置为环境变量即可。
具体用法代码如下:
# 从selenium库中导入浏览器驱动
from selenium import webdriver
# 创建谷歌浏览器对象
browser = webdriver.Chrome()
# 准备网址
url = 'https://www.baidu.com'
# 对网址发起请求
browser.get(url)
如果有的小伙伴使用时在控制台出现警告字符,想去除警告的话在开头加上如下代码:
import warnings
warnings.filterwarnings('ignore')
还有的小伙伴有强迫症,不喜欢看到浏览器上方显示的“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)
当然谷歌浏览器一般都会有检测机制,可以检测出我们是真实的人还是代码,所以也要加上防检测代码,具体代码模版如下:
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)
程序运行的速度很快,但是一般电脑配置都参差不齐,如果电脑配置差会导致程序报错,程序运行到后面而网页还没加载好,针对这种问题,我们要设置延时,设置延时方式有两种
强制延时使用time模块,里面的sleep()方法,代码示例如下:
# 导入time模块
import time
# 程序执行到此沉睡5s,而后往下执行
time.sleep(5)
print('ok')
隐式延时又叫隐式等待,比如我去请求某个网站,设置隐式等待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。
运行代码之后我们会发现浏览器窗口只有屏幕一半大小,可以设置为全屏,具体代码如下:
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标签作用其实相当于给网页中套了一个网页,比如下面代码所示:
<!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空间登录里面就使用了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()
案例实战:使用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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。