关于爬虫解析数据的4种方式

发布时间:2022-06-29 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了关于爬虫解析数据的4种方式脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

目录

一、xpath解析数据

1、XPath解析数据

2、XML的树形结构

3、使用XPath选取节点

4、课堂案例 - 爬取起点小说网

二、BeautifulSoup解析数据

1、BeautifulSoup

2、BeautifulSoup的使用

3、使用BeautifulSoup爬取淘宝网首页

三、正则表达式

1、正则表达式

2、正则语法

3、特殊序列

4、正则处理函数

5、课堂案例(下载糗事百科小视频)

6、课外案例

四、pyquery解析数据

1、pyquery

2、pyquery的初始化方式

3、pyquery的使用

4、课堂案例(爬取起点小说网)


一、XPath解析数据

1、XPath解析数据

@H_304_54@
  • XPath
    • 全称F1a;XML Path Language是一种小型的查询语言
    • 是一门在XML文档中查找信息的语言
  • XPath的优点
    • 可在XML中查找信息
    • 支持HTML的查找
    • 可通过元素和属性进行导航
  • XPath需要依赖lxml
    • 安装方式: pip install lxml
  • 2、XML的树形结构

    关于爬虫解析数据的4种方式

    3、使用XPath选取节点

    序号

    表达式

    描述

    1

    nodename

    选取此节点的所有子节点

    2

    /

    从根节点选择

    3

    //

    从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置

    4

    .

    选取当前节点

    5

    ..

    选取当前节点的父节点

    6

    /text()

    选取当前路径下的文本内容

    7

    /@xxx

    提取当前路径下标签的属性值

    8

    |可选符

    可选择若干个路径//p|//div,在当前路径下选取所有符合条件的p标签和div标签

    序号

    表达式

    描述

    1

    xpath('./body/div[1]')

    选取body下的第一个div节点

    2

    xpath('./body/div[ last() ]')

    选取body下最后一个div节点

    3

    xpath('./body/div[ last()-1 ]')

    选取body下倒数第二个div节点

    4

    xpath('./body/div[ posITion()<3 ]')

    选取body下前两个div节点

    5

    xpath('./body/div[ @class ]')

    选取body下带有class属性的div节点

    6

    xpath('./body/div[ @class=";main" ]')

    选取body下class属性为main的div节点

    7

    xpath('./body/div[ PRice>35.00 ]')

    选取body下price元素大于35的div节点

    4、课堂案例 - 爬取起点小说网

    • 下载谷歌浏览器XPath插件
    • 安装XPath插件
    • 使用XPath
    import requests
    From lxml import etree
    url='https://www.qidian.COM/rank/yuepiao'
    headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) Applewebkit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
    
    # 发送请求
    resp=requests.get(url,headers)
    e=etree.HTML(resp.text)     # 类型转换,把str类型转换成class 'lxml.etree._Element'
    # print(tyPE(e))        # <class 'lxml.etree._Element'>
    names=e.xpath('//div[@class="Book-mid-info"]/h4/a/text()')  # 获取小说名称
    authors=e.xpath('//p[@class="author"]/a[1]/text()')         # 获取小说作者
    # print(names)        # ['大奉打更人', '这个人仙太过正经', '从红月开始', '稳住别浪', 。。。]
    # print(authors)      # ['卖报小郎君', '言归正传', '黑山老鬼', '跳舞', '我最白',  。。。]
    
    for name,author in zip(names,authors):
        print(name, ":", author)
    # 大奉打更人 : 卖报小郎君
    # 这个人仙太过正经 : 言归正传
    # 从红月开始 : 黑山老鬼
    # 稳住别浪 : 跳舞
    # ...    ...

    二、BeautifulSoup解析数据

    1、BeautifulSoup

    • BeautifulSoup
      • 是一个可以从HTML或XML文件中提取数据的Python库。其功能简单而强大、容错能力强、文档相对完善,清晰易懂
      • 非Python标准模块,需要安装才能使用
    • 安装方式
      • pip install bs4
    • 测试方式
      • import bs4
    • 解析器
      • BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果不安装第三方解析器,则Python会使用默认浏览器

    序号

    解析器

    使用方法

    优点

    缺点

    1

    标准库

    BeautifulSoup(html,'html.parser')

    内置标准库,速度适中,文档容错能力强

    Python3.2版本前的文档容错能力差

    2

    lxml HTML

    BeautifulSoup(html, 'lxml')

    速度快,文档容错能力强

    安装c语言

    3

    lxml XML

    BeautifulSoup(html, 'xml')

    速度快,唯一支持XML

    安装C语言库

    4

    html5lib

    BeautifulSoup(html, 'html5lib')

    容错能力最强,可生成HTML5

    运行慢,扩展差

    from bs4 import BeautifulSoup
    
    html='''
        <html>
           <head>
              <title>今天又是美好的一天</title>
            </head>
            <body>
                <h1 class="info bg" float="left">早起对自己说:我真美!</h1>
                <a href="http://www.baidu.com">百度</a>
                <h2><!--注释的内容--></h2>
            </body>
        </html>
    '''
    # bs=BeautifulSoup(html, 'html.parser')
    bs=BeautifulSoup(html, 'lxml')
    print(bs.title)     # 获取标题         <title>今天又是美好的一天</title>
    print(bs.h1.attrs)    # 获取h1标签的所有属性   {'class': ['info', 'bg'], 'float': 'left'}
    
    # 获取单个属性
    print(bs.h1.get('class'))       # ['info', 'bg']
    print(bs.h1['class'])           # ['info', 'bg']
    print(bs.a['href'])             # http://www.baidu.com
    
    # 获取文本内容
    print(bs.title.text)            # 今天又是美好的一天
    print(bs.title.string)          # 今天又是美好的一天
    
    # 获取内容
    print('-----', bs.h2.string)       # ----- 注释的内容
    print('-----', bs.h2.text)         # -----
    # string可以获取注释的内容,但是text不能获取注释内容

    2、BeautifulSoup的使用

    返回值类型

    方法

    功能

    语法

    举例

    Tag

    find()

    提取满足要求的首个数据

    bs.find(标签,属性)

    bs.find('div', class_='books')

    Tag

    find_all()

    提取满足要求的所有数据

    bs.find_all(标签,属性)

    bs.find_all('div', class_='books')

    • CSS选择题

    功能

    举例

    通过ID查找

    bs.select('#abc')

    通过classa查找

    bs.select('.abc')

    通过属性查找

    bs.select(a[' class="abc" '])

    • Tag对象

    功能

    举例

    获取标签

    bs.title

    获取所有属性

    bs.title.attrs

    获取单个属性的值

    bs.div.get('class')

    bs.div['class']

    bs.a['href']

    from bs4 import BeautifulSoup
    
    html='''
        <title>今天又是美好的一天</title>
        <div class="info" float="left">今天又是美好的一天</div>
       <div class="info" float="right" id="gb">
          <span>好好学习,天天向上</span>
          <a href="http://www.baidu.com">百度</a>
       </div>
       <span>人生苦短,唯有爱情</span>
    '''
    
    bs=BeautifulSoup(html, 'lxml')
    
    print(bs.title, type(bs.title))      # 获取标题及其类型
    # <title>今天又是美好的一天</title> <class 'bs4.element.Tag'>
    
    print(bs.find('div',class_='info'), type(bs.find('div',class_='info')))     # 获取第一个满足条件的标签
    # <div class="info" float="left">今天又是美好的一天</div> <class 'bs4.element.Tag'>
    
    print(bs.find_all('div', class_='info'))    # 得到的是一个标签的列表
    # [<div class="info" float="left">今天又是美好的一天</div>, <div class="info" float="right" id="gb">
    # <span>好好学习,天天向上</span>
    # <a href="http://www.baidu.com">百度</a>
    # </div>]
    
    for item in bs.find_all('div',class_='info'):
        print(item, type(item))
    
    print(bs.find_all('div', attrs={'float':'right'}))  # 得到属性为'float':'right'的div标签
    
    print('---------------CSS选择器---------------------')
    print(bs.select("#gb"))
    print(bs.select(".info"))
    
    print(bs.select('div>span'))    # [<span>好好学习,天天向上</span>]
    print(bs.select('div.info>span'))    # [<span>好好学习,天天向上</span>]
    
    for item in bs.select('div.info>span'):
        print(item.text)    # 好好学习,天天向上

    3、使用BeautifulSoup爬取淘宝网首页

    import requests
    from bs4 import BeautifulSoup
    url='https://www.taobao.com/'
    headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
    resp=requests.get(url,headers)
    # print(resp.text)        # <html>... ...</html>
    bs=BeautifulSoup(resp.text,'lxml')
    a_list=bs.find_all('a')
    # print(len(a_list))      # 128
    for a in a_list:
        url=a.get('href')
        # print(url)
        if url==None:
            continue
        if url.startswith('http') or url.startswith('https'):
            print(url)

    三、正则表达式

    1、正则表达式

    • 是一个特殊的字符序列,它能帮助用户便捷地检查一个字符串是否与某种模式匹配
    • Python的正则模块是re,是Python的内置模块,不需要安装,导入即可

    2、正则语法

    序号

    元字符

    说明

    1

    .

    匹配任意字符(不包括n)

    2

    ^

    匹配字符串的开头

    3

    $

    匹配字符的末尾

    4

    *

    匹配前一个元字符0到多次

    5

    +

    匹配前一个元字符1到多次

    6

    ?

    匹配前一个元字符0到1次

    7

    {m}

    匹配前一个字符m次

    8

    {m,n}

    匹配前一个字符m到n次

    9

    {m,n}?

    匹配前一个字符m到n次,并且取尽可能少的情况

    10

    \

    对特殊字符进行转义

    11

    []

    一个字符的集合,可匹配其中任意一个字符

    12

    |

    逻辑表达式“或”,比如 a|b 代表可匹配a或者b

    13

    (...)

    被括起来的表达式作为一个元组。findall()在有组的情况下只显示组的内容

    3、特殊序列

    序号

    元字符

    说明

    1

    A

    只在字符串开头进行匹配

    2

    b

    匹配位于开头或者结尾的空字符串

    3

    B

    匹配不位于开头或者结尾的空字符串

    4

    d

    匹配任意十进制数,相当于[0-9]

    5

    D

    匹配任意非数字字符,相当于[^0-9]

    6

    s

    匹配任意空白字符,相当于[tnrfv]

    7

    S

    匹配任意非空白字符,相当于[^tnrfv]

    8

    w

    匹配任意数字、字母、下划线,相当于[a-zA-Z0-9_]

    9

    W

    匹配任意非数字、字母、下划线,相当于[^a-zA-Z0-9_]

    10

    Z

    只在字符串结尾进行匹配

    11

    [u4e00-u9fa5]

    中文

    4、正则处理函数

    序号

    正则处理函数

    说明

    1

    re.match(pattern, string, flags=0)

    尝试从字符串的开始位置匹配一个模式,如果匹配成功,就返回一个匹配成功的对象,否则返回None

    2

    re.seArch(pattern, string, flags=0)

    扫描整个字符串并返回第一次成功匹配的对象,如果匹配失败,就返回None

    3

    re.findall(pattern, string, flags=0)

    获取字符串中所有匹配的字符串,并以列表的形式返回

    4

    re.sub(pattern, repl, string, count=0,flags=0)

    用于替换字符串中的匹配项,如果没有匹配的项则返回没有匹配的字符串

    5

    re.compile(pattern[ ,flags ])

    用于编译正则表达式,生成一个正则表达式(Pattern)对象,供match()和search()函数使用

    import re
    s = 'I study Python3.8 every day'
    print('--------match方法,从起始位置开始匹配--------')
    print(re.match("I", s).group())     # I
    print(re.match('w', s).group())    # I
    print(re.match('.', s).group())     # I
    
    print('--------search方法,从任意位置开始匹配,匹配第一个--------')
    print(re.search('study', s).group())    # study
    print(re.search('sw', s).group())      # st
    
    print('--------findall方法,从任意位置开始匹配,匹配多个--------')
    print(re.findall("y", s))           # 结果为数组   ['y', 'y', 'y', 'y']
    print(re.findall("Python", s))      # ['Python']
    print(re.findall("Pw+.d", s))     # ['Python3.8']
    print(re.findall("P.+d", s))     # ['Python3.8']
    
    print('--------sub方法的使用,替换功能--------')
    print(re.sub('study', 'like', s))     # 将study替换成like   I like Python3.8 every day
    print(re.sub('sw+', 'like', s))     #  I like Python3.8 every day

    5、课堂案例(下载糗事百科小视频)

    • 请求的url
      • 最新视频 - 糗事百科

    爬取数据时,一定要记得先找F12代码,看看和爬取的数据是否一致,若一致,则可直接提取。

    import re
    import requests
    
    url='http://www.qiushibaike.com/video/'
    headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
    resp=requests.get(url,headers=headers)
    # print(resp.text)
    
    # 先随便找一个视频,看是否能提取到。单引号中的单引号用转义:'...'
    # info=re.findall('<source src="//qiubai-video.qiushibaike.com/1EXAHVPHKWXFJYR2_org.mp4" type='video/mp4' />', resp.text)
    # print(info)     # ['<source src="//qiubai-video.qiushibaike.com/1EXAHVPHKWXFJYR2_org.mp4" type='video/mp4' />']
    
    info=re.findall('<source src="(.*)" type='video/mp4' />', resp.text)
    # print(info)     # 给出所有URL的相对位置的数组
    lst=[]
    for item in info:
        lst.append("https:"+item)
    # print(lst)
    
    # 循环
    count=0
    for item in lst:
        count+=1
        resp=requests.get(item, headers=headers)
        # 转成二进制存储
        with open('video/'+str(count)+'.mp4', 'wb') as file:
            file.write(resp.content)
    print('视频下载完毕')

    6、课外案例

    用正则表达式提取51job网页中的信息

    import requests
    import re
    from pandas import DataFrame
     
    # 网址
    url = "https://search.51job.com/list/000000,000000,0000,32,9,99,Java%25E5%25BC%2580%25E5%258F%2591,2,1.html"
    # 获得网页对象
    res = requests.get(url)
    # 设置编码格式
    res.encoding = "gbk"
     
    # 职位名
    # 将要提取的用(.*)表示,每条数据不同的地方用.*表示
    position_pat = '<a target="_blank" title="(.*)" href=".*" onmousedown=".*">'  
    position = re.findall(position_pat, res.text)
     
    # 公司名
    company_pat = '<span class="t2"><a target="_blank" title="(.*)" href=".*">.*</a></span>'
    company = re.findall(company_pat, res.text)
     
    # 工作地点
    place_pat = '<div class="el">.*?<span class="t3">(.*?)</span>'  # 非贪婪模式
    place = re.findall(place_pat, res.text, re.S)
     
    # 薪资
    salary_pat = '<div class="el">.*?<span class="t4">(.*?)</span>'  # 非贪婪模式
    salary = re.findall(salary_pat, res.text, re.S)
     
    # 将取出的信息放到数据框
    jobInfo = DataFrame([position, company, place, salary]).T
    # 设置列名
    jobInfo.columns = ['职位名', '公司名', '工作地点', '薪资']
    print(jobInfo.head())
     
    # 将数据保存到本地
    jobInfo.to_csv('51job2.csv')

    四、pyquery解析数据

    1、pyquery

    • pyquery库是jquery的Python实现,就能以jQuery的语法来操作解析HTML文档,易用性和解析速度都很好
    • 前提条件:
      • 你对CSS选择器与jQuery有所了解
    • 非Python标准模块,需要安装
      • 安装方式
        • pip install pyquery
      • 测试方式
        • import pyquery

    2、pyquery的初始化方式

    • 字符串方式

    @H_107_1261@

    • url方式

    关于爬虫解析数据的4种方式

    • 文件

    关于爬虫解析数据的4种方式

    # 字符串方式
    from pyquery import PyQuery as py
    html='''
        <html>
           <head>
              <title>PyQuery</title>
           </head>
           <body>
              <h1>PyQuery</h1>
           </body>
        </html>
    '''
    
    doc=py(html)    # 创建PyQuery的对象,实际上就是在进行一个类型转换,将str类型转成PyQuery类型
    print(doc)              # 和html一样的内容
    print(type(doc))        # <class 'pyquery.pyquery.PyQuery'>
    print(type(html))       # <class 'str'>
    print(doc('title'))     # <title>PyQuery</title>
    # url方式
    from pyquery import PyQuery
    doc=PyQuery(url='http://www.baidu.com', encoding='utf-8')
    print(doc)              # 获取html
    print(doc('title'))     # <title>百度一下,你就知道</title>
    # 文件
    from pyquery import PyQuery
    doc=PyQuery(filename='a1.html')
    print(doc)           # 获取html
    print(doc('h1'))     # <h1>PyQuery</h1>

    3、pyquery的使用

    序号

    提取数据

    举例

    1

    获取当前节点

    doc('#main')

    2

    获取子节点

    doc('#main').children()

    3

    获取父节点

    doc('#main').parent()

    4

    获取兄弟节点

    doc('#main').siblings()

    5

    获取属性

    doc('#main').attr('href')

    6

    获取内容

    doc('#main').html() doc('#main').text()

    from pyquery import PyQuery
    html='''
        <html>
            <head>
                <title>PyQuery</title>
            </head>
            <body>
                <div id="main">
                    <a href="http://www.baidu.com">百度</a>
                    <h1>百度一下</h1>
                </div>
                <h2>Python学习</h2>
            </body>
        </html>
    '''
    doc=PyQuery(html)
    # 获取当前节点
    print(doc("#main"))      # 获取整个div
    # 获取父节点
    print(doc("#main").parent())      # 获取整个body
    # 获取子节点
    print(doc("#main").children())    # 获取<a>和<h1>
    # # 获取兄弟节点
    print(doc("#main").siblings())      # 获取<h2>
    
    print('----------获取属性------------')
    print(doc('a').attr('href'))     # http://www.baidu.com
    
    print('----------获取标签的内容------------')
    print(doc("#main").html())        #  获取<a>和<h1>,div中的所有都获取到了
    print(doc("#main").text())          #  百度  百度一下, 只获取了div中的文本
    

    4、课堂案例(爬取起点小说网)

    import requests
    from pyquery import PyQuery
    
    url='https://www.qidian.com/rank/yuepiao'
    headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
    resp=requests.get(url,headers)
    # print(resp.text)
    
    # 初始化PyQuery对象
    doc=PyQuery(resp.text)      # 使用字符串初始化方式初始化PyQuery对象
    # a_tag=doc('h4 a')       # 获取h4的a标签
    # print(a_tag)
    names=[a.text for a in doc('h4 a')]
    # print(names)        # ['大奉打更人', '这个人仙太过正经', '从红月开始', '稳住别浪',....]
    
    authors = doc('p.author a')       # 找<p class="author">下的<a>标签
    # print(authors)
    
    authors_lst=[]
    for index in range(len(authors)):
        if index%2==0:
            authors_lst.append(authors[index].text)
    # print(authors_lst)      # ['卖报小郎君', '言归正传', '黑山老鬼', '跳舞', '我最白', '白驹易逝', ...]
    
    for name,author in zip(names,authors_lst):
        print(name, ':', author)
    # 大奉打更人 : 卖报小郎君
    # 这个人仙太过正经 : 言归正传
    # 从红月开始 : 黑山老鬼
    # 稳住别浪 : 跳舞
    # ... ...

    脚本宝典总结

    以上是脚本宝典为你收集整理的关于爬虫解析数据的4种方式全部内容,希望文章能够帮你解决关于爬虫解析数据的4种方式所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。