0


爬虫解析模块(bs4,selenium)

bs4文档

  1. 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格式的文档速度慢、不依赖外部扩展

初始化

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

获取标签和属性

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

对于返回的Element对象:

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

其他find_*

  1. find_parents() 返回所有祖先节点
  2. find_parent() 返回直接父节点
  3. find_next_siblings() 返回后面所有兄弟节点
  4. find_next_sibling() 返回后面第一个兄弟节点
  5. find_all_next() 返回节点后所有符合条件的节点
  6. find_next() 返回第一个符合条件的节点
  7. find_all_previous() 返回节点后所有符合条件的节点
  8. 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 是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作。

  1. pip install selenium

Selenium 支持非常多的浏览器

  1. from selenium import webdriver
  2. # 常用Chrome和Edge
  3. browser = webdriver.Chrome()
  4. browser = webdriver.Edge()
  5. browser = webdriver.Firefox()
  6. browser = webdriver.Safari()
  7. browser = webdriver.Android()
  8. browser = webdriver.Ie()
  9. browser = webdriver.Opera()
  10. browser = webdriver.PhantomJS()

浏览器驱动

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

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

验证安装

  1. from selenium import webdriver
  2. from time import sleep
  3. browser = webdriver.Chrome()# 打开百度
  4. browser.get('https://www.baidu.com')
  5. sleep(5)# 使用完关闭
  6. browser.close()

定位方式

  1. <buttonid="submit"name="submitBtn"class="text-center">提交</button>
  1. id:标签ID定位
  1. find_element_by_id("submit")
  1. name:标签name属性
  1. find_element_by_name("submitBtn")
  1. class name:标签类名字定位
  1. find_element_by_class_name("text-center")
  1. tag name:标签名字定位
  1. find_element_by_tag_name("button")
  1. link text:链接文本定位
  1. find_element_by_link_text("提交")
  1. partial link text:部分链接文本定位
  1. find_element_by_link_text("交")
  1. xpath:xpath定位
  1. find_element_by_xpath("//div[@id='csdn-toolbar']/div/div/div[2]/div/div/input[1]")
  1. css selector:css选择器定位
    方法例子描述**.class**
    1. .toolbar-search-container
    选择
    1. class = 'toolbar-search-container'
    的所有元素**#id**
    1. #toolbar-search-input
    选择
    1. id = 'toolbar-search-input'
    的元素*****
    ```
    1. 选择所有元素**element**
    input
    1. 选择所有
    <input>
    1. 元素**element>element**
    div>input
    1. 选择父元素为
    <div>
    1. 的所有
    <input>
    1. 元素**element+element**
    div+input
    1. 选择同一级中在
    <div>
    1. 之后的所有
    <input>
    1. 元素**[attribute=value]**
    type='text'
    1. 选择
    type = 'text'
    1. 的所有元素
    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参数。

在这里插入图片描述

  1. from selenium.webdriver.common.by import By
  2. classBy:"""
  3. Set of supported locator strategies.
  4. """
  5. ID ="id"
  6. XPATH ="xpath"
  7. LINK_TEXT ="link text"
  8. PARTIAL_LINK_TEXT ="partial link text"
  9. NAME ="name"
  10. TAG_NAME ="tag name"
  11. CLASS_NAME ="class name"
  12. 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已经加载过了)

  1. from selenium import webdriver
  2. from selenium.webdriver.common.by import By
  3. edge = webdriver.Edge()# 提交表单
  4. edge.find_element(By.ID,"submit").submit()

浏览器控制(无头等)

修改浏览器窗口大小

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

还有一些快捷方式:

  1. defmaximize_window(self)->None:"""
  2. 最大化
  3. """
  4. command = Command.W3C_MAXIMIZE_WINDOW
  5. self.execute(command,None)deffullscreen_window(self)->None:"""
  6. 全屏
  7. """
  8. self.execute(Command.FULLSCREEN_WINDOW)defminimize_window(self)->None:"""
  9. 最小化
  10. """
  11. self.execute(Command.MINIMIZE_WINDOW)

前进后退

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

  1. #返回
  2. driver.back()#前进
  3. driver.forward()

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

  1. # 获取打开的多个窗口句柄
  2. windows = driver.window_handles
  3. # 切换到当前最新打开的窗口
  4. 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 中存储的行为,可以理解成是对整个操作的提交动作

  1. from selenium import webdriver
  2. from selenium.webdriver.common.by import By
  3. from selenium.webdriver.common.action_chains import ActionChains
  4. edge = webdriver.Edge()# 提交表单
  5. edge.maximize_window()# 点击验证码
  6. ActionChains(edge).move_to_element_with_offset(验证码标签,偏移量x,偏移量y).click().perform()# 定位要拖动的元素
  7. source = edge.find_element_by_xpath('xxx')# 定位目标元素
  8. target = edge.find_element_by_xpath('xxx')# 执行拖动动作
  9. ActionChains(edge).drag_and_drop(source, target).perform()

键盘事件

  1. rom selenium.webdriver.common.keys import Keys
  2. # 模拟回车键进行跳转(输入内容后)
  3. 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 。

  1. WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)- driver:浏览器驱动
  2. - timeout:超时时间,单位秒
  3. - poll_frequency:每次检测的间隔时间,默认为0.5
  4. - ignored_exceptions:指定忽略的异常,如果在调用 until until_not 的过程中抛出指定忽略的异常,则不中断代码,默认忽略的只有 NoSuchElementException
  5. ------------------------------------------------------
  6. until(method, message=’ ‘)
  7. until_not(method, message=’ ')- method:指定预期条件的判断方法
  8. - message:TimeoutException报错信息
  9. -----------------------------------------------------------------------------from selenium import webdriver
  10. from selenium.webdriver.support.ui import WebDriverWait
  11. from selenium.webdriver.support import expected_conditions
  12. from selenium.webdriver.common.by import By
  13. driver = webdriver.Chrome()
  14. element = WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,'submitBtn')),
  15. 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

隐式等待

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

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

强制等待

  1. time.sleep()

iframe

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

弹窗处理

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

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

  1. text

获取弹窗中的文字

  1. accept()

接受(确认)弹窗内容

  1. dismiss()

解除(取消)弹窗

  1. send_keys()

发送文本至警告框

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

文件操作

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

上传

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

下载

需要用到浏览器选项,

  1. from selenium.webdriver import ChromeOptions
  1. from selenium.webdriver import ChromeOptions
  2. prefs ={# 禁止弹窗'profile.default_content_settings.popups':0,# 文件下载路径'download.default_directory':"file_Path"}
  3. option = webdriver.ChromeOptions()
  4. option.add_experimental_option('prefs', prefs)
  5. driver = webdriver.Chrome(options=option)
  6. driver.find_element_by_xpath('下载链接').click()# 如果出现非安全需要切换到最新窗口
  7. driver.switch_to.window(driver.window_handles[-1])# 输入thisisunsafe即可
  8. 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()关闭当前页面

下拉框选择操作

  1. from selenium.webdriver.support.select import Select

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

  1. sel = edge.find_element_by_xpath("//select[@id='nr']")for selectIndex inrange(len(sel.options)):# 索引print(selectIndex)
  2. Select(sel).select_by_value('50')# 显示50

图片处理

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

其他属性

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

无头浏览器

  1. from selenium import webdriver
  2. from selenium.webdriver import ChromeOptions
  3. option = ChromeOptions()
  4. option.add_argument('--headless')# 都无头了要个锤子图片,不用gpu渲染
  5. option.add_argument("--disable-gpu")
  6. browser = webdriver.Chrome(options=option)

反屏蔽

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

  1. from selenium import webdriver
  2. from selenium.webdriver import ChromeOptions
  3. option = ChromeOptions()
  4. option.add_argument("--headless")
  5. option.add_experimental_option('excludeSwitches',['enable-automation'])
  6. option.add_experimental_option('useAutomationExtension',False)
  7. 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')
  8. option.add_argument("--disable-blink-features=AutomationControlled")
  9. browser = webdriver.Chrome(options=option)# https://github.com/kingname/stealth.min.jswithopen('stealth.min.js')as f:
  10. js = f.read()
  11. browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source': js
  12. })

总结

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

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

标签: 爬虫 selenium python

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

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

还没有评论