zoukankan      html  css  js  c++  java
  • 数据解析的方式

    数据解析

    - 数据解析
        - 数据解析的作用:
            - 可以帮助我们实现聚焦爬虫
        - 数据解析的实现方式:
            - 正则
            - bs4
            - xpath
            - pyquery
         - 数据解析的通用原理
             - 问题1:聚焦爬虫爬取的数据是存储在哪里的?
                 - 都被存储在了相关的标签之中and相关标签的属性中
             - 1.定位标签
             - 2.取文本或者取属性

    一、正则表达式解析

    # 示例一:正则表达式解析数据抓取糗事百科糗图
    import os
    import re
    from urllib import request
    dirName="./qiutu"
    if not os.path.exists(dirName):
        os.mkdir(dirName)
    base_url="https://www.qiushibaike.com/imgrank/page/%d/"
    headers={
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
    }
    pattern='<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
    for i in range(1,3):
        url=format(base_url%i)
        response=requests.get(url=url,headers=headers)
        page_text=response.text
        src_list=re.findall(pattern,page_text,re.S)
        for src in src_list:
            src="https:"+src
            img_name=src.split("/")[-1]
            img_path=dirName+"/"+img_name
            request.urlretrieve(src,filename=img_path)
            print(img_name+"下载完成...")

    二、bs4数据解析

    原理分析:

    - bs4解析
        - bs4解析的原理:
            - 实例化一个BeautifulSoup的对象,需要将即将被解析的页面源码数据加载到该对象中
            - 调用BeautifulSoup对象中的相关方法和属性进行标签定位和数据提取
        - 环境的安装:
            - pip install bs4
            - pip install lxml
        - BeautifulSoup的实例化:
            - BeautifulSoup(fp,'lxml'):将本地存储的一个html文档中的数据加载到实例化好的BeautifulSoup对象中
            - BeautifulSoup(page_text,'lxml'):将从互联网上获取的页面源码数据加载到实例化好的BeautifulSoup对象中

    使用方式:

    - 定位标签的操作:
        - soup.tagName:定位到第一个出现的tagName标签
        - 属性定位:soup.find('tagName',attrName='value')
        - 属性定位:soup.find_all('tagName',attrName='value'),返回值为列表
        - 选择器定位:soup.select('选择器')
            - 层级选择器:>表示一个层级  空格表示多个层级
    - 取文本
        - .string:获取直系的文本内容
        - .text:获取所有的文本内容
    - 取属性
        - tagName['attrName']

    使用方法示例:

    from bs4 import BeautifulSoup
    fp = open('./test.html','r',encoding='utf-8')
    soup = BeautifulSoup(fp,'lxml')
    soup.div
    soup.find('div',class_='song')
    soup.find('a',id="feng")
    soup.find_all('div',class_="song")
    soup.select('#feng')
    soup.select('.tang > ul > li')
    soup.select('.tang li') #
    a_tag = soup.select('#feng')[0]
    a_tag.text
    div = soup.div
    div.string
    div = soup.find('div',class_="song")
    div.string
    a_tag = soup.select('#feng')[0]
    a_tag['href']

    示例:

    # 示例二:使用bs4 数据解析下载三国演义
    import lxml
    from bs4 import BeautifulSoup
    fp=open("sanguo.txt",'a',encoding="utf-8")
    url="http://www.shicimingju.com/book/sanguoyanyi.html"
    headers={
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
    }
    response=requests.get(url=url,headers=headers)
    page_text=response.text
    soup=BeautifulSoup(page_text,"lxml")
    li_list=soup.select(".book-mulu li a")
    for i in li_list:
        chapter=i.string
        detail_src="http://www.shicimingju.com"+i["href"]
        response2=requests.get(url=detail_src,headers=headers)
        detail_text=response2.text
        soup2=BeautifulSoup(detail_text,"lxml")
        content=soup2.find("div",class_="chapter_content").text
        fp.write(chapter+"
    "+content+"
    ")
        print(chapter,"下载完毕...")
    fp.close()

    三、xpath数据解析

    原理分析:

    - xpath解析
        - xpath解析的实现原理
            - 1.实例化一个etree的对象,然后将即将被解析的页面源码加载到改对象中
            - 2.使用etree对象中的xpath方法结合着不同形式的xpath表达式实现标签定位和数据提取
        - 环境安装:
            - pip install lxml
        - etree对象的实例化:
            - etree.parse('test.html')
            - etree.HTML(page_text)

    使用方式:

    - xpath表达式:xpath方法的返回值一定是一个列表
        - 最左侧的/表示:xpath表达式一定要从根标签逐层进行标签查找和定位
        - 最左侧的//表示:xpath表达式可以从任意位置定位标签
        - 非最左侧的/:表示一个层级
        - 非最左侧的//:表示夸多个层级
        - 属性定位://tagName[@attrName="value"]
        - 索引定位://tagName[index] 索引是从1开始
    - 取文本:
        - /text():直系文本内容
        - //text():所有的文本内容
    - 取属性:
        - /@attrName

    使用方式示例:

    from lxml import etree
    tree = etree.parse('./test.html')
    tree.xpath('/html/head/title')
    tree.xpath('//title')
    tree.xpath('/html/body//p')
    tree.xpath('//p')
    tree.xpath('//div[@class="song"]')
    tree.xpath('//li[7]')
    tree.xpath('//a[@id="feng"]/text()')[0]
    tree.xpath('//div[@class="song"]//text()')
    tree.xpath('//a[@id="feng"]/@href')

    实战3.1

    # 示例3.1:使用xpath解析数据获取糗事百科段子及作者
    from lxml import etree
    base_url="https://www.qiushibaike.com/text/page/1/"
    response=requests.get(url,headers=headers)
    tree=etree.HTML(response.text)
    item_list=tree.xpath('//div[@class="col1 old-style-col1"]/div')
    for i in item_list:
        author=i.xpath('.//a[2]/h2/text()')[0]
        content=i.xpath('.//div[@class="content"]/span//text()')[0]
        print(author,content)
        print("------"*20)
    #     tree.xpath(//div[@class="article"]//div[@class="content"]/span/text())

    实战3.2

    # 示例3.2:http://pic.netbian.com/4kmeinv/中文乱码的处理  没有分页下载
    dirName="./meinv"
    if not os.path.exists(dirName):
        os.mkdir(dirName)
    url="http://pic.netbian.com/4kmeinv/"
    response_text=requests.get(url,headers=headers).text
    tree=etree.HTML(response_text)
    a_list=tree.xpath('//div[@class="slist"]/ul[@class="clearfix"]/li/a')
    for i in a_list:
        img_title=i.xpath('./b/text()')[0]
        img_title=img_title.encode("iso-8859-1").decode("gbk")
        img_src="http://pic.netbian.com"+i.xpath('./img/@src')[0]
        img_path=dirName+"/"+img_title+".jpg"
        img_data=requests.get(img_src,headers=headers).content
        with open(img_path,"wb") as fp:
            fp.write(img_data)
            print(img_title,"下载完成...")

    实战3.3

    # 示例3.2:http://pic.netbian.com/4kmeinv/中文乱码的处理  有分页下载
    dirName="./meinvPage"
    if not os.path.exists(dirName):
        os.mkdir(dirName)
    
    for index in range(1,4):
        print("正在下载第%s页..."%str(index))
        if index==1:
            url="http://pic.netbian.com/4kmeinv/"
        else:
            url=format("http://pic.netbian.com/4kmeinv/index_%d.html"%index)
        response_text=requests.get(url,headers=headers).text
        tree=etree.HTML(response_text)
        a_list=tree.xpath('//div[@class="slist"]/ul[@class="clearfix"]/li/a')
        for i in a_list:
            img_title=i.xpath('./b/text()')[0]
            img_title=img_title.encode("iso-8859-1").decode("gbk")
            img_src="http://pic.netbian.com"+i.xpath('./img/@src')[0]
            img_path=dirName+"/"+img_title+".jpg"
            img_data=requests.get(img_src,headers=headers).content
            with open(img_path,"wb") as fp:
                fp.write(img_data)
                print(img_title,"下载完成...")

    实战3.4

    #https://www.aqistudy.cn/historydata/  抓取所有城市名称
    url="https://www.aqistudy.cn/historydata/"
    response_text=requests.get(url,headers=headers).text
    tree=etree.HTML(response_text)
    #方式一
    # hot_cities=tree.xpath('//div[@class="hot"]//li/a/text()')
    # all_cities=tree.xpath('//div[@class="all"]//li/a/text()')
    # print(hot_cities)
    # print(all_cities)
    #方式二
    cities=tree.xpath('//div[@class="hot"]//li/a/text() | //div[@class="all"]//li/a/text()')
    print(cities)

    持久化数据的两种方式

    1:使用requests方式持久化数据

    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
    }
    #如何爬取图片
    url = 'https://pic.qiushibaike.com/system/pictures/12223/122231866/medium/IZ3H2HQN8W52V135.jpg'
    img_data = requests.get(url,headers=headers).content #byte类型数据
    with open('./img.jpg','wb') as fp:
        fp.write(img_data)

    2:使用urllib方式持久化数据

    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
    }
    #弊端:不能使用UA伪装
    from urllib import request
    url = 'https://pic.qiushibaike.com/system/pictures/12223/122231866/medium/IZ3H2HQN8W52V135.jpg'
    request.urlretrieve(url,filename='./qiutu.jpg')

    总结

    不管使用哪种数据解析方式,第一步都需要使用requests将整个页面数据拿到,然后再根据不同的数据解析方式使用不同的方法进行提取需要的数据部分。
  • 相关阅读:
    JQuery+Ajax+Ashx+Base64 data无法传递的问题
    用户 'IIS APPPOOL\DefaultAppPool' 登录失败。 的解决方案
    CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\web\4b49f661\23a749fc\App_Web_default.aspx.cdcab7d2.zii776dc.dl
    SQL 按月统计
    591  Box of Bricks
    10038 Jolly Jumpers
    113 Power of Cryptography
    10370 Above Average
    10189 Minesweeper
    136 Ugly Numbers 之“堆”的解法
  • 原文地址:https://www.cnblogs.com/sun-10387834/p/12830220.html
Copyright © 2011-2022 走看看