5. 基于Selenium实现爬虫
selenium
- 概念:基于浏览器自动化的模块
- 自动化:可以通过代码指定一系列的行为动作,然后将起作用在浏览器中
- 安装:pip install selenium
- selenium和爬虫之间的关系
-
- 便捷的捕获到任意形式动态加载的数据
-
- 模拟登录
-
- 谷歌驱动下载:http://chromedriver.storage.googleapis.com/index.html
from selenium import webdriver
import time
# 1. 基于浏览器的驱动程序实例化一个浏览器对象
bro = webdriver.Chrome(executable_path="./chromefriver")
# 2. 对目标网站发起请求
bro.get('https://jd.com')
# 3. 标签定位
search_text = bro.find_element_by_xpath('//*[@id="key"]')
search_text.send_keys('iphoneX')
btn = bro.find_element_by_xpath("//*[#id='search']/div/div[2]/button")
btn.click()
time.sleep(2)
# 在搜索结果页面进行滚轮向下滑动的操作(执行js操作:js注入)
bro.execute_script("window.scrollTo(0,document.body.scrollHeight)")
time.sleep(2)
bro.quit()
from selenium import webdriver
import time
# 后面是你的浏览器驱动位置,记得在前面加上r'',r是防止字符转义
driver = webdriver.Chrome(r'驱动程序路径')
# 用get打开百度首页
driver.get('https://www.baidu,com')
# 查找出首页的"设置"选项,并进行点击
driver.find_elements_by_link_text('设置')[0].click()
time.sleep()
# 打开设置后找到'搜索设置'选项,设置为煤业显示50条
driver.find_elements_by_link_text("搜索设置")[0].click()
time.sleep()
# 选中每页显示50条
m = driver.find_element_by_id('nr')
time.sleep()
m.find_element_by_xpath('//*[@id="nr"]/option[3]').click()
m.find_element_by_xpath('.//option[3]').click()
time.sleep()
# 点击保存设置
driver.find_elements_by_class_name('prefpanelgo')[0].click()
timee.sleep()
# 处理弹出的警告框,确定accept() 和 取消dismiss()
driver.switch_to_alert().accept()
time.sleep()
# 找到百度的搜索框,并输入'美女'
driver.find_element_by_id('kw').send_keys('美女')
time.sleep()
# 点击搜索按钮
driver.find_element_by_id('su').click()
time.sleep()
# 再打开的页面中找到“Selenium - 开源中国社区”,并打开这个也买你
driver.find_elements_by_link_text('美女_百度图片')[0].click()
time.sleep()
# 关闭浏览器
driver.quit()
- 如何捕获动态加载的数据
- 药监总局为例:http://125.35.6.84:81/xk/
- 前三页所有企业名称爬取
url = 'http://125.35.6.84:81/xk/'
bro = webdriver.Chrome(executable_path='./chromedriver')
bro.get(url)
page_text_list = [] # 每一页的页面源码数据
time.sleep()
# 捕获到当前页面对应的页面源码数据
page_text = bro.page_source() # 当前页面全部加载完毕后对应的所有的数据
# 点击下一页
next_page = bro.find_element_by_xpath('//*[@id="pageIto_next"]')
next_page.click()
bro.page_source
tree = etree.HTML(page_text)
list_list = tree.xpath('//*[@id="gzlist"]/li')
for li in li_list:
name = li.xpath('./dl/@title')[0]
print(name)
time.sleep(2)
bro.quit()
- selenium的弊端
- 效率低
动作链ActionChains
- 动作链:一系列连续的动作(滑动动作)
from selenium.webdriver import ActionChains # 动作链
url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
bro = webdriver.Chrome(executable='./chromedriver')
bro.get(url)
time.sleep(1)
# 如果通过find系列的函数进行标签定位,如果标签是存在与iframe里面,则会定位失败
# 解决方案:使用switch_to即可
bro.switch_to.frame('iframeResult')
div_tag = bro.find_element_by_xpath('//*[@id="draggable"]')
# 对div_tag进行滑动操作
action = ActionChains(bro)
action.click_and_hold(div_tag) # 点击且长按
for i in range(6):
# preform让动作链立即执行
action.move_by_offset(10,15).preform()
time.sleep(0.5)
action.release()
bro.quit()
-
如何selenium规避检测
- 有的网站会检测请求是否为selenium发起的,如果是的话则让该次请求失败
- 规避检测的方法
- selenium接管chrome浏览器
-
实现步骤:
-
- 必须将你的电脑中安装的谷歌浏览器的驱动程序所在的目录找到。且将目录添加到环境变量中。
-
-
打开cmd,在命令行输入命令
- chrome.exe --remote-debugging-port=9222 -user-data-dir="一个空的文件夹的目录"
- 指定执行结束后,会打开你本机安装好的谷歌浏览器
-
-
- 执行如下代码:可以使用下属代码接管步骤2打开的真实的浏览器
-
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Oprions()
chrome_options.add_experimental_option(debuggerAddress),'1237.0.0.1:9222'
chrome_driver = '你谷歌驱动的路径'
driver = webdriver.Chrome(chrome_driver,chrome_options=chrome_options)
print(driver.title)
- 无头浏览器(无可视化界面的浏览器)
- 谷歌无头浏览器
- phantomJs
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
# 创建一个参数对象,用来控制chrome以无头界面模式打开
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 驱动路径
path = r'本机谷歌驱动的路径'
# 创建浏览器对象
browser = webdriver.Chrome(executable_path=path,chrome_options=chrome_options)
# 上网
url = 'https://www.baidu.com'
browser.get(url)
time.sleep(3)
# 截图
browser.save_screeshot('baidu.png')
print(browser.page_source)
browser.quit()
基本方法总结
- 浏览器方法
- brower.get() 请求url
- brower.quit() 关闭浏览器
- brower.close() 关闭当前页面
- brower.page_source 获取源代码
- brower.page_sourse.find('keyword') 在源代码中查找
- brower.maximize_window() 窗口最大化
- 节点操作
- node.send_keys("") 在文本框内填入内容
- node.click() 点击
- node.get_attribute('href/id/name') 获取属性
- node.text 获取节点文本
- 其他方法
- brower.get_cookies() 获取cookies
- brower.current_url 获取当前页面url
- brower.page_source 获取页面源代码
- 切换Frame
- Selenium打开页面后,默认是在父级Frame里面操作,如页面中还有子Frame,Selenium不能获取到子Frame里面的节点的,这是需要使用switch_to_frame方法来切换Frame
- 示例:brower.switch_to_frame('id name')
- Selenium打开页面后,默认是在父级Frame里面操作,如页面中还有子Frame,Selenium不能获取到子Frame里面的节点的,这是需要使用switch_to_frame方法来切换Frame
- 查找单节点
- brower.find_element_by_name('sunrisecai') 按照name值查找
- brower.find_element_by_id("sunrisecai") 按照ID值查找
- brower.find_element_by_xpath("sunrisecai") 按照xpath语法查找
- brower.find_element_by_css_selector("sunrisecai") 按照css选择器差找
- 查找多节点
- brower.find_elements_by_name('sunrisecai') 按照name值查找
- brower.find_elements_by_id("sunrisecai") 按照ID值查找
- brower.find_elements_by_xpath("sunrisecai") 按照xpath语法查找
- brower.find_elements_by_css_selector("sunrisecai") 按照css选择器差找
- 填写表单
- 首先定位文本框:text_box=brower.find_element_by_xpath("XXX")
- 清空文本框:text_box.clear()
- 输入文本内容:text_box.send_key_words("xxx")
- 模拟登陆:text.box=brower.find_element_by_xpath('XXX').click()
- 执行JS
- 页面进度条拉取
- brower.execute_script('window.scrollTo(0,document.body.scrollHeight)')
- 页面进度条拉取
- 浏览器等待方法:brower.implicitly_wait(10)