美文网首页
Selenium/Xpath/BeautifulSoup

Selenium/Xpath/BeautifulSoup

作者: 222AblackA | 来源:发表于2019-03-04 23:34 被阅读0次

    一: selenium库 -- 模拟用户登陆,并解析网页

    应用现状:

    selenium模拟浏览器进行数据抓取无疑是当下最通用的数据采集方案,它通吃各种数据加载方式,能够绕过客户JS加密,绕过爬虫检测,绕过签名机制。它的应用,使得许多网站的反采集策略形同虚设。由于selenium不会在HTTP请求数据中留下指纹,因此无法被网站直接识别和拦截

    selenium在运行的时候会暴露出一些预定义的Javascript变量(特征字符串),例如"window.navigator.webdriver",在非selenium环境下其值为undefined,而在selenium环境下,其值为true

    大众点评网的验证码表单页,如果是正常的浏览器操作,能够有效的通过验证,但如果是使用selenium就会被识别,即便验证码输入正确,也会被提示“请求异常,拒绝操作”,无法通过验证

    知道了屏蔽的原理,只要能够隐藏这些特征串就可以了。但是还不能直接删除这些属性,因为这样可能会导致selenium不能正常工作了。我们采用曲线救国的方法,使用中间人代理,比如fidder, proxy2.py或者mitmproxy,将JS文件(本例是yoda.*.js这个文件)中的特征字符串给过滤掉(或者替换掉,比如替换成根本不存在的特征串),让它无法正常工作,从而达到让客户端脚本检测不到selenium的效果
    (以上内容借用其他作者语录)

    安装: pip install selenium

    安装浏览器驱动:

    查找到与自己装的浏览器先匹配的驱动进行下载
    淘宝镜像驱动下载地址:https://npm.taobao.org/mirrors/chromedriver
    最好将下载的chromdriver.exe ⽂件放到Python Scripts⽬录下或者配置PATH路径
    

    导入selenium库,生成浏览器对象

    可以复制导入以下常用函数

    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver import ActionChains
    

    生成浏览器对象:

    brower = webdriver.Chrome()
    

    生成无头浏览器对象:

    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    brower = webdriver.Chrome(chrome_options=chrome_options)
    

    设置网页窗口大小

    browser.set_window_size(1400, 700)
    

    设置最大等待时间

    wait = WebDriverWait(browser, 5)
    

    访问网页,生成网页页面对象

    browser.get('https://www.mkv99.com/vod-detail-id-9462.html')
    

    selenium相关函数方法:

    获取渲染数据后的页面内容
    a= browser.page_source
    
    获取当前页面的url
    browser.current_url
    
    获取当前页面的cookies
    browser.get_cookies()
    
    根据节点的id查找获取节点对象
    input1 = browser.find_element_by_id('1thUrlid第01集')
    
    获取节点属性值
    href = input1.get_attribute('href'))
    
    css选择器获取节点
    input_list = browser.find_elements_by_css_selector('.dwon2')
    
    获取节点在页面中坐标(左上角)
    input1.location
    
    获取节点的宽高
    input1.size
    
    利用xpath方法获取节点:
    input3 = browser.find_element_by_xpath('//*[@class="dwon2"]')
    通过name的值获取
    input4 = browser.find_element_by_name('CopyAddr1')
    a= input4.tag_name
    通过文本文字获取有该文字的一个标签
    input5 = browser.find_element_by_link_text('今日更新')
    通过文本文字获取有该文字的多个标签
    input6 = browser.find_elements_by_partial_link_text('下载')
    获取节点文本值
    input5.text
    
    让页面执行js代码(让页面滑动到底部)
    str_js = 'var scrollHeight = document.body.scrollHeight;window.scrollTo(0, scrollHeight);'
    browser.execute_script(str_js)
    
    
    通过css选择器选择节点,并且等到该节点能被点击时获取(在最大等待时间内) --
    next_page = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_topPage .fp-next')))
    通过xpath获取节点,并且等到该节点存在时获取(在最大等待时间内) --
    next_page = wait.until(EC.presence_of_element_located((By.XPATH, '//a')))
    通过text文本内容获取节点,并且等到该节点存在时获取(在最大等待时间内) --
    next_page = wait.until(EC.presence_of_element_located((By.LINK_TEXT, '你好')))
    通过标签名获取节点,并且等到该节点存在时获取(在最大等待时间内) --
    next_page = wait.until(EC.presence_of_element_located((By.TAG_NAME, 'a')))
                --其他方法参照具体情况调用--
    
    
    模拟用户点击next_page这个标签节点,其他模拟用户的事件在最下面 -- 
    next_page.click()
    
    模拟用户操作浏览器上节点对象的方法 -- (需指定节点对象来调用下列方法)
    click(on_element=None) ——单击鼠标左键
    click_and_hold(on_element=None) ——点击鼠标左键,不松开
    context_click(on_element=None) ——点击鼠标右键
    double_click(on_element=None) ——双击鼠标左键
    drag_and_drop(source, target) ——拖拽到某个元素然后松开
    drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开
    key_down(value, element=None) ——按下某个键盘上的键
    key_up(value, element=None) ——松开某个键
    move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标
    move_to_element(to_element) --鼠标移动到某个元素
    move_to_element_with_offset(to_element, xoffset, yoffset) --移动到距某个元素(左上⾓坐标)多少距离的位置
    perform() ——执⾏链中的所有动作
    release(on_element=None) ——在某个元素位置松开鼠标左键
    send_keys(*keys_to_send) ——发送某个键到当前焦点的元素
    send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素
    

    二: lxml库 (支持HTML和XML解析,xpath解析方式)

    xpath是XQuery的一个子集,XQuery是处理xml和html页面的路径查询语言,专用于xml中沿着路径(专业术语叫轴)查找数据用的,可以返回单个元素、文本元素、多个元素节点、属性节点等

    1.安装并导入 -- pip install lxml

    导入库etree:
    from lxml import etree 
    将页面数据html转为etree对象:
    etree_html = etree.HTML(html)
    

    2.调用xpath方法解析:

    匹配对象中所有节点 --> //* 
    result = etree_html.xpath('//*') -- 结果是Elenment对象
    
    匹配所有a标签节点 --> //a
    result = etree_html.xpath('//a') -- 结果是Elenment对象
    
    获取文本 --> text()
    result = etree_html.xpath('//a/text()') -- 结果是元素是文本的列表
    
    
    查找元素子节点 --> /
    result = etree_html.xpath('//div/p/text()')
    
    查找元素class属性匹配的所有子孙节点 --> //
    result = etree_html.xpath('//div[@class="channel-item"]')
    
    查找多个节点 --> | (或者的意思)
    result = etree_html.xpath('//div[@class="channel-item"] | //span[@class="pubtime"]/../span/a/text()')
    
    查询获取节点的父节点 --> ..
    result = etree_html.xpath('//span[@class="pubtime"]/..')
    
    查询或者属性的值 
    result = etree_html.xpath('//div[@class="article"]/div/@class')
    
    属性多值匹配(包含)
    result = etree_html.xpath('//div[contains(@class, "grid-16-8")]
    
    多属性匹配 --> or, and, mod, //book | //cd, + - * div = != < > <= >=
    result = etree_html.xpath('//span[@class="pubtime" and contains(text(), "-12-29")]/text()')
    
    按顺序选择获取节点 -->
     [1] -- 第一个, [last()] -- 最后一个, [position() < 3] -- 前两个, [last() -2] -- 倒数第3个 
    result = etree_html.xpath('//div[1]')
    result = etree_html.xpath('//div[last()]')
    
    
    其他按条件匹配获取节点方式:
    
    //li/ancestor::*  li所有祖先节点
    //li/ancestor::div div这个祖先节点
    //li/attribute::* attribute轴,获取li节点所有属性的值
    //li/child::a[@href="link1.html"]  child轴,获取直接子节点
    //li/descendant::span 获取所有span类型的子孙节点   
    //li/following::* 选取文档中当前节点的结束标记之后的所有节点
    //li/following-sibling::*     选取当前节点之后的所有同级节点
    

    三 : BeautifulSoup -- 靓汤

    1. 安装 -- pip install beautifulsoup4

    导入BeautifulSoup库:
     from bs4 import BeautifulSoup
    
    调用解析器,生成网页数据html的解析对象:
    soup = BeautifulSoup(html, 'lxml')
    

    2. beautifulsoup的四种解析器:

    Python标准库 -- BeautifulSoup(html, 'html.parser') -- 速度 一般,容错能力好
    lxml HTML解析器BeautifulSoup(html, 'lxml') -- 速度快,容错好
    lxml xml解析器 BeautifulSoup(markup, 'xml') -- 速度快,唯一支持xml
    html5lib 解析器 BeautifulSoup(markup, 'html5lib') -- 容错性高,速度慢
    
    a = soup.prettify() -- 将网页格式化,有缩进的格式整齐输出  (print(a))
    title = soup.title.string -- 取网页title的内容
    head = soup.head -- 取head标签所有内容(有多个标签,只取第一个)
    name = soup.p.name -- 获取标签名
    
    获取标签的某一个属性值 -- 返回字符串
    print(soup.img.attrs["src"])
    print(soup.img['src'])
    
    获取该标签的所有属性值 -- 返回结果是一个字典
    print(soup.img.attrs)
    
    获取p标签中所有标签对象 -- 返回列表,元素是标签的bs对象
    a= soup.p.contents
    
    获取的标签对象可以继续选择 
    soup.head.title.string
    
    取节点下面所有子节点列表
    soup.p.contents
    
    
        soup.p.descendants -- 取节点所有子孙节点
        soup.a.parent -- 取父节点
        soup.a.parents --  取所有祖先节点
        soup.a.next_sibling -- 同级下⼀节点
        soup.a.previous_sibling -- 同级上⼀节点
        soup.a.next_siblings -- 同级所有后⾯节点
        soup.a.previous_siblings -- 同级所有前⾯节点
        列子:  list(soup.a.parents)[0].attrs['class'])
    
    方向选择器:
    
        根据属性和文本查找 -- 
        for ul in soup.find_all(name="ul"):
         print(ul.find_all(name="li"))
         for li in ul.find_all(name="li"):
         print(li.string)
        soup.find_all(attrs={"id": "list-1"})
        
        css选择器:
        soup.select('.panel .panel_heading')
        soup.select('ul li')
        soup.select('#id1 .element')

    相关文章

      网友评论

          本文标题:Selenium/Xpath/BeautifulSoup

          本文链接:https://www.haomeiwen.com/subject/fykguqtx.html