Loading

爬虫学习

urllib库

requests库

发送请求

传递 URL 参数

响应内容

二进制响应内容

JSON 响应内容

原始响应内容

定制请求头

更加复杂的 POST 请求

POST一个多部分编码(Multipart-Encoded)的文件

响应状态码

响应头

重定向与请求历史

超时

错误与异常

正则表达式(regex)

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

许多程序设计语言都支持利用正则表达式进行字符串操作。

测试网站:https://regexr-cn.com/

XPath

XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言。它最初是用来搜寻XML文档的,但它同样适用于HTML文档的搜索。

XPath语法大致分为三类:

  • 层级:/ 选取直接子结点、// 选取子孙结点
  • 属性:@ 选取属性
  • 函数:contains(属性名称, 属性值)text()

菜鸟教程:https://www.runoob.com/xpath/xpath-tutorial.html

BeautifulSoup

解析器

BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器

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

节点选择器

方法选择器

  • find_all()

    1. 根据节点名查询(name属性)

      soup.find_all(name="li")
      
    2. 根据属性查询(attrs属性)

      soup.find_all(attrs={'class': 'item-0'})
      
    3. 匹配节点内的文本(text属性)

      soup.find_all(text=re.compile(r'hello'))
      
  • find()

    find()与find_all()类似,只不过find()返回的是单个元素(第一个匹配的元素),而find_all()分会的是所有匹配元素组成的列表。

CSS选择器

select()方法

​ 例如:

soup.select('ul li')	# 选择所有ul节点下面的所有li节点
soup.select('#list-1 .element')	   # 选择id为list-1的节点下类为element的所有节点

数据存储

文件存储

关系型数据库存储

非关系型数据库存储

Ajax数据爬取

动态渲染页面爬取

Selenium的使用

需要安装Chrome浏览器,并配置好ChromeDriver。(不同浏览器的Driver不同

  1. 声明浏览器对象

    from selenium import webdriver
    browser = webdriver.Chrome()    # 完成浏览器的初始化
    
  2. 访问页面

    browser.get("https://www.taobao.com")
    print(browser.page_source)
    browser.close()
    
  3. 查找节点
    Selenium可以驱动浏览器完成各种操作,比如填充表单、模拟点击等。
    比如,我们想要向某个输入框输入文字,这就需要知道这个输入框在哪里。
    我们可以用Selenium提供的一系列查找节点的方法来获取想要的节点。

    image

    • 单个节点

      from selenium import webdriver
      
      browser = webdriver.Chrome()    # 完成浏览器的初始化
      browser.get("https://www.taobao.com")
      input_first = browser.find_element_by_id('q')
      input_second = browser.find_element_by_css_selector('#q')
      input_third = browser.find_element_by_xpath('//*[@id="q"]')
      browser.close()
      

      分别根据id、css选择器、XPath来获取输入框节点。

      它们返回的结果完全一致。(返回类型为WebElement)

      以下是所有获取单个节点的方法:

      find_element_by_id()——按id查找

      find_element_by_name()——按name值查找

      find_element_by_class_name()——按类名查找

      find_element_by_tag_name()——按标签名查找

      find_element_by_link_text()——此种方法是专门用来定位文本链接的,比如百度首页右上角有“新闻”,“hao123”,“地图”等链接。如:

      # 通过link定位"新闻"这个链接并点击
      driver.find_element_by_link_text('新闻').click()
      

      find_element_by_partial_link_text()——按部分文本链接名称查找

        有时候一个超链接的文本很长很长,我们如果全部输入,既麻烦,又显得代码很不美观,这时候我们就可以只截取一部分字符串,用这种方法模糊匹配了。

      find_element_by_xpath()——按xpath方式查找

      find_element_by_css_selector()——按css选择器查找

      通用方法:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      
      browser.find_element(By.ID, 'q')
      # 等价于browser.find_element_by_id('q')
      
    • 多个节点

      如果查找的目标在网页中只有一个,那么完全可以使用find_element()方法。

      但如果有多个节点,就需要使用find_elements()方法。(find_element()方法只能得到第一个节点)

      比如,要查找淘宝左侧导航条的所有条目。

      image

      from selenium import webdriver
      
      browser = webdriver.Chrome()
      browser.get("https://www.taobao.com/")
      lis = browser.find_elements_by_css_selector('.service-bd li')
      print(lis)
      browser.close()
      

      得到的结果是一个列表,列表中每个元素都是WebElement类型。

      通用方法:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      
      browser.find_elements(By.CSS_SELECTOR, '.service-bd li')
      
  4. 节点交互

    Selenium可以驱动浏览器执行一些操作(模拟执行一些动作)。

    比较常见的用法有:输入文字时用send_keys()方法,清空文字时用clear()方法,点击按钮时用click()方法。

    示例:

    from selenium import webdriver
    import time
    
    browser = webdriver.Chrome()
    browser.get('https://www.taobao.com')
    input = browser.find_element_by_id('q')
    input.send_keys('输入测试')
    time.sleep(1)
    input.clear()
    input.send_keys('计算机系统结构')
    button = browser.find_element_by_class_name('btn-search')
    button.click()
    
  5. 动作链

    还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳操作、键盘按键等,这些动作用另一种方式来执行,那就是动作链。

    比如,实现一个节点的拖曳操作,将某个节点从一处拖曳到另一处:

    from selenium import webdriver
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome()
    url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
    browser.get(url)
    # webDriver只能在一个页面上对元素识别和定位,对于frame/iframe表单内嵌页面上的元素无法直接定位,
    # 此时就需要通过switch_to.frame()方法将当前定位的主题切换为iframe表单的内嵌页面中。
    browser.switch_to.frame('iframeResult')
    source = browser.find_element_by_css_selector('#draggable')
    target = browser.find_element_by_css_selector('#droppable')
    actions = ActionChains(browser)
    actions.drag_and_drop(source, target)
    actions.perform()
    
  6. 执行JavaScript

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get('https://www.zhihu.com/explore')
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    driver.execute_script('window.alert("To Bottom!")')
    driver.execute_script('window.scrollTo(0, 0)')
    driver.execute_script('window.alert("To Top!")')
    
  7. 获取节点信息

    • 获取属性

      from selenium import webdriver
      
      driver = webdriver.Chrome()
      url = 'https://maoyan.com/board/4'
      driver.get(url)
      logo = driver.find_element_by_css_selector('.logo')
      print(logo)
      print(logo.get_attribute('href'))   # 获取属性
      input = driver.find_element_by_xpath('//ul[@class="navbar"]/li[5]/a')
      print(input.text)   # 获取文本值	榜单
      print(input.id)		# 获取id
      print(input.location)   # 获取节点在页面中的相对位置 {'x': 500, 'y': 0}
      print(input.tag_name)   # 获取标签名称 a
      print(input.size)       # 获取节点的大小 {'height': 80, 'width': 70}
      
    • 获取文本值

  • 获取id、位置、标签名、大小
  1. 切换Frame

    webdriver只能在一个页面上对元素识别和定位,对于frame/iframe表单内嵌页面上的元素无法直接定位,此时就需要通过switch_to.frame()方法将当前定位的主题切换为iframe表单
    的内嵌页面中,然后再进行操作。

  2. 延时等待

    在Selenium中,get()方法会在网页框架加载结束后结束执行,此时如果获取page_source,可能并不是浏览器完全加载完成的页面,如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。所有,这里需要延时等待一定时间,确保节点已经加载出来。

    • 隐式等待(implicitlyWait)

      使用隐式等待执行测试的时候,如果Selenium没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。默认等待时间是0。

      from selenium import webdriver
      
      driver = webdriver.Chrome()
      driver.implicitly_wait(10)  # 若没有找到,等待10秒
      driver.get('https://maoyan.com/board/4')
      input = driver.find_element_by_name('kw')
      print(input.get_attribute('placeholder'))
      
    • 显式等待(explicitlyWait)

      显示等待方法,它指定要查找的节点,然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果在规定时间内依然没有加载出该节点,则抛出超时异常。

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      
      driver = webdriver.Chrome()
      driver.get('https://www.taobao.com/')
      wait = WebDriverWait(driver, 10)    # 构造WebDriverWait对象,指定最长等待时间
      input = wait.until(EC.presence_of_element_located((By.ID, 'q')))    # 调用until()方法,传入等待条件
      # 等待条件EC.presence_of_element_located()的参数是一个定位元组。在这里就是(By.ID, 'q')。
      button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
      print(input)
      print(button)
      
  3. 前进和后退

    浏览器都有前进和后退功能,Selenium也可以完成这个操作。

    import time
    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com/')
    time.sleep(1)
    driver.get('https://www.taobao.com/')
    time.sleep(1)
    driver.back()		# 后退
    time.sleep(1)
    driver.forward()	# 前进
    time.sleep(1)
    driver.close()
    
  4. Cookies

    使用Selenium,可以方便地对Cookies进行操作,例如获取、添加、删除Cookies等。

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get('https://www.zhihu.com/explore')
    print(driver.get_cookies())     # 获取所有Cookies
    driver.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'tky'})  # 添加一个Cookie
    print(driver.get_cookies())     
    driver.delete_all_cookies()     # 删除所有Cookies
    print(driver.get_cookies()) 
    
  5. 选项卡管理

    访问网页时,我们会在浏览器中开启许多选项卡。在Selenium中,我们也可以对选项卡进行操作。

    from selenium import webdriver
    import time
    
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com/')
    driver.execute_script('window.open()')      # 执行JS语句,在浏览器中新开启一个选项卡
    print(driver.window_handles)    # ['CDwindow-898EEA6DCA8AEB5EE82142D437460125', 'CDwindow-40C26092B29F727874D18E7662C901E6']
    driver.switch_to.window(driver.window_handles[1])   # 切换到第二个选项卡
    driver.get('https://www.taobao.com/')       # 第二个选项卡跳转到淘宝
    time.sleep(1)
    driver.switch_to.window(driver.window_handles[0])   # 切换到第一个选项卡
    driver.get('https://www.bilibili.com/')     # 第一个选项卡跳转到b站
    
  6. 异常处理

结尾

全文完。

学习资料:Python 3网络爬虫开发实战 (崔庆才著)

posted @ 2021-03-26 09:57  Skyey  阅读(60)  评论(0编辑  收藏  举报