爬虫之selenium和PhantomJS
selenium
selenium是什么?
是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作
环境搭建
1.安装: pip install selenium 2.获取对应的驱动:以谷歌为例 2.1.查看谷歌浏览器帮助中的关于Google Chrome 查看版本 2.2映射表地址: # 查看对应的驱动
http://blog.csdn.net/huilan_same/article/details/51896672 2.3谷歌浏览器驱动下载地址: # 根据映射表下载对应驱动
http://chromedriver.storage.googleapis.com/index.html
使用简介
导包
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait
使用
driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') driver.get('http://www.baidu.com') input_tag = driver.find_element_by_id('kw') # 找到id=kw 的input标签 assert '百度一下' in driver.title # 页面标题 print(driver.title) # 打印当前页面的标题title input_tag.send_keys('python') # input框输入值'python' input_tag.send_keys(Keys.ENTER) # 按回车 print(driver.current_url) # 当前页面的url print(driver.page_source) # 当前页面的response print(browser.get_cookies()) # 当前页面的浏览器本地cookie # driver.close() # 关闭浏览器
select下拉菜单选择
# dirver = Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') # dirver.get('http://www.cma.gov.cn/') # print(dirver.page_source) # select_tag = Select(dirver.find_element(By.NAME, 'province')) # 获取下拉菜单标签 # select_tag.select_by_index(3) # 索引选择 # select_tag.select_by_value('河北') # 按照下拉框的值选择 # select_tag.select_by_visible_text('河北') # 按照下拉框可视化文本选择 # select_tag.deselect_all() # 取消选中所有值
行为链
# 行为链 driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') driver.get('http://www.baidu.com') input_tag = driver.find_element_by_id('kw') # 找到id=kw 的input标签 submit_tag = driver.find_element_by_id('su') # 找到id=su 的submit提交标签 actions = ActionChains(driver) # 浏览器驱动传进去实例化一个行为链对象 actions.move_to_element(input_tag) #移动到输入框上 actions.send_keys_to_element(input_tag, 'python') # 给输入框输入python actions.move_to_element(submit_tag) # 移动到提交元素上 actions.click(submit_tag) # 点击提交元素 actions.perform() # 执行行为链
cookie操作
driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') driver.get('http://www.baidu.com') [print(cookie) for cookie in driver.get_cookies()] # 获取所有浏览器上的cookie并展示 [driver.delete_cookie(cookie['domain']) for cookie in driver.get_cookies()] # 删除所有的cookie driver.delete_all_cookies() # 删除浏览器上当前页面的所有cookie
等待
1. 隐式等待
driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') driver.get('http://www.baidu.com') # driver.implicitly_wait(10) # 在找元素的时候等待10秒 如果找不到再报错 input_tag = driver.find_element_by_id('123') input_tag.send_keys('python') # input框输入值'python'
2. 显式等待
driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') driver.get('http://www.baidu.com') try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, 'somename')) ) # 等待10s 一直等待 id='somename'的标签出现。 如果没有再报错。 finally: driver.quit()
js代码执行和窗口切换
driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') driver.get('http://www.baidu.com') driver.execute_script('window.open("http://www.cma.gov.cn/")') # 执行js代码 print(driver.current_url) # https://www.baidu.com/ driver.switch_to_window(driver.window_handles[1]) # 类似于列表操作 print(driver.current_url) # http://www.cma.gov.cn/
ip代理
driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\chromedriver_win32\chromedriver.exe') options = webdriver.ChromeOptions() # 是指谷歌浏览器的选项信息 ip = 'http://125.123.136.226:9999' # 代理ip options.add_argument(f"--proxy-server={ip}") # 使用代理ip driver.get('http://httpbin.org/ip')
注意:如果是Anaconda3的jupyter的情况,不能直接下载到本地的cpython解释器 要在Anaconda3\Scripts中指定下载
示例:先运行下看下结果
from time import sleep from selenium import webdriver # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的 driver = webdriver.Chrome(r'F:\Python\10爬虫\包\chromedriver_win32\chromedriver.exe') # 用get打开百度页面 driver.get("http://www.baidu.com") # 查找页面的“设置”选项,并进行点击 driver.find_elements_by_link_text('设置')[0].click() sleep(2) # # 打开设置后找到“搜索设置”选项,设置为每页显示50条 driver.find_elements_by_link_text('搜索设置')[0].click() sleep(2) # 选中每页显示50条 m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 点击保存设置 driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 处理弹出的警告页面 确定accept() 和 取消dismiss() driver.switch_to_alert().accept() sleep(2) # 找到百度的输入框,并输入 美女 driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 点击搜索按钮 driver.find_element_by_id('su').click() sleep(2) # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面 driver.find_elements_by_link_text('美女_百度图片')[0].click() sleep(3) # 关闭浏览器 driver.quit()
代码介绍:
#导包 from selenium import webdriver #创建浏览器对象,通过该对象可以操作浏览器 browser = webdriver.Chrome('驱动路径') #使用浏览器发起指定请求 browser.get(url) #使用下面的方法,查找指定的元素进行操作即可 find_element_by_id 根据id找节点 find_elements_by_name 根据name找 find_elements_by_xpath 根据xpath查找 find_elements_by_tag_name 根据标签名找 find_elements_by_class_name 根据class名字查找
phantomJs
PhantomJS是一款无界面的浏览器,其自动化操作流程和上述操作谷歌浏览器是一致的。由于是无界面的,为了能够展示自动化操作流程,PhantomJS为用户提供了一个截屏的功能,使用save_screenshot函数实现。
示例:
from time import sleep from selenium import webdriver # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的 driver = webdriver.Chrome(r'F:\Python\10爬虫\包\chromedriver_win32\chromedriver.exe') # 用get打开百度页面 driver.get("http://www.baidu.com") # 查找页面的“设置”选项,并进行点击 driver.find_elements_by_link_text('设置')[0].click() sleep(2) # # 打开设置后找到“搜索设置”选项,设置为每页显示50条 driver.find_elements_by_link_text('搜索设置')[0].click() sleep(2) # 选中每页显示50条 m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 点击保存设置 driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 处理弹出的警告页面 确定accept() 和 取消dismiss() driver.switch_to_alert().accept() sleep(2) # 找到百度的输入框,并输入 美女 driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 点击搜索按钮 driver.find_element_by_id('su').click() sleep(2) # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面 driver.find_elements_by_link_text('美女_百度图片')[0].click() sleep(3) # 关闭浏览器 driver.quit()
谷歌无界面使用
# selenium 对 无头谷歌 的调用 ######################################################### #固定格式 from selenium import webdriver import time from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') ######################################################### path = r'F:\Python\视屏\10爬虫\包\chromedriver_win32\chromedriver.exe' bro = webdriver.Chrome(executable_path=path,chrome_options=chrome_options) # 此时 属于无界面的调用谷歌浏览器 # 请求的发送 bro.get(url='https://www.baidu.com') #根据find系列的函数定位到指定的标签 baidu_input = bro.find_element_by_id('kw') baidu_input.send_keys('python') # 百度搜索框输入 python time.sleep(0.5) bro.find_element_by_id('su').click() # 找到百度一下 time.sleep(1) response = bro.find_element_by_xpath('//*[@id="1"]/h3/a[1]').click() time.sleep(6) bro.quit()
重点:selenium+phantomjs 就是爬虫终极解决方案:有些网站上的内容信息是通过动态加载js形成的,所以使用普通爬虫程序无法回去动态加载的js内容。例如豆瓣电影中的电影信息是通过下拉操作动态加载更多的电影信息。
#需求:爬取豆瓣电影动态加载出的电影详情数据
from time import sleep from selenium import webdriver # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的 driver = webdriver.Chrome(r'F:\Python\视屏\10爬虫\包\chromedriver_win32\chromedriver.exe') url = 'https://movie.douban.com/typerank?type_name=%E7%88%B1%E6%83%85&type=13&interval_id=100:90&action=' # 豆瓣的url driver.get(url=url) # 调用浏览器访问豆瓣 js = 'window.scrollTo(0,document.body.scrollHeight)' # 滚动下拉当前屏幕对应像素的js代码 driver.execute_script(js) # 下拉滚动第一次 sleep(2) driver.execute_script(js) # 下拉滚动第二次 sleep(2) driver.execute_script(js) # 下拉滚动第三次 sleep(2) page_text = driver.page_source # 类似requests.get(url).text # print(page_text) with open('./douban.html','w',encoding='utf-8') as fp: fp.write(page_text) bro.quit()
qq空间登录爬取
from time import sleep from selenium import webdriver from lxml import etree #登录qq空间 bro = webdriver.Chrome(executable_path=r'F:\Python\视屏\10爬虫\包\chromedriver_win32\chromedriver.exe') url = 'https://qzone.qq.com/' #请求的发送 bro.get(url=url) sleep(1) #定位到指定的iframe # 使用的组件嵌套 点位组件 bro.switch_to.frame('login_frame') bro.find_element_by_id('switcher_plogin').click() # 定位切换账号密码登录 sleep(1) userName = bro.find_element_by_id('u') # 账号输入框 userName.send_keys('qq账号') passWord = bro.find_element_by_id('p') # 密码输入栏 passWord.send_keys('qq密码.') sleep(1) bro.find_element_by_id('login_button').click() # 点击登录 sleep(1) js = 'window.scrollTo(0,document.body.scrollHeight)' # 向下滚动的js代码 bro.execute_script(js) # 1次 sleep(3) bro.execute_script(js) # 2次 sleep(3) bro.execute_script(js) # 3次 sleep(3) bro.execute_script(js) # 3次 sleep(3) bro.execute_script(js) # 3次 sleep(3) page_text = bro.page_source # 获取页面的response.text的内容 print(page_text) sleep(5) #解析 tree = etree.HTML(page_text) # DOM数 div_list = tree.xpath('//div[@class="f-info qz_info_cut"] | //div[@class="f-info"]') # 获取 说说 或者其他转发dom节点 for div in div_list: text = div.xpath('.//text()') # 得到每一个节点的文本内容 text = "".join(text) print(text) bro.quit()