注册 登录

清河洛

使用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


网址导航