• Request模块—数据解析工具


    一、爬虫基本步骤

    • 指定URL信息
    • 发起请求
    • 获取响应数据
    • 对响应数据进行数据解析
    • 持久化存储

    二、数据解析

    1. 正则表达式

    (1) 基本语法
    1. 单字符:
    	. : 除换行以外所有字符
    	[] :[aoe] [a-w] 匹配集合中任意一个字符
    	d :数字  [0-9]
    	D : 非数字
    	w :数字、字母、下划线、中文
    	W : 非w
    	s :所有的空白字符包,括空格、制表符、换页符等等。等价于 [ f
    
    	v]。
    	S : 非空白
    2. 数量修饰:
    	* : 任意多次  >=0
    	+ : 至少1次   >=1
    	? : 可有可无  0次或者1次
    	{m} :固定m次 hello{3,}
    	{m,} :至少m次
    	{m,n} :m-n次
    3. 边界:
    	$ : 以某某结尾
    	^ : 以某某开头
    4. 分组:
    	(ab)  
    5. 贪婪模式: .*
    6. 非贪婪(惰性)模式: .*?
    7. 爬虫正则
    	re.I : 忽略大小写
        re.M :多行匹配
        re.S :单行匹配  //爬虫常用
        re.sub(正则表达式, 替换内容, 字符串)
    
    (2) 相关案例
    import re
    # 提取出python
    key="javapythonc++php"
    re.findall('python',key)[0]
    -----------------------------------------------------------------------------------------
    # 提取出hello world
    key="<html><h1>hello world<h1></html>"
    re.findall('<h1>(.*)<h1>',key)[0]
    -----------------------------------------------------------------------------------------
    # 提取170
    string = '我喜欢身高为170的女孩'
    re.findall('d+',string)
    -----------------------------------------------------------------------------------------
    # 提取出http://和https://
    key='http://www.baidu.com and https://boob.com'
    re.findall('https?://',key)
    -----------------------------------------------------------------------------------------
    # 提取出hello
    key='lalala<hTml>hello</HtMl>hahah' #输出<hTml>hello</HtMl>
    re.findall('<[Hh][Tt][mM][lL]>(.*)</[Hh][Tt][mM][lL]>',key)
    -----------------------------------------------------------------------------------------# 提取出hit.
    key='bobo@hit.edu.com'  # 想要匹配到hit.
    re.findall('h.*?.',key)
    -----------------------------------------------------------------------------------------
    # 匹配sas和saas
    key='saas and sas and saaas'
    re.findall('sa{1,2}s',key)
    -----------------------------------------------------------------------------------------
    # 匹配出i开头的行
    string = '''fall in love with you
    i love you very much
    i love she
    i love her'''
    
    re.findall('^.*',string,re.M)
    -----------------------------------------------------------------------------------------
    # 匹配全部行
    string1 = """<div>静夜思
    窗前明月光
    疑是地上霜
    举头望明月
    低头思故乡
    </div>"""
    
    re.findall('.*',string1,re.S)
    

    2. Beautifulsoup

    (1) 环境安装
    - 需要将pip源设置为国内源,阿里源、豆瓣源、网易源等
       - windows
        (1)打开文件资源管理器(文件夹地址栏中)
        (2)地址栏上面输入 %appdata%
        (3)在这里面新建一个文件夹  pip
        (4)在pip文件夹里面新建一个文件叫做  pip.ini ,内容写如下即可
            [global]
            timeout = 6000
            index-url = https://mirrors.aliyun.com/pypi/simple/
            trusted-host = mirrors.aliyun.com
       - linux
        (1)cd ~
        (2)mkdir ~/.pip
        (3)vi ~/.pip/pip.conf
        (4)编辑内容,和windows一模一样
    - 需要安装:pip install bs4
         bs4在使用时候需要一个第三方库,把这个库也安装一下
         pip install lxml
    
    (2) 基础使用
    1. 使用流程:       
        - 导包:from bs4 import BeautifulSoup
        - 使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点
        
    2. 内容
    	(1)转化本地文件:
    		- soup = BeautifulSoup(open('本地文件'), 'lxml')
    	(2)转化网络文件:
    		- soup = BeautifulSoup('字符串类型或者字节类型', 'lxml')
    	(3)打印soup对象显示内容为html文件中的内容
        
    3. 基础巩固:
        (1)根据标签名查找
            - soup.a   只能找到第一个符合要求的标签
        (2)获取属性
            - soup.a.attrs  获取a所有的属性和属性值,返回一个字典
            - soup.a.attrs['href']   获取href属性
            - soup.a['href']   也可简写为这种形式
        (3)获取内容
            - soup.a.string
            - soup.a.text
            - soup.a.get_text()
           【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个可以获取文本内容
        (4)find:找到第一个符合要求的标签
            - soup.find('a')  找到第一个符合要求的
            - soup.find('a', title="xxx")
            - soup.find('a', alt="xxx")
            - soup.find('a', class_="xxx")
            - soup.find('a', id="xxx")
        (5)find_all:找到所有符合要求的标签
            - soup.find_all('a')
            - soup.find_all(['a','b']) 找到所有的a和b标签
            - soup.find_all('a', limit=2)  限制前两个
        (6)根据选择器选择指定的内容
                   select:soup.select('#feng')
            - 常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器
                - 层级选择器:
                    div .dudu #lala .meme .xixi  下面好多级
                    div > p > a > .lala          只能是下面一级
            【注意】select选择器返回永远是列表,需要通过下标提取指定的对象
    

    3. xpath

    (1) 选取节点
    表达式 描述
    nodename 选取此节点的所有子节点
    / 从根节点选取
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性
    (2) 案例
    路径表达式 结果
    bookstore 选取 bookstore 元素的所有子节点
    /bookstore 选取根元素 bookstore;注释:假如路径起始于正斜杠( / )则此路径始终代表到某元素的绝对路径
    bookstore/book 选取属于 bookstore 的子元素的所有 book 元素
    //book 选取所有 book 子元素,而不管它们在文档中的位置
    bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
    //@lang 选取名为 lang 的所有属性
    (3) 谓语
    表达式 结果
    /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素
    /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素
    /bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素
    /bookstore/book[position()❤️] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素
    //title[@lang] 选取所有拥有名为 lang 的属性的 title 元素
    //title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性
    /bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00
    /bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00
    (4) 选取位置节点
    表达式 结果
    * 匹配任何元素节点
    @* 匹配任何元素属性节点
    node() 匹配任何类型的节点
    路径表达式 结果
    /bookstore/* 选取bookstore元素的所有子元素
    //* 选取文档中的所有元素
    //title[@*] 选取所有带属性的title元素
    路径表达式 结果
    //book/title | //book/price 选取 book 元素的所有 title 和 price 元素
    //title | //price 选取文档中的所有 title 和 price 元素
    /bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素
    (5) 基本案例
    1. 属性定位:
        #找到class属性值为song的div标签
        //div[@class="song"]
    2. 层级&索引定位:
        #找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a
        //div[@class="tang"]/ul/li[2]/a
    3. 逻辑运算:
        #找到href属性值为空且class属性值为du的a标签
        //a[@href="" and @class="du"]
    4. 模糊匹配:
        //div[contains(@class, "ng")]
        //div[starts-with(@class, "ta")]
    5. 取文本:
        # /表示获取某个标签下的文本内容
        # //表示获取某个标签下的文本内容和所有子标签下的文本内容
        //div[@class="song"]/p[1]/text()
        //div[@class="tang"]//text()
    6. 取属性:
        //div[@class="tang"]//li[2]/a/@href
    

    三、流程

    1.下载:pip install lxml
    
    2.导包:from lxml import etree
    
    3.将html文档或者xml文档转换成一个etree对象,然后调用对象中的方法查找指定的节点
    	2.1 本地文件: tree = etree.parse(文件名)
                     tree.xpath("xpath表达式")
        2.2 网络数据:tree = etree.HTML(网页内容字符串)
                     tree.xpath("xpath表达式")
            
    4.备注:
        安装Chrome的xpath插件
        安装xpath插件在浏览器中对xpath表达式进行验证:可以在插件中直接执行xpath表达式
    	将xpath插件拖动到谷歌浏览器拓展程序(更多工具)中,安装成功
        启动和关闭插件 ctrl + shift + x
      	
    5.xpath解析原理
    - 实例化一个etree的对象,且将页面源码数据加载到该对象中    
    - 调用etree对象中的xpath方法实现标签定位和数据的提取    
    - 在xpath函数中必须作用xpath表达式    
    - xpath函数返回的一定是一个列表
    
  • 相关阅读:
    Linux主机肉鸡木马minerd导致CPU跑满
    阿里云Redis加速Typecho博客访问
    啪啪啪!敲代码时你喜欢听什么音乐?
    排列组合的去重问题
    01背包变形
    判断两个线段是否相交
    Centos搭建SVN服务器三步曲
    nodejs for centos配置
    AngularJS 授权 + Node.js REST api
    1082 射击比赛 (20 分)C语言
  • 原文地址:https://www.cnblogs.com/hq82/p/10792698.html
Copyright © 2020-2023  润新知