0


爬虫解析模块(bs4,selenium)

bs4文档

from bs4 import BeautifulSoup
  1. Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
  2. Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。

解析器

解析器使用方法优势劣势Python标准库BeautifulSoup(markup, “html.parser”)Python的内置标准库、执行速度适中 、文档容错能力强Python 2.7.3 or 3.2.2)前的版本中文容错能力差lxml HTML 解析器BeautifulSoup(markup, “lxml”)速度快、文档容错能力强需要安装C语言库lxml XML 解析器BeautifulSoup(markup, “xml”)速度快、唯一支持XML的解析器需要安装C语言库html5libBeautifulSoup(markup, “html5lib”)最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档速度慢、不依赖外部扩展

初始化

def__init__(self, markup="", features=None, builder=None,
             parse_only=None, from_encoding=None, exclude_encodings=None,
             element_classes=None,**kwargs):"""Constructor.
    :param markup: html文本或file-like对象
    :param features: 解析器:("lxml","lxml-xml", "html.parser", or "html5lib")
    """

soup = BeautifulSoup("html","lxml")

获取标签和属性

print(soup.title)#选择title标签。print(soup.head)#选择head标签print(soup.p)#选择p标签print(soup.title.name)#获取title标签名print(soup.p.attrs['name'])#获取p标签name属性值print(soup.p['name'])#获取p标签name属性值print(soup.p.string)#获取p标签内容,该方法只能获取第一个p标签内容print(soup.head.title.string)#嵌套选择,用点号分割,层层嵌套print(soup.p.contents)# 获取p标签的子节点及其内容,->listprint(soup.p.children)# 获取获取标签的子节点->iterprint(soup.p.descendants)# 返回子孙节点(不仅仅是子节点,返回结果为迭代器)print(soup.a.parent)# 返回的是第一个a标签的父节点print(soup.a.parents)# 返回的是父节点以及祖先节点print(list(enumerate(soup.a.next_siblings)))#a标签的下一个兄弟节点print(list(enumerate(soup.a.previous_siblings)))#上一个兄弟

find()和find_all()方法

  1. find_all()方法返回值:所有符合条件的元素列表。
  2. find()方法 返回值:返回符合条件的第一个元素。
deffind_all(self, name=None, attrs={}, recursive=True, string=None,
             limit=None,**kwargs):"""
    :param name: 标签名称,可以为字符串,列表,正则
    :param attrs: 标签属性
    :param recursive: 递归
    :param limit: 限制数量
    :kwargs: key=val格式的标签属性,如果是class属性,需要写为class_=val
    
    :return: A ResultSet of PageElements.
    :rtype: bs4.element.ResultSet
    """deffind(self, name=None, attrs={}, recursive=True, string=None,**kwargs):
    r =None
    l = self.find_all(name, attrs, recursive, string,1,**kwargs)if l:
        r = l[0]return r

对于返回的Element对象:

  1. tag.text 表示其中的文本内容
  2. tag.get(attr) 获取attr属性
  3. tag.name 表示标签的名字

其他find_*

find_parents()  返回所有祖先节点
find_parent()  返回直接父节点

find_next_siblings()  返回后面所有兄弟节点
find_next_sibling()    返回后面第一个兄弟节点

find_all_next()  返回节点后所有符合条件的节点
find_next() 返回第一个符合条件的节点

find_all_previous() 返回节点后所有符合条件的节点
find_previous() 返回第一个符合条件的节点

select()方法

select()主要是以CSS选择器(selector)的方式寻找元素。如果找到元素,则返回元素列表;否则返回空列表。

  1. 标签选择器:直接指定标签名 1. Soup.select(‘p’):寻找所有<p>标签的元素;2. Soup.select(‘img’):寻找所有<img>标签的元素3. Soup.select(‘input[name]’):寻找所有<input>标签且包含name属性的元素
  2. 类(class)选择器:.1. Soup.select('.name):寻找所有class属性为name的元素
  3. 选择器:#1. Soup.select('#name):寻找所有id属性为name的元素
  4. 层级选择器: 1. 单层:> Soup.select(‘div.list > ul > li > a’):查找所有class为list的div中的ul里的li标签里面的a标签;2. 多层:空格 Soup.select(‘p #name’):寻找所有<p>标签且id为name的元素 Soup.select(‘p .name’):寻找所有class为name的<p>标签

小结

大部分情况下,find和find_all方法就可以解决问题
在这里插入图片描述

selenium中文文档----------文档

Selenium 是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作。

pip install selenium

Selenium 支持非常多的浏览器

from selenium import webdriver
# 常用Chrome和Edge
browser = webdriver.Chrome() 
browser = webdriver.Edge() 

browser = webdriver.Firefox() 
browser = webdriver.Safari()
browser = webdriver.Android()
browser = webdriver.Ie()
browser = webdriver.Opera()
browser = webdriver.PhantomJS()

浏览器驱动

  1. Chrome Chrome找到对应版本的下载即可。
  2. Edge Edge找到对应版本下载即可。

可以将浏览器驱动放到selenium库的目录下,这样在初始化browser对象时就可以不用传入参数了或者干脆丢个文件夹下,配置环境变量就行。

验证安装

from selenium import webdriver
from time import sleep

browser = webdriver.Chrome()# 打开百度
browser.get('https://www.baidu.com')
sleep(5)# 使用完关闭
browser.close()

定位方式

<buttonid="submit"name="submitBtn"class="text-center">提交</button>
  1. id:标签ID定位
find_element_by_id("submit")
  1. name:标签name属性
find_element_by_name("submitBtn")
  1. class name:标签类名字定位
find_element_by_class_name("text-center")
  1. tag name:标签名字定位
find_element_by_tag_name("button")
  1. link text:链接文本定位
find_element_by_link_text("提交")
  1. partial link text:部分链接文本定位
find_element_by_link_text("交")
  1. xpath:xpath定位
find_element_by_xpath("//div[@id='csdn-toolbar']/div/div/div[2]/div/div/input[1]")
  1. css selector:css选择器定位
    方法例子描述**.class**
    .toolbar-search-container
    
    选择
    class = 'toolbar-search-container'
    
    的所有元素**#id**
    #toolbar-search-input
    
    选择
    id = 'toolbar-search-input'
    
    的元素*****
    ```
  • 选择所有元素**element**
    
    input
    选择所有 
    
    <input>
    元素**element>element**
    
    div>input
    选择父元素为 
    
    <div>
    的所有 
    
    <input>
    元素**element+element**
    
    div+input
    选择同一级中在 
    
    <div>
    之后的所有 
    
    <input>
    元素**[attribute=value]**
    
    type='text'
    选择 
    
    type = 'text'
    的所有元素
    
    find_element_by_css_selector('#submit')
    find_element_by_css_selector('html>body>div>div>div>div>div>div>button')
    ```
    定位一个元素定位多个元素含义find_element_by_idfind_elements_by_id通过元素id定位find_element_by_namefind_elements_by_name通过元素name定位find_element_by_xpathfind_elements_by_xpath通过xpath表达式定位find_element_by_link_textfind_elements_by_link_tex通过完整超链接定位find_element_by_partial_link_textfind_elements_by_partial_link_text通过部分链接定位find_element_by_tag_namefind_elements_by_tag_name通过标签定位find_element_by_class_namefind_elements_by_class_name通过类名进行定位find_elements_by_css_selectorfind_elements_by_css_selector通过css选择器进行定位
    注意:高版本的selenium只提供了find_element和find_elements方法,通过什么寻找需要额外传入By参数。

在这里插入图片描述

from selenium.webdriver.common.by import By

classBy:"""
    Set of supported locator strategies.
    """

    ID ="id"
    XPATH ="xpath"
    LINK_TEXT ="link text"
    PARTIAL_LINK_TEXT ="partial link text"
    NAME ="name"
    TAG_NAME ="tag name"
    CLASS_NAME ="class name"
    CSS_SELECTOR ="css selector"deffind_element(self, by=By.ID, value=None)-> WebElement:passdeffind_elements(self, by=By.ID, value=None)-> List[WebElement]:pass

操作标签的一些方法

方法说明set_window_size()设置浏览器的大小back()控制浏览器后退forward()控制浏览器前进refresh()刷新当前页面clear()清除文本send_keys (value)模拟按键输入click()单击元素submit()用于提交表单get_attribute(name)获取元素属性值is_displayed()设置该元素是否用户可见size返回元素的尺寸text获取元素的文本execute_script(js)执行js脚本page_source获取页面源码(js已经加载过了)

from selenium import webdriver
from selenium.webdriver.common.by import By

edge = webdriver.Edge()# 提交表单
edge.find_element(By.ID,"submit").submit()

浏览器控制(无头等)

修改浏览器窗口大小

defset_window_size(self, width, height, windowHandle:str='current')->None:"""
       设置浏览器的长宽
       driver.set_window_size(800,600)
    """

还有一些快捷方式:

defmaximize_window(self)->None:"""
     最大化
     """
     command = Command.W3C_MAXIMIZE_WINDOW
     self.execute(command,None)deffullscreen_window(self)->None:"""
     全屏
     """
     self.execute(Command.FULLSCREEN_WINDOW)defminimize_window(self)->None:"""
     最小化
     """
     self.execute(Command.MINIMIZE_WINDOW)

前进后退

webdriver 提供 back 和 forward 方法来实现页面的后退与前进。

#返回
driver.back()#前进
driver.forward()

焦点:selenium中,弹出新窗口,焦点不会切换过去,会导致找不到新页面的标签。
方法说明current_window_handle获得当前窗口句柄window_handles返回所有窗口的句柄到当前会话switch_to.window()用于切换到相应的窗口,与上一节的switch_to.frame()类似,前者用于不同窗口的切换,后者用于不同表单之间的切换。

# 获取打开的多个窗口句柄
windows = driver.window_handles
# 切换到当前最新打开的窗口
driver.switch_to.window(windows[-1])

鼠标事件(事件链,操作链)

方法说明ActionChains(driver)构造ActionChains对象context_click()执行鼠标悬停操作move_to_element(above)右击double_click()双击drag_and_drop()拖动move_to_element(above)执行鼠标悬停操作context_click()用于模拟鼠标右键操作, 在调用时需要指定元素定位perform()执行所有 ActionChains 中存储的行为,可以理解成是对整个操作的提交动作

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

edge = webdriver.Edge()# 提交表单
edge.maximize_window()# 点击验证码
ActionChains(edge).move_to_element_with_offset(验证码标签,偏移量x,偏移量y).click().perform()# 定位要拖动的元素
source = edge.find_element_by_xpath('xxx')# 定位目标元素
target = edge.find_element_by_xpath('xxx')# 执行拖动动作
ActionChains(edge).drag_and_drop(source, target).perform()

键盘事件

rom selenium.webdriver.common.keys import Keys

# 模拟回车键进行跳转(输入内容后) 
edge.find_element_by_id('xxx').send_keys(Keys.ENTER)

模拟键盘按键说明send_keys(Keys.BACK_SPACE)删除键(BackSpace)send_keys(Keys.SPACE)空格键(Space)send_keys(Keys.TAB)制表键(Tab)send_keys(Keys.ESCAPE)回退键(Esc)send_keys(Keys.ENTER)回车键(Enter)模拟键盘按键说明send_keys(Keys.CONTROL,‘a’)全选(Ctrl+A)send_keys(Keys.CONTROL,‘c’)复制(Ctrl+C)send_keys(Keys.CONTROL,‘x’)剪切(Ctrl+X)send_keys(Keys.CONTROL,‘v’)粘贴(Ctrl+V)send_keys(Keys.F1…Fn)键盘 F1…Fn

等待

显示等待

显式等待:设置一个超时时间,每个一段时间就去检测一次该元素是否存在,如果存在则执行后续内容,如果超过最大时间(超时时间)则抛出超时异常(TimeoutException)。显示等待需要使用 WebDriverWait,同时配合 until 或 not until 。

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)- driver:浏览器驱动
- timeout:超时时间,单位秒
- poll_frequency:每次检测的间隔时间,默认为0.5秒
- ignored_exceptions:指定忽略的异常,如果在调用 until 或 until_not 的过程中抛出指定忽略的异常,则不中断代码,默认忽略的只有 NoSuchElementException 。

------------------------------------------------------

until(method, message=’ ‘)
until_not(method, message=’ ')- method:指定预期条件的判断方法
- message:TimeoutException报错信息

-----------------------------------------------------------------------------from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
element = WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,'submitBtn')),
                                           message='guys,不是叔找不到,是你程序有Bug!')

方法描述title_is(‘百度一下’)判断当前页面的 title 是否等于预期title_contains(‘百度’)判断当前页面的 title 是否包含预期字符串presence_of_element_located(locator)判断元素是否被加到了 dom 树里,并不代表该元素一定可见visibility_of_element_located(locator)判断元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不等于0visibility_of(element)跟上一个方法作用相同,但传入参数为 elementtext_to_be_present_in_element(locator , ‘百度’)判断元素中的 text 是否包含了预期的字符串text_to_be_present_in_element_value(locator , ‘某值’)判断元素中的 value 属性是否包含了预期的字符串frame_to_be_available_and_switch_to_it(locator)判断该 frame 是否可以 switch 进去,True 则 switch 进去,反之 Falseinvisibility_of_element_located(locator)判断元素中是否不存在于 dom 树或不可见element_to_be_clickable(locator)判断元素中是否可见并且是可点击的staleness_of(element)等待元素从 dom 树中移除element_to_be_selected(element)判断元素是否被选中,一般用在下拉列表element_selection_state_to_be(element, True)判断元素的选中状态是否符合预期,参数 element,第二个参数为 True/Falseelement_located_selection_state_to_be(locator, True)跟上一个方法作用相同,但传入参数为 locatoralert_is_present()判断页面上是否存在 alert

隐式等待

隐式等待是全局性的,即运行过程中,如果元素可以定位到,它不会影响代码运行,但如果定位不到,则它会以轮询的方式不断地访问元素直到元素被找到,若超过指定时间,则抛出异常。

# 等待5s
driver.implicitly_wait(5)try:# 触发隐式等待
    driver.find_element_by_id('btn')except Exception as e:print(f'叔找不到你要的标签,叔给你报个错:{str(e)}')

强制等待

time.sleep()

iframe

  1. 对于内嵌的页面 selenium 是无法直接定位的,需要使用 switch_to.frame() 方法将当前操作的对象切换成 frame/iframe 内嵌的页面。
  2. switch_to.frame() 默认可以用的 id 或 name 属性直接定位,但如果 iframe 没有 id 或 name ,这时就需要使用 xpath 进行定位。
# 1.通过id定位
driver.switch_to.frame('fuck off')# 2.通过name定位
driver.switch_to.frame('fuck off')# 3. 通过xpath定位
iframe_label = driver.find_element_by_xpath('/html/body/fuck/off/iframe')
driver.switch_to.frame(iframe_label)

弹窗处理

PS:**的,之前写超星某某通自动评论的脚本,弹窗真心恶心到我了。

JavaScript 有三种弹窗 alert(确认)、confirm(确认、取消)、prompt(文本框、确认、取消)。
方法描述

text

获取弹窗中的文字

accept()

接受(确认)弹窗内容

dismiss()

解除(取消)弹窗

send_keys()

发送文本至警告框

alert = driver.switch_to.alert
alert.accept()

文件操作

对于文件操作,我还是觉得可以先拿到url然后多进程,多线程,协程下载就行

上传

edge.find_element_by_xpath('//*[@name="upload"]').send_keys(file_path)

下载

需要用到浏览器选项,

from selenium.webdriver import ChromeOptions
from selenium.webdriver import ChromeOptions

prefs ={# 禁止弹窗'profile.default_content_settings.popups':0,# 文件下载路径'download.default_directory':"file_Path"}
option = webdriver.ChromeOptions() 
option.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(options=option)

driver.find_element_by_xpath('下载链接').click()# 如果出现非安全需要切换到最新窗口
driver.switch_to.window(driver.window_handles[-1])# 输入thisisunsafe即可
driver.find_element_by_xpath('./html').send_keys('thisisunsafe')

cookies

  1. edge.get_cookies:以字典的形式返回当前会话中可见的 cookie 信息。
  2. edge.get_cookie(name):返回 cookie 字典中 key == name 的 cookie 信息。
  3. edge.add_cookie(cookie_dict):将 cookie 添加到当前会话中
  4. edge.delete_cookie(name):删除指定名称的单个 cookie。
  5. edge.delete_all_cookies():删除会话范围内的所有 cookie。

关闭操作

  1. quit()关闭所有页面并退出驱动
  2. close()关闭当前页面

下拉框选择操作

from selenium.webdriver.support.select import Select

方法说明select_by_value(“选择值”)select标签的value属性的值select_by_index(“索引值”)下拉框的索引select_by_visible_testx(“文本值”)下拉框的文本值

sel = edge.find_element_by_xpath("//select[@id='nr']")for selectIndex inrange(len(sel.options)):# 索引print(selectIndex)

Select(sel).select_by_value('50')# 显示50条

图片处理

# 截图
edge.get_screenshot_as_file(r'截图后保存路径')# 获取网页图片二进制数据
edge.find_element_by_xpath(xx).screenshot_as_png()# 对页面进行截图,返回二进制数据
edge.get_screenshot_as_png()

其他属性

# 获取当前页面url
driver.current_url
# 获取当前html源码
driver.page_source
# 获取当前页面标题
driver.title
# 获取浏览器名称(chrome)
driver.name
# 对页面进行截图,返回二进制数据
driver.get_screenshot_as_png()# 设置浏览器尺寸
driver.get_window_size()# 获取浏览器尺寸,位置
driver.get_window_rect()# 获取浏览器位置(左上角)
driver.get_window_position()# 设置浏览器尺寸
driver.set_window_size(width=1000, height=600)# 设置浏览器位置(左上角)
driver.set_window_position(x=500, y=600)# 设置浏览器的尺寸,位置
driver.set_window_rect(x=200, y=400, width=1000, height=600)

无头浏览器

from selenium import webdriver
from selenium.webdriver import ChromeOptions

option = ChromeOptions()
option.add_argument('--headless')# 都无头了要个锤子图片,不用gpu渲染
option.add_argument("--disable-gpu")
browser = webdriver.Chrome(options=option)

反屏蔽

防止webdriver检测不通过,感谢 @CSDN博主「小小明-代码实体」

from selenium import webdriver
from selenium.webdriver import ChromeOptions

option = ChromeOptions()
option.add_argument("--headless")
option.add_experimental_option('excludeSwitches',['enable-automation'])
option.add_experimental_option('useAutomationExtension',False)
option.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
option.add_argument("--disable-blink-features=AutomationControlled")
browser = webdriver.Chrome(options=option)# https://github.com/kingname/stealth.min.jswithopen('stealth.min.js')as f:
    js = f.read()
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source': js
})

总结

由于无论去哪都携带着十几个纸质笔记本过于不便,最近计划将笔记本内容全部搬到CSDN做存储。

本文结合了我的爬虫笔记和网络大佬(小小明-代码实体,Dream丶Killer)的博客,对爬虫学习做一个总结。

标签: 爬虫 selenium python

本文转载自: https://blog.csdn.net/General_zy/article/details/128712331
版权归原作者 Generalzy 所有, 如有侵权,请联系我们删除。

“爬虫解析模块(bs4,selenium)”的评论:

还没有评论