使用slenium + driver实现万能爬虫
qingheluo2020-04-23清河洛329
通常各大网站都会有一定的反爬机制,既为了数据安全,也为了减小服务器压力,而常见反爬的手段都是识别非浏览器客户端,而selenium所做的事情,就是驱动真正的浏览器去执行请求和操作,只不过信号不是来源于鼠标,而是来源于selenium的API(selenium本是一个自动化的测试工具)自然人用户能做的一切,selenium几乎都可以通过API驱动浏览器去做,包括输入、点击、滑动,删除cookie等等selenium有很多语言的版本,如java,ruby,python等,python使用pip install selenium就可以安装1、chrome:https://sites.googl...
通常各大网站都会有一定的反爬机制,既为了数据安全,也为了减小服务器压力,而常见反爬的手段都是识别非浏览器客户端,而selenium所做的事情,就是驱动真正的浏览器去执行请求和操作,只不过信号不是来源于鼠标,而是来源于selenium的API(selenium本是一个自动化的测试工具)
自然人用户能做的一切,selenium几乎都可以通过API驱动浏览器去做,包括输入、点击、滑动,删除cookie等等
selenium有很多语言的版本,如java,ruby,python等,python使用pip install selenium就可以安装
1、chrome:https://sites.google.com/a/chromium.org/chromedriver/downloads 2、Firefox:https://github.com/mozilla/geckodriver/releases 3、Safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/ 4、Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ 下载对应的浏览器dirver后放到有执行权限的目录中
操作步骤
1、引入模块
from selenium import webdriver webdriver是专门用于操作浏览器的,不同的浏览器有各自对应的类
2、创建一个chrome对话
webdriver.Chrome(executable_path=‘chromedriver‘,port=0,options=None) executable_path:指定驱动程序文件,如果文件所在目录已经加入到环境变量PATH中可以省略该参数,否则就需要指定完整路径 chrome_options参数指定创建chrome对话的配置选项,以下两种方法(两种方法等价)可以创建一个配置选项对象 options = webdriver.chrome.options.Options() options = webdriver.ChromeOptions() 常用的添加配置项: options.add_argument(‘--headless‘) 无头模式,不打开浏览器窗口 options.add_argument(‘--proxy-server=http://ipaddress:port‘) 使用指定代理访问 options.binary_location(exe_path) 指定浏览器的运行程序,这个在指定chrome内核的其他浏览器程序时很有用 dirver_path=r‘D:\path\chromedirver.exe‘ driver=webdriver.chrome(executable_path=dirver_path,options=options)
3、使用chrome对话操作chrome浏览器
获取属性值: current_url:当前页面url name:当前driver的名称 title:当前页面的title window_handles:当前浏览器打开的标签列表 浏览器设置: get_network_conditions:获取Chrome网络设置的dict格式 implicitly_wait(timeout):设定每次打开页面查找元素的超时时间(秒) set_network_conditions():设置网络条件 set_page_load_timeout(timeout):设置页面加载超时 set_script_timeout(timeout):设置异步js脚本超时时间 浏览器操作: back():后退一步 close():关闭当前页面 forward():前进一步 fullscreen_window():全屏显示 get(url):在当前浏览器会话中加载网页 switch_to.window(driver.window_handles[index]): 使用数字索引切换到指定标签,第一个标签索引为0,然后从后向前,最后一个标签索引为1,倒数第2个标签索引为2,以此类推 launch_app(id):启动由id指定的Chrome应用程序 maximize_window():最大化当前窗口 minimize_window():最小化当前窗口 page_source:返回当前页面的源码 quit():退出整个页面 refresh():刷新当前页面 cookie操作 add_cookie(cookie_dict):添加cookie delete_all_cookies():删除所有cookie delete_cookie(key):删除cookie中指定的key get_cookie(key):获取执行cookie制定key的值 get_cookies():以dict格式获取所有cookie 浏览器窗口位置大小 get_window_position():以dict格式返回当前窗口左上角所在屏幕坐标 get_window_rect():以dict格式返回当前窗口的高和宽还有左上角所在屏幕坐标 get_window_size():以dict格式返回当前窗口的宽和高 set_window_position(x,y):设置当前窗口左上角所在屏幕坐标 set_window_rect(x=None, y=None, width=None, height=None):设置当前窗口位置和大小 set_window_size(width, height):设置当前窗口大小 屏幕截图 get_screenshot_as_base64():返回当前窗口截图的base64格式 get_screenshot_as_file(file_name):以png格式保存当前窗口截图 get_screenshot_as_png():获取当前窗口截图的二进制数据 save_screenshot(png_filename):以png格式保存当前窗口截图 查找元素 find_element_by_*:查找单一元素,返回查找到的第一个元素 find_elements_by_*:返回列表,查找所有满足条件的元素 星号(*)表示的值有: class_name(class_name):按照css名称查找 css_selector(css_selector):按照css选择器查找 id(id):按照id查找 link_text(text):按a标签的文本查找 name(name):按照name值查找 partial_link_text(text):元素a标签文本的部分匹配来查找元素 tag_name(tag_name):按照标签名称查找 xpath(xpath_str):通过一个xpath语句查找 其他操作 execute_async_script(script, *args):执行异步js脚本 execute_script(script, *args):打开浏览器在执行其他交本之前执行指定js脚本 get_log(log_type):获取指定日志类型的日志,log_type的值:‘browser‘、‘driver‘、‘client‘、‘server‘ 滚动页面的2个方法 1、driver.execute_script("document.documentElement.scrollTop=1000") 整个页面向下偏移1000px 2.driver.execute_script("arguments[0].scrollIntoView(true/false);",driver.find_element_by_id(‘search‘)) 参数为true则页面移动至指定元素顶部和浏览器顶部对齐的位置 参数为false则页面移动至指定元素的底部和浏览器底部对齐的位置
4、查找到元素
查找到元素仍然有查找元素的所有方法,另外还有一些方法 clear():如果是文本输入元素,则清除文本 click():单击元素 get_attribute(attr):获取元素的给定属性 is_displayed():元素是否对用户可见 is_enabled():元素是否已启用 is_selected():是否选择了元素 rect:返回一个包含元素宽高和元素左上角坐标的dict screenshot(png_filename):将当前元素的屏幕截图保存成png文件 screenshot_as_base64():将当前元素的屏幕截图保存成png图片的base格式 screenshot_as_png(png_filename):将当前元素的屏幕截图保存成png文件 size():返回一个包含元素宽高的dict submit():提交一个表单 tag_name:该元素的标签名 text:获取元素的文本 send_keys(val1,val2,...valn):按参数顺序依次输入指定的字符串或按键组合 首先要导入按键模块: from selenium.webdriver.common.keys import Keys Keys有各种按键的常量 ADD(+),SUBTRACT(-),MULTIPLY(*),DIVIDE(/) DECIMAL(点‘.‘),EQUALS(=),SEMICOLON(分号冒号) TAB,ALT,LEFT_ALT,CONTROL(Ctrl),LEFT_CONTROL,SHIFT,LEFT_SHIFT ENTER(回车),SPACE(空格),COMMAND,META(win),ESCAPE(Esc) BACKSPACE,BACK_SPACE(退格),DELETE ARROW_UP,ARROW_DOWN,ARROW_LEFT,ARROW_RIGHT UP,DOWN,LEFT,RIGHT PAGE_UP,PAGE_DOWN NUMPAD[0-9](小键盘0-9) F[1-12](F1-F12) PAUSE,INSERT,HOME,HELP CANCEL,CLEAR,DECIMAL,NULL,RETURN,SEPARATOR 如:demo=driver.find_element_by_id(‘input‘) demo.send_keys(Keys.CONTROL,‘v‘) 表示按住Ctrl+v(粘贴) 模拟鼠标操作 模拟鼠标操作需要导入ActionChains类,使用ActionChains(driver)获取一个ActionChains对象,该对象提供的常用操作鼠标方法: context_click(target):右击 double_click(target):双击 drag_and_drop(start_target,target_target):拖到 move_to_element(target):鼠标悬停 以上四个方法可以链式调用。最后使用perform()方法执行之前所有行为 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains browser = webdriver.Chrome() browser.get(‘https://www.baidu.com‘) demo=browser.find_element_by_link_text(‘新闻‘) demo2=browser.find_element_by_link_text(‘图片‘) ActionChains(browser).move_to_element(demo).drag_and_drop(demo,demo2).context_click(demo2).perform() #鼠标先停留在新闻文字上,然后移动到图片文字上,最后点击右键
5、表单元素select下拉菜单简单的运用点击等不能实现操作,需要使用一个类
from selenium.webdriver.support.ui import Select sel=Select(driver.find_element_by_name(‘sel‘)) #选中下拉菜单,使用Select创建对象 sel.select_by_index(index):根据索引值选择 sel.select_by_value(value):根据value值选择 sel.select_by_visible_text(text):根据文本值选择 sel.deselect_all():取消所有选中
6、页面的隐式等待和显示等待
现在的网页越来越多的采用ajax或者类似的技术,这样抓取时不确定某个元素是否已经完全加载出来了,如果在元素没有加载出来时使用了这个元素,那么会抛出NullPointer异常,为了解决这个问题Selenium提供了两种解决办法:隐式等待和显式等待。
隐式等待:
调用浏览器对话的implicitly_wait(timeout)方法,设定每次打开页面查找元素的超时时间(秒)
显式等待:表示某个条件成立之后才执行获取元素的操作
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC element=WebDriverWait(driver,timeout).until( EC.presence_of_element_located((By.ID,‘find_id‘)) ) presence_of_element_located():满足指定条件才执行后续操作 presence_of_all_element_located():满足所有指定条件才执行后续操作 emelent_to_be_cliable():某个元素可以点击才执行后续操作 以上三个方法中传入一个或多个元祖,每个元祖第一个元素时指定要通过什么方式查找元素,可能的值有 CLASS_NAME,CSS_SELECTOR,ID,LINK_TEXT,NAME,PARTIAL_LINK_TEXT,TAG_NAME,XPATH